refactor(projects): 1、新增执行任务,表单优化;2、删除逻辑丰富。3、修改已知问题
This commit is contained in:
@@ -1,46 +1,151 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
||||
import { onBeforeRouteLeave } from 'vue-router';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { useWorkbenchStore } from '@/store/modules/workbench';
|
||||
import { buildWorkbenchBannerSummary } from './homepage';
|
||||
import { workbenchBannerSummaryMock } from './mock';
|
||||
import {
|
||||
buildWorkbenchActivityItems,
|
||||
buildWorkbenchBannerSummary,
|
||||
buildWorkbenchKpiCards,
|
||||
buildWorkbenchProjectItems,
|
||||
buildWorkbenchTodoItems
|
||||
} from './homepage';
|
||||
import {
|
||||
workbenchActivityMock,
|
||||
workbenchBannerSummaryMock,
|
||||
workbenchKpiMock,
|
||||
workbenchProjectMock,
|
||||
workbenchTodoMock
|
||||
} from './mock';
|
||||
type WorkbenchColumnId,
|
||||
type WorkbenchModuleKey,
|
||||
useWorkbenchModules
|
||||
} from './composables/use-workbench-modules';
|
||||
import WorkbenchBanner from './modules/workbench-banner.vue';
|
||||
import WorkbenchColumn from './modules/workbench-column.vue';
|
||||
import WorkbenchEditOverlay from './modules/workbench-edit-overlay.vue';
|
||||
import WorkbenchModuleLibrary from './modules/workbench-module-library.vue';
|
||||
import WorkbenchKpi from './modules/workbench-kpi.vue';
|
||||
import WorkbenchTodoPanel from './modules/workbench-todo-panel.vue';
|
||||
import WorkbenchActivityPanel from './modules/workbench-activity-panel.vue';
|
||||
import WorkbenchProjectGrid from './modules/workbench-project-grid.vue';
|
||||
import WorkbenchMyTask from './modules/workbench-my-task.vue';
|
||||
import WorkbenchMyRequirement from './modules/workbench-my-requirement.vue';
|
||||
import WorkbenchTeamTodo from './modules/workbench-team-todo.vue';
|
||||
import WorkbenchProjectHealth from './modules/workbench-project-health.vue';
|
||||
import WorkbenchProgressChart from './modules/workbench-progress-chart.vue';
|
||||
import WorkbenchFavorite from './modules/workbench-favorite.vue';
|
||||
import WorkbenchShortcut from './modules/workbench-shortcut.vue';
|
||||
|
||||
defineOptions({ name: 'Workbench' });
|
||||
|
||||
const { registerModuleComponent } = useWorkbenchModules();
|
||||
registerModuleComponent('kpi', WorkbenchKpi);
|
||||
registerModuleComponent('myTodo', WorkbenchTodoPanel);
|
||||
registerModuleComponent('myProject', WorkbenchProjectGrid);
|
||||
registerModuleComponent('activity', WorkbenchActivityPanel);
|
||||
registerModuleComponent('myTask', WorkbenchMyTask);
|
||||
registerModuleComponent('myRequirement', WorkbenchMyRequirement);
|
||||
registerModuleComponent('teamTodo', WorkbenchTeamTodo);
|
||||
registerModuleComponent('projectHealth', WorkbenchProjectHealth);
|
||||
registerModuleComponent('progressChart', WorkbenchProgressChart);
|
||||
registerModuleComponent('favorite', WorkbenchFavorite);
|
||||
registerModuleComponent('shortcut', WorkbenchShortcut);
|
||||
|
||||
const workbench = useWorkbenchStore();
|
||||
const libraryOpen = ref(false);
|
||||
|
||||
onMounted(() => {
|
||||
workbench.load();
|
||||
});
|
||||
|
||||
function onBeforeUnload(e: BeforeUnloadEvent) {
|
||||
if (workbench.mode === 'editing' && workbench.dirty) {
|
||||
e.preventDefault();
|
||||
e.returnValue = '';
|
||||
}
|
||||
}
|
||||
onMounted(() => window.addEventListener('beforeunload', onBeforeUnload));
|
||||
onBeforeUnmount(() => window.removeEventListener('beforeunload', onBeforeUnload));
|
||||
|
||||
watch(
|
||||
() => workbench.error,
|
||||
err => {
|
||||
if (err) window.$message?.error(`布局保存失败:${err.message}`);
|
||||
}
|
||||
);
|
||||
|
||||
const bannerSummary = computed(() => buildWorkbenchBannerSummary(workbenchBannerSummaryMock));
|
||||
const kpiCards = computed(() => buildWorkbenchKpiCards(workbenchKpiMock));
|
||||
const todoItems = computed(() => buildWorkbenchTodoItems(workbenchTodoMock));
|
||||
const activityItems = computed(() => buildWorkbenchActivityItems(workbenchActivityMock));
|
||||
const projectItems = computed(() => buildWorkbenchProjectItems(workbenchProjectMock));
|
||||
|
||||
function onColumnUpdate(columnId: WorkbenchColumnId, modules: WorkbenchModuleKey[]) {
|
||||
workbench.setColumnModules(columnId, modules);
|
||||
}
|
||||
|
||||
async function handleReset() {
|
||||
try {
|
||||
await ElMessageBox.confirm('重置后将恢复默认布局,确认继续?', '重置默认布局', { type: 'warning' });
|
||||
await workbench.resetToDefault();
|
||||
} catch {
|
||||
/* cancelled */
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeRouteLeave(async (_to, _from, next) => {
|
||||
if (workbench.mode === 'editing' && workbench.dirty) {
|
||||
try {
|
||||
await ElMessageBox.confirm('编辑布局未保存,确认离开?', '确认离开', { type: 'warning' });
|
||||
workbench.cancelEditing();
|
||||
next();
|
||||
} catch {
|
||||
next(false);
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="workbench">
|
||||
<WorkbenchBanner :summary="bannerSummary" />
|
||||
|
||||
<WorkbenchKpi :cards="kpiCards" />
|
||||
<div class="workbench__toolbar">
|
||||
<ElButton v-if="workbench.mode === 'normal'" type="primary" link @click="workbench.enterEditing">
|
||||
<SvgIcon icon="mdi:pencil-outline" />
|
||||
自定义布局
|
||||
</ElButton>
|
||||
<ElButton v-else type="primary" link @click="libraryOpen = true">
|
||||
<SvgIcon icon="mdi:view-grid-plus-outline" />
|
||||
模块库
|
||||
</ElButton>
|
||||
</div>
|
||||
|
||||
<section class="workbench__main">
|
||||
<WorkbenchTodoPanel :items="todoItems" />
|
||||
<WorkbenchActivityPanel :items="activityItems" />
|
||||
<WorkbenchEditOverlay
|
||||
v-if="workbench.mode === 'editing'"
|
||||
:dirty="workbench.dirty"
|
||||
:saving="workbench.saving"
|
||||
@save="workbench.saveEditing"
|
||||
@cancel="workbench.cancelEditing"
|
||||
@reset="handleReset"
|
||||
/>
|
||||
|
||||
<ElEmpty v-if="workbench.layout.columns.every(c => c.modules.length === 0)" description="还没有可见模块">
|
||||
<ElButton type="primary" @click="workbench.enterEditing">添加模块</ElButton>
|
||||
</ElEmpty>
|
||||
|
||||
<section v-else class="workbench__main">
|
||||
<WorkbenchColumn
|
||||
v-for="col in workbench.layout.columns"
|
||||
:key="col.id"
|
||||
:column-id="col.id"
|
||||
:modules="col.modules"
|
||||
:editing="workbench.mode === 'editing'"
|
||||
:collapsed="workbench.layout.collapsed"
|
||||
@update:modules="onColumnUpdate(col.id, $event)"
|
||||
@hide="workbench.hideModule"
|
||||
@toggle-collapse="workbench.toggleCollapse"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<WorkbenchProjectGrid :items="projectItems" />
|
||||
<WorkbenchModuleLibrary
|
||||
v-model="libraryOpen"
|
||||
:hidden-metas="workbench.hiddenMetas"
|
||||
@add-module="
|
||||
(key, col) => {
|
||||
workbench.showModule(key, col);
|
||||
libraryOpen = false;
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -50,13 +155,15 @@ const projectItems = computed(() => buildWorkbenchProjectItems(workbenchProjectM
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.workbench__toolbar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.workbench__main {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
@media (width <= 1280px) {
|
||||
.workbench__main {
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
Reference in New Issue
Block a user