refactor(projects): 1、新增执行任务,表单优化;2、删除逻辑丰富。3、修改已知问题
This commit is contained in:
158
src/views/workbench/composables/use-workbench-layout.ts
Normal file
158
src/views/workbench/composables/use-workbench-layout.ts
Normal file
@@ -0,0 +1,158 @@
|
||||
import { computed, ref } from 'vue';
|
||||
import { useDebounceFn } from '@vueuse/core';
|
||||
import { type WorkbenchColumnId, type WorkbenchModuleKey, useWorkbenchModules } from './use-workbench-modules';
|
||||
import { buildDefaultLayout } from './workbench-layout-default';
|
||||
import type { LayoutStorage } from './layout-storage';
|
||||
import { LocalStorageAdapter } from './layout-storage-local';
|
||||
import { reconcileLayout } from './workbench-layout-reconcile';
|
||||
import type { WorkbenchLayout } from './workbench-layout-types';
|
||||
|
||||
export type WorkbenchMode = 'normal' | 'editing';
|
||||
|
||||
interface UseWorkbenchLayoutOptions {
|
||||
userId: string;
|
||||
storage?: LayoutStorage;
|
||||
}
|
||||
|
||||
export function useWorkbenchLayout(options: UseWorkbenchLayoutOptions) {
|
||||
const { getAllModules } = useWorkbenchModules();
|
||||
const storage = options.storage ?? new LocalStorageAdapter();
|
||||
|
||||
const layout = ref<WorkbenchLayout>(buildDefaultLayout(getAllModules()));
|
||||
const mode = ref<WorkbenchMode>('normal');
|
||||
const dirty = ref(false);
|
||||
const saving = ref(false);
|
||||
const error = ref<Error | null>(null);
|
||||
|
||||
let snapshotBeforeEdit: WorkbenchLayout | null = null;
|
||||
|
||||
async function load() {
|
||||
const fromStorage = await storage.load(options.userId);
|
||||
layout.value = reconcileLayout(fromStorage ?? buildDefaultLayout(getAllModules()), getAllModules());
|
||||
}
|
||||
|
||||
const persist = useDebounceFn(async () => {
|
||||
saving.value = true;
|
||||
error.value = null;
|
||||
try {
|
||||
await storage.save(options.userId, layout.value);
|
||||
} catch (err) {
|
||||
error.value = err as Error;
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
}, 500);
|
||||
|
||||
function markDirty() {
|
||||
if (mode.value === 'editing') {
|
||||
dirty.value = true;
|
||||
} else {
|
||||
// 非编辑态写(如折叠)直接落盘
|
||||
persist();
|
||||
}
|
||||
}
|
||||
|
||||
function enterEditing() {
|
||||
snapshotBeforeEdit = JSON.parse(JSON.stringify(layout.value));
|
||||
mode.value = 'editing';
|
||||
dirty.value = false;
|
||||
}
|
||||
|
||||
async function saveEditing() {
|
||||
saving.value = true;
|
||||
try {
|
||||
await storage.save(options.userId, layout.value);
|
||||
mode.value = 'normal';
|
||||
dirty.value = false;
|
||||
snapshotBeforeEdit = null;
|
||||
} catch (err) {
|
||||
error.value = err as Error;
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function cancelEditing() {
|
||||
if (snapshotBeforeEdit) {
|
||||
layout.value = snapshotBeforeEdit;
|
||||
}
|
||||
mode.value = 'normal';
|
||||
dirty.value = false;
|
||||
snapshotBeforeEdit = null;
|
||||
}
|
||||
|
||||
function hideModule(key: WorkbenchModuleKey) {
|
||||
for (const col of layout.value.columns) {
|
||||
col.modules = col.modules.filter(k => k !== key);
|
||||
}
|
||||
if (!layout.value.hidden.includes(key)) layout.value.hidden.push(key);
|
||||
markDirty();
|
||||
}
|
||||
|
||||
function showModule(key: WorkbenchModuleKey, columnId: WorkbenchColumnId = 'left') {
|
||||
layout.value.hidden = layout.value.hidden.filter(k => k !== key);
|
||||
const target = layout.value.columns.find(c => c.id === columnId);
|
||||
if (target && !target.modules.includes(key)) target.modules.push(key);
|
||||
markDirty();
|
||||
}
|
||||
|
||||
function setColumnModules(columnId: WorkbenchColumnId, modules: WorkbenchModuleKey[]) {
|
||||
const target = layout.value.columns.find(c => c.id === columnId);
|
||||
if (target) target.modules = modules;
|
||||
markDirty();
|
||||
}
|
||||
|
||||
function toggleCollapse(key: WorkbenchModuleKey) {
|
||||
if (layout.value.collapsed.includes(key)) {
|
||||
layout.value.collapsed = layout.value.collapsed.filter(k => k !== key);
|
||||
} else {
|
||||
layout.value.collapsed.push(key);
|
||||
}
|
||||
markDirty();
|
||||
}
|
||||
|
||||
function updateModuleSettings<K extends keyof WorkbenchLayout['settings']>(
|
||||
key: K,
|
||||
value: WorkbenchLayout['settings'][K]
|
||||
) {
|
||||
layout.value.settings = { ...layout.value.settings, [key]: value };
|
||||
markDirty();
|
||||
}
|
||||
|
||||
async function resetToDefault() {
|
||||
layout.value = buildDefaultLayout(getAllModules());
|
||||
mode.value = 'normal';
|
||||
dirty.value = false;
|
||||
snapshotBeforeEdit = null;
|
||||
await storage.save(options.userId, layout.value);
|
||||
}
|
||||
|
||||
const isCollapsed = (key: WorkbenchModuleKey) => layout.value.collapsed.includes(key);
|
||||
|
||||
const hiddenMetas = computed(() => {
|
||||
const allMeta = getAllModules();
|
||||
return layout.value.hidden
|
||||
.map(k => allMeta.find(m => m.key === k))
|
||||
.filter((m): m is NonNullable<typeof m> => Boolean(m));
|
||||
});
|
||||
|
||||
return {
|
||||
layout,
|
||||
mode,
|
||||
dirty,
|
||||
saving,
|
||||
error,
|
||||
hiddenMetas,
|
||||
isCollapsed,
|
||||
load,
|
||||
enterEditing,
|
||||
saveEditing,
|
||||
cancelEditing,
|
||||
hideModule,
|
||||
showModule,
|
||||
setColumnModules,
|
||||
toggleCollapse,
|
||||
updateModuleSettings,
|
||||
resetToDefault
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user