feat(module-management): 导航状态化阶段一——分 section 脏检查 + tab 脏点
- useModuleConfig 新增 dirtySections(逐段 JSON.stringify 对比),hasModuleChanges 改为其派生;先以整树对比语义为基准写等价断言(含「加载补全默认行即脏」的 既有怪癖),新 spec module-dirty-sections 7 用例全绿 - index.vue #label 插槽给脏 tab 渲染 6px 圆点(title/aria-label,不只靠颜色), ui/Tabs 组件零改动;groups 由列表/表单两面板共享编辑,两 tab 联动标脏 - 计划文档 docs/module-management-tab-status-plan.md(横排保留、不做分组为已决策)
This commit is contained in:
1 parent
05d0c7f304
commit
4f89f373e6
4 files changed
+297
-4
No files matched your search
@@ -189,6 +189,26 @@ const configNavItems = computed(() =>
|
||||
/* 编辑设计器:form/table 两面板 props/emits 契约一致,用动态组件消除模板重复 */
|
||||
const activeEditPanel = computed(() => (editMode.value === 'table' ? ModuleTableEditPanel : ModuleFormEditPanel))
|
||||
|
||||
/* tab 脏点:tab key → drafts section 映射。groups 在列表/表单两个面板都可编辑,
|
||||
分组变化时两个 tab 都标脏;多语言 tab 的数据独立保存(不走 drafts),不参与脏检查 */
|
||||
const TAB_SECTION_MAP = {
|
||||
basic: ['module'],
|
||||
fields: ['fields'],
|
||||
list: ['listConfig', 'groups'],
|
||||
edit: ['editConfig', 'groups'],
|
||||
query: ['queryConfig'],
|
||||
'auto-code': ['autoCode'],
|
||||
powers: ['powers'],
|
||||
}
|
||||
|
||||
const dirtyTabKeys = computed(() => {
|
||||
const keys = new Set()
|
||||
for (const [tabKey, sections] of Object.entries(TAB_SECTION_MAP)) {
|
||||
if (sections.some((section) => dirtySections.value.has(section))) keys.add(tabKey)
|
||||
}
|
||||
return keys
|
||||
})
|
||||
|
||||
/* ================= composables ================= */
|
||||
const { saveModule } = useModuleSave({
|
||||
selectedModule,
|
||||
@@ -296,6 +316,7 @@ const {
|
||||
onFieldsUpdate,
|
||||
onAutoCodeUpdate,
|
||||
syncFields,
|
||||
dirtySections,
|
||||
missingQueryCount,
|
||||
fillMissingConfigs,
|
||||
} = useModuleConfig({
|
||||
@@ -447,6 +468,14 @@ loadModuleTree()
|
||||
>
|
||||
<template #label="{ item }">
|
||||
<component :is="item.icon" :size="14" class="mm-config-nav__icon" />
|
||||
<!-- 脏点:有未保存修改的 tab 在图标后显示实心圆点(形状+title,不只靠颜色) -->
|
||||
<span
|
||||
v-if="dirtyTabKeys.has(item.key)"
|
||||
class="mm-config-nav__dirty"
|
||||
role="img"
|
||||
title="有未保存修改"
|
||||
aria-label="有未保存修改"
|
||||
></span>
|
||||
<span class="mm-config-nav__label">{{ item.label }}</span>
|
||||
<span v-if="item.badge" class="mm-config-nav__badge">{{ item.badge }}</span>
|
||||
</template>
|
||||
@@ -826,6 +855,15 @@ loadModuleTree()
|
||||
color: var(--fms-text-secondary);
|
||||
}
|
||||
|
||||
/* 脏点:作为 label 插槽的 flex 子元素排在图标后,间距由 .tabs-tab 的 gap 统一管理 */
|
||||
.mm-config-nav__dirty {
|
||||
flex: none;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--fms-primary);
|
||||
}
|
||||
|
||||
.mm-config-nav .tabs-tab-active .mm-config-nav__icon {
|
||||
color: var(--fms-primary);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user