mirror of
https://github.com/kuaifan/dootask.git
synced 2026-10-30 06:20:44 +00:00
feat(dashboard): 合并仪表盘视图切换为「列表|四象限|部门总览」
- 右上角两组切换合并为一个,部门视角选中后该项显示部门范围与成员数,再次点击选择团队范围 - 全选多个部门时显示「部门总览」,切换范围加载中成员数以 loading 占位 - 切换器宽度随内容平滑过渡,尊重减少动态效果设置;部门项与成员数补充悬停提示 - 移动端收起为图标按钮:部门负责人点击弹出列表/四象限/部门总览下拉,底部可选择团队范围并显示成员人数;普通用户点击在列表与四象限间切换 - 移动端部门视角图标带成员数角标(超过 99 显示 99+),头部右侧只占图标宽度 - 清理不再使用的文案与样式,同步 ai-kb 仪表盘相关说明
This commit is contained in:
parent
4115291bff
commit
c06d61a11f
@ -2489,7 +2489,6 @@ AI任务分析
|
||||
你撤回了一条消息
|
||||
重新编辑
|
||||
四象限
|
||||
个人视角
|
||||
部门任务总览
|
||||
(*) 人
|
||||
最久 (*) 天
|
||||
@ -2537,7 +2536,6 @@ AI任务分析
|
||||
没有超期任务,保持住
|
||||
今天只有这一项,处理完就轻松了
|
||||
数量较多,仅显示最近 (*) 项,展开其余 (*) 项
|
||||
我的部门
|
||||
待开始
|
||||
暂无待开始任务
|
||||
太棒了,任务全部清空
|
||||
@ -2783,3 +2781,6 @@ WebDAV 路径冲突
|
||||
请填写指派留言
|
||||
任务负责人最多不能超过10个
|
||||
展开显示更多
|
||||
部门总览
|
||||
全部部门
|
||||
团队成员 (*) 人
|
||||
|
||||
@ -37475,18 +37475,6 @@
|
||||
"id": "Empat kuadran",
|
||||
"ru": "Четыре квадранта"
|
||||
},
|
||||
{
|
||||
"key": "个人视角",
|
||||
"zh": "",
|
||||
"zh-CHT": "個人視角",
|
||||
"en": "Personal view",
|
||||
"ko": "개인 보기",
|
||||
"ja": "個人ビュー",
|
||||
"de": "Persönliche Ansicht",
|
||||
"fr": "Vue personnelle",
|
||||
"id": "Tampilan pribadi",
|
||||
"ru": "Личный вид"
|
||||
},
|
||||
{
|
||||
"key": "部门任务总览",
|
||||
"zh": "",
|
||||
@ -37979,18 +37967,6 @@
|
||||
"id": "Item banyak; menampilkan (%T1) terbaru, buka (%T2) sisanya",
|
||||
"ru": "Элементов много: показаны последние (%T1), разверните остальные (%T2)"
|
||||
},
|
||||
{
|
||||
"key": "我的部门",
|
||||
"zh": "",
|
||||
"zh-CHT": "我的部門",
|
||||
"en": "My department",
|
||||
"ko": "내 부서",
|
||||
"ja": "自分の部署",
|
||||
"de": "Meine Abteilung",
|
||||
"fr": "Mon service",
|
||||
"id": "Departemen saya",
|
||||
"ru": "Мой отдел"
|
||||
},
|
||||
{
|
||||
"key": "待开始",
|
||||
"zh": "",
|
||||
@ -40162,5 +40138,41 @@
|
||||
"fr": "Afficher plus",
|
||||
"id": "Tampilkan lebih banyak",
|
||||
"ru": "Показать больше"
|
||||
},
|
||||
{
|
||||
"key": "部门总览",
|
||||
"zh": "",
|
||||
"zh-CHT": "部門總覽",
|
||||
"en": "Department overview",
|
||||
"ko": "부서 개요",
|
||||
"ja": "部門概要",
|
||||
"de": "Abteilungsübersicht",
|
||||
"fr": "Vue du service",
|
||||
"id": "Ikhtisar departemen",
|
||||
"ru": "Обзор отдела"
|
||||
},
|
||||
{
|
||||
"key": "全部部门",
|
||||
"zh": "",
|
||||
"zh-CHT": "全部部門",
|
||||
"en": "All departments",
|
||||
"ko": "모든 부서",
|
||||
"ja": "すべての部門",
|
||||
"de": "Alle Abteilungen",
|
||||
"fr": "Tous les services",
|
||||
"id": "Semua departemen",
|
||||
"ru": "Все отделы"
|
||||
},
|
||||
{
|
||||
"key": "团队成员 (%T1) 人",
|
||||
"zh": "",
|
||||
"zh-CHT": "團隊成員 (%T1) 人",
|
||||
"en": "(%T1) team members",
|
||||
"ko": "팀원 (%T1)명",
|
||||
"ja": "チームメンバー (%T1)人",
|
||||
"de": "(%T1) Teammitglieder",
|
||||
"fr": "(%T1) membres de l’équipe",
|
||||
"id": "(%T1) anggota tim",
|
||||
"ru": "Участников команды: (%T1)"
|
||||
}
|
||||
]
|
||||
|
||||
2
public/language/web/de.js
vendored
2
public/language/web/de.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/en.js
vendored
2
public/language/web/en.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/fr.js
vendored
2
public/language/web/fr.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/id.js
vendored
2
public/language/web/id.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/ja.js
vendored
2
public/language/web/ja.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/key.js
vendored
2
public/language/web/key.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/ko.js
vendored
2
public/language/web/ko.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/ru.js
vendored
2
public/language/web/ru.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/zh-CHT.js
vendored
2
public/language/web/zh-CHT.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/zh.js
vendored
2
public/language/web/zh.js
vendored
File diff suppressed because one or more lines are too long
@ -19,13 +19,13 @@ negative:
|
||||
- 普通成员只有个人视角,不能查看部门负责人视角
|
||||
- 部门负责人视角是只读任务总览,不会授予任务修改权限
|
||||
- 仪表盘不支持用户自定义卡片或调整统计口径
|
||||
last_verified: v1.8.69
|
||||
last_verified: v1.9.36
|
||||
---
|
||||
|
||||
# 仪表盘个人视角与部门负责人视角
|
||||
|
||||
## 定义
|
||||
DooTask 仪表盘是登录后的任务工作台,入口为左侧栏「仪表盘」。所有用户都有个人视角;系统默认开启「部门负责人视角」(管理员可关闭),且当前用户负责或管理至少一个部门时,右上角还会出现「个人视角 / 部门负责人」切换。
|
||||
DooTask 仪表盘是登录后的任务工作台,入口为左侧栏「仪表盘」。所有用户都有个人视角;系统默认开启「部门负责人视角」(管理员可关闭),且当前用户负责或管理至少一个部门时,右上角「列表 / 四象限」切换器末尾还会出现「部门总览」,点击进入部门负责人视角,再次点击该项可选择团队范围;再点「列表」或「四象限」即回到个人视角。
|
||||
|
||||
## 个人视角
|
||||
- 顶部卡片:已超期、今日到期、待完成、我协助的;待完成卡片还会提示待开始数量。
|
||||
|
||||
@ -18,13 +18,13 @@ negative:
|
||||
- 布局切换只适用于个人视角
|
||||
- 四象限不显示待开始和本周完成分组
|
||||
- 用户不能自定义象限名称或顺序
|
||||
last_verified: v1.9.18
|
||||
last_verified: v1.9.36
|
||||
---
|
||||
|
||||
# 切换仪表盘列表和四象限布局
|
||||
|
||||
## 入口
|
||||
进入仪表盘个人视角,在右上角选择「列表」或「四象限」。所选布局保存在当前浏览器,下次进入时继续使用。
|
||||
在仪表盘右上角切换器中选择「列表」或「四象限」。当前处于部门负责人视角(切换器选中部门项)时,点击「列表」或「四象限」会同时切回个人视角。移动端右上角为一个布局图标:普通成员点击即在列表和四象限之间来回切换;部门负责人点击后在下拉菜单中选择。所选布局保存在当前浏览器,下次进入时继续使用。
|
||||
|
||||
## 列表布局
|
||||
- 顶部显示已超期、今日到期、待完成、我协助的四张摘要卡。
|
||||
|
||||
@ -19,13 +19,13 @@ negative:
|
||||
- 至少选择一个部门后才能确定
|
||||
- 部门范围与项目负责人视角开关是两个独立状态
|
||||
- 范围选择保存在当前浏览器,不跨设备同步
|
||||
last_verified: v1.8.69
|
||||
last_verified: v1.9.36
|
||||
---
|
||||
|
||||
# 选择部门负责人仪表盘的团队范围
|
||||
|
||||
## 仪表盘入口
|
||||
切换到「部门负责人」视角,点击右上角当前部门名称,打开「选择团队范围」。弹窗支持清空、全选、反选和逐项勾选;编辑时可以暂时清空,但没有选择任何部门时「确定」按钮不可用。
|
||||
在仪表盘右上角切换器中选择「部门总览」进入部门负责人视角,该切换项保持选中:管理多个部门且选中全部时仍显示「部门总览」,只管理一个部门或只选部分部门时显示部门名称(多个部门显示为「研发部 +2」),后面附团队成员数。再次点击它打开「选择团队范围」。移动端点击右上角图标,在下拉菜单底部点击当前团队范围(全选多个部门时显示「全部部门」)打开同一弹窗。弹窗支持清空、全选、反选和逐项勾选;编辑时可以暂时清空,但没有选择任何部门时「确定」按钮不可用。
|
||||
|
||||
## 范围规则
|
||||
- 首次默认选择全部可管理部门。
|
||||
|
||||
@ -22,7 +22,7 @@ negative:
|
||||
- 项目可单独关闭负责人视角可见性,关闭后不会被纳入
|
||||
- 没有选择任何部门时不能保存范围
|
||||
- 部门范围和项目列表开关保存在当前浏览器,不跨设备同步
|
||||
last_verified: v1.9.18
|
||||
last_verified: v1.9.36
|
||||
---
|
||||
|
||||
# 设置项目负责人视角和共用部门范围
|
||||
@ -30,7 +30,7 @@ last_verified: v1.9.18
|
||||
## 入口
|
||||
- 右上角头像菜单 →「负责人视角」。
|
||||
- 项目列表搜索栏旁的负责人视角按钮。
|
||||
- 仪表盘「部门负责人」视角 → 右上角部门名称;该入口只选择团队范围。
|
||||
- 仪表盘右上角切换器选择「部门总览」→ 再次点击该切换项;该入口只选择团队范围。
|
||||
|
||||
## 项目负责人视角
|
||||
从菜单或项目列表打开「项目负责人视角」弹窗:
|
||||
|
||||
@ -16,10 +16,10 @@ related_tools: [list_tasks]
|
||||
related_pages: [dashboard]
|
||||
prerequisites: []
|
||||
negative:
|
||||
- 普通成员看不到「部门负责人」切换
|
||||
- 普通成员看不到「部门总览」切换项
|
||||
- 仪表盘没有独立的权限配置,登录用户都能使用个人视角
|
||||
- 部门负责人视角不会让用户获得系统管理员权限
|
||||
last_verified: v1.8.69
|
||||
last_verified: v1.9.36
|
||||
---
|
||||
|
||||
# 仪表盘入口在哪
|
||||
@ -32,9 +32,10 @@ last_verified: v1.8.69
|
||||
|
||||
## 进入后看到什么
|
||||
- 所有登录用户默认可使用个人视角,查看自己负责和协助的任务。
|
||||
- 个人视角右上角可以切换「列表 / 四象限」。
|
||||
- 符合部门负责人条件时,右上角增加「个人视角 / 部门负责人」切换。
|
||||
- 部门负责人视角顶部的部门按钮可打开「选择团队范围」弹窗。
|
||||
- 右上角切换器可选「列表 / 四象限」,两者都是个人视角的布局。
|
||||
- 符合部门负责人条件时,切换器末尾增加「部门总览」,点击进入部门负责人视角(部门任务总览)。
|
||||
- 进入部门负责人视角后,该切换项保持选中:管理多个部门且选中全部时仍显示「部门总览」,只管理一个部门或只选部分部门时显示部门名称(多个部门显示为「研发部 +2」),后面附团队成员数;再次点击可打开「选择团队范围」弹窗。
|
||||
- 移动端右上角三段切换收起为一个图标按钮:部门负责人点击后在下拉菜单中选择「列表 / 四象限 / 部门总览」,部门视角下菜单底部显示当前团队范围及成员人数(全选多个部门时为「全部部门」),点击可打开「选择团队范围」;图标在部门视角下带成员数角标,超过 99 显示「99+」。普通成员点击图标直接在列表和四象限之间切换。
|
||||
|
||||
## 部门负责人视角出现条件
|
||||
1. 系统设置 `department_owner_project_view` 已开启(新安装或未设置时默认开启,管理员可手动关闭)。
|
||||
|
||||
@ -17,7 +17,7 @@ prerequisites: []
|
||||
negative:
|
||||
- 普通成员不能切换到部门负责人视角
|
||||
- 部门负责人视角只提供团队任务只读总览
|
||||
last_verified: v1.8.69
|
||||
last_verified: v1.9.36
|
||||
---
|
||||
|
||||
# 仪表盘导航入口
|
||||
@ -34,4 +34,4 @@ last_verified: v1.8.69
|
||||
- 部门负责人视角:团队指标、成员任务分配、优先级分布、重点关注任务。
|
||||
|
||||
## 权限
|
||||
所有登录用户可访问个人视角。系统默认开启负责人视角(管理员可关闭),且用户管理至少一个部门时,才显示「部门负责人」切换。详细说明见 [[dashboard.entry.menu-map]]。
|
||||
所有登录用户可访问个人视角。系统默认开启负责人视角(管理员可关闭),且用户管理至少一个部门时,右上角「列表 / 四象限」切换器末尾才会出现「部门总览」。详细说明见 [[dashboard.entry.menu-map]]。
|
||||
|
||||
@ -56,19 +56,53 @@
|
||||
<Icon type="ios-search"/>
|
||||
<span>{{$L('搜索')}} ({{mateName}}+F)</span>
|
||||
</div>
|
||||
<div v-if="currentView === 'my'" class="header-seg">
|
||||
<span :class="{'seg-active': layout === 'list'}" @click="setLayout('list')">{{$L('列表')}}</span>
|
||||
<span :class="{'seg-active': layout === 'quad'}" @click="setLayout('quad')">{{$L('四象限')}}</span>
|
||||
</div>
|
||||
<div v-else class="header-dept" @click="deptViewShow = true">
|
||||
<Icon type="md-people"/>
|
||||
<span>{{deptLabel}}</span>
|
||||
<em v-if="teamStats.member_count" class="dept-badge">{{teamStats.member_count}}</em>
|
||||
</div>
|
||||
<div v-if="teamEnabled" class="header-seg">
|
||||
<span :class="{'seg-active': currentView === 'my'}" @click="setView('my')">{{$L('个人视角')}}</span>
|
||||
<span :class="{'seg-active': currentView === 'team'}" @click="setView('team')">{{$L('部门负责人')}}</span>
|
||||
<!--外层按内层实际宽度过渡,内容变化时宽度平滑伸缩-->
|
||||
<div v-show="!windowPortrait" ref="headerSeg" class="header-seg">
|
||||
<div ref="headerSegInner" class="seg-inner">
|
||||
<span :class="{'seg-active': currentView === 'my' && layout === 'list'}" @click="setLayout('list')">{{$L('列表')}}</span>
|
||||
<span :class="{'seg-active': currentView === 'my' && layout === 'quad'}" @click="setLayout('quad')">{{$L('四象限')}}</span>
|
||||
<!--部门视角:未选中显示入口文案,选中后变为部门范围选择-->
|
||||
<span v-if="teamEnabled && currentView === 'team'" class="seg-active seg-dept" :title="$L('选择团队范围')" @click="deptViewShow = true">
|
||||
<em class="dept-name">{{deptLabel}}</em>
|
||||
<em v-if="teamStats.member_count" class="dept-badge" :title="$L('团队成员 (*) 人', teamStats.member_count)">{{teamStats.member_count}}</em>
|
||||
<div v-else-if="teamStatsLoading" class="dept-load"><Loading/></div>
|
||||
</span>
|
||||
<span v-else-if="teamEnabled" @click="setView('team')">{{$L('部门总览')}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!--移动端:部门负责人用下拉切换,其余用户点击在列表/四象限间来回切换-->
|
||||
<template v-if="windowPortrait">
|
||||
<Dropdown v-if="teamEnabled" trigger="click" placement="bottom-end" transfer @on-click="onModeMenu">
|
||||
<div class="header-mode">
|
||||
<i class="taskfont" v-html="modeIcon"></i>
|
||||
<template v-if="currentView === 'team'">
|
||||
<em v-if="teamStats.member_count" class="mode-badge">{{teamStats.member_count > 99 ? '99+' : teamStats.member_count}}</em>
|
||||
<div v-else-if="teamStatsLoading" class="mode-load"><Loading/></div>
|
||||
</template>
|
||||
</div>
|
||||
<DropdownMenu slot="list">
|
||||
<DropdownItem name="list" :selected="currentView === 'my' && layout === 'list'">
|
||||
<div class="dashboard-mode-item"><i class="taskfont"></i>{{$L('列表')}}</div>
|
||||
</DropdownItem>
|
||||
<DropdownItem name="quad" :selected="currentView === 'my' && layout === 'quad'">
|
||||
<div class="dashboard-mode-item"><i class="taskfont"></i>{{$L('四象限')}}</div>
|
||||
</DropdownItem>
|
||||
<DropdownItem name="team" :selected="currentView === 'team'">
|
||||
<div class="dashboard-mode-item"><i class="taskfont"></i>{{$L('部门总览')}}</div>
|
||||
</DropdownItem>
|
||||
<DropdownItem v-if="currentView === 'team'" name="scope" divided>
|
||||
<div class="dashboard-mode-item">
|
||||
<span>{{deptScopeLabel}}</span>
|
||||
<em v-if="teamStats.member_count" class="mode-count">{{$L('(*) 人', teamStats.member_count)}}</em>
|
||||
<i class="taskfont mode-arrow"></i>
|
||||
</div>
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
<div v-else class="header-mode" @click="setLayout(layout === 'list' ? 'quad' : 'list')">
|
||||
<i class="taskfont" v-html="modeIcon"></i>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<!--个人视角-->
|
||||
@ -355,6 +389,16 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.segObserver = new ResizeObserver(this.syncSegWidth);
|
||||
this.segObserver.observe(this.$refs.headerSegInner);
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.segObserver?.disconnect();
|
||||
this.segObserver = null;
|
||||
},
|
||||
|
||||
activated() {
|
||||
this.loadInterval(true);
|
||||
this.loadLicense(true);
|
||||
@ -577,12 +621,22 @@ export default {
|
||||
return teamStats.generated_at ? $A.dayjs(teamStats.generated_at).format('HH:mm:ss') : '--'
|
||||
},
|
||||
|
||||
deptLabel({userInfo, cacheDepartmentOwnerIds}) {
|
||||
// 当前团队范围:未选择或选中全部可管理部门时 all 为 true
|
||||
deptSelected({userInfo, cacheDepartmentOwnerIds}) {
|
||||
const managed = (userInfo.managed_departments || []).map(item => ({...item, id: parseInt(item.id)}));
|
||||
const ids = (cacheDepartmentOwnerIds || []).map(id => parseInt(id));
|
||||
const selected = ids.length > 0 ? managed.filter(item => ids.includes(item.id)) : managed;
|
||||
if (selected.length === 0 || selected.length === managed.length) {
|
||||
return managed.length === 1 ? managed[0].name : this.$L('我的部门');
|
||||
return {
|
||||
managed,
|
||||
selected,
|
||||
all: selected.length === 0 || selected.length === managed.length,
|
||||
};
|
||||
},
|
||||
|
||||
deptLabel({deptSelected}) {
|
||||
const {managed, selected, all} = deptSelected;
|
||||
if (all) {
|
||||
return managed.length === 1 ? managed[0].name : this.$L('部门总览');
|
||||
}
|
||||
if (selected.length === 1) {
|
||||
return selected[0].name;
|
||||
@ -590,6 +644,22 @@ export default {
|
||||
return `${selected[0].name} +${selected.length - 1}`;
|
||||
},
|
||||
|
||||
// 移动端下拉菜单里的部门范围:全选多个部门时显示「全部部门」,其余同 deptLabel
|
||||
deptScopeLabel({deptSelected, deptLabel}) {
|
||||
if (deptSelected.all && deptSelected.managed.length > 1) {
|
||||
return this.$L('全部部门');
|
||||
}
|
||||
return deptLabel;
|
||||
},
|
||||
|
||||
// 移动端切换图标跟随当前模式(taskfont 字符)
|
||||
modeIcon({currentView, layout}) {
|
||||
if (currentView === 'team') {
|
||||
return '';
|
||||
}
|
||||
return layout === 'quad' ? '' : '';
|
||||
},
|
||||
|
||||
dashboardHello({systemConfig, userInfo, nowTime}) {
|
||||
if (systemConfig.system_welcome) {
|
||||
return this.$L(systemConfig.system_welcome).replace(/\{username}/g, userInfo.nickname);
|
||||
@ -647,7 +717,35 @@ export default {
|
||||
$A.IDBSave("dashboardView", view);
|
||||
},
|
||||
|
||||
/**
|
||||
* 头部切换器宽度跟随内容:外层设置显式宽度才能触发 CSS 过渡
|
||||
*/
|
||||
syncSegWidth() {
|
||||
const seg = this.$refs.headerSeg;
|
||||
const inner = this.$refs.headerSegInner;
|
||||
if (!seg || !inner || inner.offsetWidth === 0) {
|
||||
return; // keep-alive 隐藏时宽度为 0,不同步,避免再次显示时从 0 展开
|
||||
}
|
||||
const style = window.getComputedStyle(seg);
|
||||
const padding = parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
|
||||
seg.style.width = `${inner.offsetWidth + padding}px`;
|
||||
},
|
||||
|
||||
onModeMenu(name) {
|
||||
if (name === 'team') {
|
||||
this.setView('team');
|
||||
} else if (name === 'scope') {
|
||||
this.deptViewShow = true;
|
||||
} else {
|
||||
this.setLayout(name);
|
||||
}
|
||||
},
|
||||
|
||||
// 列表/四象限属于个人视角,选中即切回个人视角
|
||||
setLayout(layout) {
|
||||
if (this.view !== 'my') {
|
||||
this.setView('my');
|
||||
}
|
||||
this.layout = layout;
|
||||
prefsCache.layout = layout;
|
||||
$A.IDBSave("dashboardLayout", layout);
|
||||
|
||||
235
resources/assets/sass/pages/page-dashboard.scss
vendored
235
resources/assets/sass/pages/page-dashboard.scss
vendored
@ -154,75 +154,81 @@
|
||||
min-height: 40px;
|
||||
flex-shrink: 0;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
transition: width 0.2s ease;
|
||||
|
||||
> span {
|
||||
padding: 0 16px;
|
||||
min-width: 0;
|
||||
min-height: 32px;
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
// 内层保持内容自然宽度,外层宽度由 syncSegWidth 同步后过渡
|
||||
.seg-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
overflow-wrap: anywhere;
|
||||
text-align: center;
|
||||
flex-shrink: 0;
|
||||
width: max-content;
|
||||
|
||||
&.seg-active {
|
||||
background: #ffffff;
|
||||
color: #2a2b2d;
|
||||
> span {
|
||||
padding: 0 16px;
|
||||
min-width: 0;
|
||||
min-height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
overflow-wrap: anywhere;
|
||||
text-align: center;
|
||||
|
||||
&.seg-active {
|
||||
background: #ffffff;
|
||||
color: #2a2b2d;
|
||||
}
|
||||
|
||||
// 部门视角选中后,该项变为部门范围选择
|
||||
&.seg-dept {
|
||||
gap: 6px;
|
||||
max-width: 240px;
|
||||
|
||||
.dept-name {
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.dept-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
min-width: 19px;
|
||||
height: 19px;
|
||||
border-radius: 10px;
|
||||
padding: 0 5px;
|
||||
background: #e6e8ea;
|
||||
color: #5f665c;
|
||||
font-style: normal;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
// 切换部门范围时成员数被清空,加载中占位
|
||||
.dept-load {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
padding: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 部门范围选择(团队视角,占个人视角布局切换的同一槽位)
|
||||
.header-dept {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 12px;
|
||||
height: 40px;
|
||||
padding: 8px 12px;
|
||||
max-width: 260px;
|
||||
font-size: 13px;
|
||||
color: #22261f;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
|
||||
> i {
|
||||
color: #7a8078;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
> span {
|
||||
font-weight: 500;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.dept-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 19px;
|
||||
height: 19px;
|
||||
border-radius: 10px;
|
||||
padding: 0 5px;
|
||||
background: #e6e8ea;
|
||||
color: #5f665c;
|
||||
font-style: normal;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #f4f5f7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1637,6 +1643,37 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 移动端模式切换下拉项(transfer 到 body)
|
||||
.dashboard-mode-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-width: 120px;
|
||||
|
||||
> i {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
> span {
|
||||
max-width: 160px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mode-count {
|
||||
flex-shrink: 0;
|
||||
color: #a2a89f;
|
||||
font-style: normal;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.mode-arrow {
|
||||
margin-left: auto;
|
||||
color: #a2a89f;
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard-cache-popper {
|
||||
.dashboard-cache-popover {
|
||||
width: 260px;
|
||||
@ -1892,13 +1929,17 @@ body.window-portrait {
|
||||
|
||||
.dashboard-header {
|
||||
.header-left {
|
||||
.header-hello,
|
||||
.header-title > h2 {
|
||||
// 右侧只剩图标按钮,取消最小宽度避免窄屏时右侧换行
|
||||
min-width: 0;
|
||||
|
||||
.header-hello {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.header-right {
|
||||
// 只占图标实际宽度,余下空间留给标题
|
||||
flex: none;
|
||||
gap: 8px;
|
||||
|
||||
// 与右侧切换器等高对齐
|
||||
@ -1915,22 +1956,66 @@ body.window-portrait {
|
||||
}
|
||||
}
|
||||
|
||||
// 移动端模式切换:图标跟随当前模式,部门视角带成员数角标
|
||||
.header-mode {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border-radius: 12px;
|
||||
background: #f9f9f9;
|
||||
color: #7a8078;
|
||||
cursor: pointer;
|
||||
|
||||
> i {
|
||||
font-size: 20px;
|
||||
transform: scale(0.86);
|
||||
}
|
||||
|
||||
.mode-badge {
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
right: -6px;
|
||||
min-width: 16px;
|
||||
height: 16px;
|
||||
padding: 0 4px;
|
||||
border-radius: 8px;
|
||||
background: $primary-color;
|
||||
color: #ffffff;
|
||||
font-style: normal;
|
||||
font-size: 10px;
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.mode-load {
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
right: -4px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
padding: 1px;
|
||||
border-radius: 50%;
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.header-seg {
|
||||
min-height: 34px;
|
||||
align-items: center;
|
||||
|
||||
> span {
|
||||
.seg-inner > span {
|
||||
padding: 4px 10px;
|
||||
min-height: 26px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.header-dept {
|
||||
height: 34px;
|
||||
padding: 0 10px;
|
||||
max-width: 180px;
|
||||
font-size: 12px;
|
||||
&.seg-dept {
|
||||
max-width: 160px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2052,6 +2137,10 @@ body.window-portrait {
|
||||
}
|
||||
|
||||
.team-focus {
|
||||
.focus-chip {
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.focus-row {
|
||||
grid-template-columns: minmax(0, 1fr) 90px 96px;
|
||||
gap: 8px;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user