feat: 脑图切换显示模板

This commit is contained in:
teukkk 2024-07-11 11:00:31 +08:00 committed by 刘瑞斌
parent b330f586ef
commit a37b8f1b94
12 changed files with 138 additions and 27 deletions

View File

@ -5,6 +5,7 @@
v-model:extra-visible="extraVisible"
v-model:loading="loading"
v-model:import-json="importJson"
:minder-key="MinderKeyEnum.CASE_REVIEW_MINDER"
:extract-content-tab-list="extractContentTabList"
:can-show-float-menu="canShowFloatMenu"
:can-show-priority-menu="false"
@ -153,7 +154,7 @@
ReviewPassRule,
} from '@/models/caseManagement/caseReview';
import { ModuleTreeNode } from '@/models/common';
import { MinderEventName } from '@/enums/minderEnum';
import { MinderEventName, MinderKeyEnum } from '@/enums/minderEnum';
import { convertToFile, getCustomField } from '@/views/case-management/caseManagementFeature/components/utils';
@ -188,7 +189,6 @@
const moduleTag = t('common.module');
const importJson = ref<MinderJson>({
root: {} as MinderJsonNode,
template: 'default',
treePath: [],
});
const loading = ref(false);

View File

@ -5,6 +5,7 @@
v-model:extra-visible="extraVisible"
v-model:loading="loading"
v-model:import-json="importJson"
:minder-key="MinderKeyEnum.FEATURE_CASE_MINDER"
:tags="[]"
:replaceable-tags="replaceableTags"
:insert-node="insertNode"
@ -97,7 +98,7 @@
FeatureCaseMinderUpdateParams,
} from '@/models/caseManagement/featureCase';
import { MoveMode, TableQueryParams } from '@/models/common';
import { MinderEventName } from '@/enums/minderEnum';
import { MinderEventName, MinderKeyEnum } from '@/enums/minderEnum';
import useMinderBaseApi from './useMinderBaseApi';
import { convertToFile } from '@/views/case-management/caseManagementFeature/components/utils';
@ -139,7 +140,6 @@
} = useMinderBaseApi({ hasEditPermission });
const importJson = ref<MinderJson>({
root: {} as MinderJsonNode,
template: 'default',
treePath: [],
});
const caseTree = ref<MinderJsonNode[]>([]);

View File

@ -4,6 +4,7 @@
v-model:loading="loading"
v-model:import-json="importJson"
:tags="[]"
:minder-key="MinderKeyEnum.TEST_PLAN_MINDER"
:insert-node="(node, type) => insertNode(node as PlanMinderNode,type)"
:can-show-enter-node="false"
:insert-sibling-menus="[]"
@ -274,7 +275,7 @@
PlanMinderNodeData,
} from '@/models/testPlan/testPlan';
import { CaseLinkEnum } from '@/enums/caseEnum';
import { MinderEventName } from '@/enums/minderEnum';
import { MinderEventName, MinderKeyEnum } from '@/enums/minderEnum';
import { PlanMinderAssociateType, PlanMinderCollectionType, RunMode } from '@/enums/testPlanEnum';
const props = defineProps<{
@ -291,7 +292,6 @@
const loading = ref(false);
const importJson = ref<MinderJson>({
root: {} as MinderJsonNode,
template: 'default',
treePath: [],
});
const caseCountTag = t('ms.minders.caseCount');
@ -802,15 +802,11 @@
};
return node;
});
const template = await minderStore.getMode(MinderKeyEnum.TEST_PLAN_MINDER);
importJson.value.template = template;
window.minder.importJson(importJson.value);
if (firstInit) {
window.minder.execCommand('template', Object.keys(window.kityminder.Minder.getTemplateList())[3]);
setTimeout(() => {
//
const position = window.minder.getViewDragger().getMovement();
position.x -= position.x - 40;
window.minder.getViewDragger().moveTo(position);
}, 200);
await minderStore.setMode(MinderKeyEnum.TEST_PLAN_MINDER, importJson.value.template);
}
} catch (error) {
// eslint-disable-next-line no-console

View File

@ -67,7 +67,7 @@ export default {
main: {
header: {
minder: 'Minder',
style: 'Appearance style',
style: 'style',
},
main: {
save: 'Save',

View File

@ -61,7 +61,7 @@ export default {
main: {
header: {
minder: '思维导图',
style: '外观样式',
style: '样式',
},
main: {
save: '保存',

View File

@ -5,7 +5,36 @@
<MsIcon :type="item.icon" class="text-[var(--color-text-4)]" />
</MsButton>
</a-tooltip>
<a-divider v-if="props.iconButtons?.length" direction="vertical" :margin="0"></a-divider>
<a-dropdown v-model:popup-visible="dropdownVisible" class="structure-dropdown" @select="handleChangeMode">
<a-tooltip :content="t('minder.main.header.style')">
<MsButton
type="icon"
:class="['ms-minder-editor-header-icon-button', `${dropdownVisible ? 'dropdown-visible' : ''}`]"
>
<MsIcon
:type="ModeIcon[minderStore.getMinderActiveMode as keyof typeof ModeIcon]"
class="text-[var(--color-text-4)]"
/>
</MsButton>
</a-tooltip>
<template #content>
<a-doption
v-for="item in Object.entries(ModeIcon)"
:key="item[0]"
:value="item[0]"
:class="[
`${
item[0] === minderStore.getMinderActiveMode
? '!bg-[rgb(var(--primary-9))] !text-[rgb(var(--primary-7))]'
: 'text-[var(--color-text-4)]'
}`,
]"
>
<MsIcon :type="item[1]" />
</a-doption>
</template>
</a-dropdown>
<a-divider direction="vertical" :margin="0"></a-divider>
<a-tooltip :content="isFullScreen ? t('common.offFullScreen') : t('common.fullScreen')">
<MsButton v-if="isFullScreen" type="icon" class="ms-minder-editor-header-icon-button" @click="toggleFullScreen">
<MsIcon type="icon-icon_off_screen" class="text-[var(--color-text-4)]" />
@ -26,12 +55,17 @@
import useFullScreen from '@/hooks/useFullScreen';
import { useI18n } from '@/hooks/useI18n';
import { useMinderStore } from '@/store';
import { ModeType } from '@/store/modules/components/minder-editor/types';
import { MinderKeyEnum, ModeIcon } from '@/enums/minderEnum';
import { MinderIconButtonItem } from '../props';
const props = defineProps<{
iconButtons?: MinderIconButtonItem[];
disabled?: boolean;
minderKey?: MinderKeyEnum;
}>();
const emit = defineEmits<{
(e: 'click', eventTag: string): void;
@ -40,6 +74,14 @@
}>();
const { t } = useI18n();
const minderStore = useMinderStore();
const dropdownVisible = ref(false);
async function handleChangeMode(value: string | number | Record<string, any> | undefined) {
if (props.minderKey) {
await minderStore.setMode(props.minderKey, value as ModeType);
}
}
const containerRef = ref<Element | null>(null);
const { toggleFullScreen, isFullScreen } = useFullScreen(containerRef);
@ -78,6 +120,24 @@
color: rgb(var(--primary-4)) !important;
}
}
&.dropdown-visible {
background-color: rgb(var(--primary-9)) !important;
.arco-icon {
color: rgb(var(--primary-7)) !important;
}
}
}
}
.structure-dropdown .arco-dropdown-list {
gap: 8px;
.arco-dropdown-option {
padding: 4px;
height: 24px;
&:hover {
.arco-icon {
color: rgb(var(--primary-4));
}
}
}
}
</style>

View File

@ -1,6 +1,11 @@
<template>
<div ref="mec" class="ms-minder-container">
<minderHeader :icon-buttons="props.iconButtons" :disabled="props.disabled" @save="save" />
<minderHeader
:minder-key="props.minderKey"
:icon-buttons="props.iconButtons"
:disabled="props.disabled"
@save="save"
/>
<Navigator />
<div
v-if="currentTreePath?.length > 0"
@ -82,7 +87,6 @@
});
const innerImportJson = ref<MinderJson>({
root: {},
template: 'default',
treePath: [],
});
const currentTreePath = ref<MinderJsonNodeData[]>([]);
@ -157,7 +161,8 @@
* 切换脑图展示的节点层级
* @param node 切换的节点
*/
function switchNode(node?: MinderJsonNode | MinderJsonNodeData) {
async function switchNode(node?: MinderJsonNode | MinderJsonNodeData) {
if (!props.minderKey) return;
if (minderStore.minderUnsaved) {
//
replaceNodeInTree(
@ -175,7 +180,10 @@
} else {
innerImportJson.value = findNodePathByKey([importJson.value.root], node?.id, 'data', 'id') as MinderJson;
}
const template = await minderStore.getMode(props.minderKey);
importJson.value.template = template;
window.minder.importJson(innerImportJson.value);
await minderStore.setMode(props.minderKey, importJson.value.template);
const root: MinderJsonNode = window.minder.getRoot();
window.minder.toggleSelect(root); //
window.minder.select(root); //

View File

@ -55,7 +55,6 @@
function handleCommand(value: string | number | Record<string, any> | undefined) {
moldIndex.value = (value as number) - 1;
window.minder.execCommand('template', Object.keys(templateList.value)[(value as number) - 1]);
minderStore.setMold((value as number) - 1);
emit('moldChange', (value as number) - 1);
}

View File

@ -2,7 +2,10 @@
* Api
*/
import { ModeType } from '@/store/modules/components/minder-editor/types';
import type { MoveMode } from '@/models/common';
import { MinderKeyEnum } from '@/enums/minderEnum';
import type { PropType } from 'vue';
@ -35,7 +38,7 @@ export interface MinderJsonNode {
export interface MinderJson {
root: MinderJsonNode;
template: string;
template?: ModeType;
treePath: MinderJsonNodeData[];
}
// 脑图类
@ -58,6 +61,7 @@ export const mainEditorProps = {
type: Number,
default: 500,
},
minderKey: String as PropType<MinderKeyEnum>,
disabled: Boolean,
extractContentTabList: Array as PropType<{ label: string; value: string }[]>,
};

View File

@ -17,4 +17,16 @@ export enum MinderEventName {
'DRAG_FINISH' = 'DRAG_FINISH', // 脑图节点拖拽结束事件
}
export enum MinderKeyEnum {
FEATURE_CASE_MINDER = 'featureCaseMinder',
CASE_REVIEW_MINDER = 'caseReviewMinder',
TEST_PLAN_MINDER = 'testPlanMinder',
}
export enum ModeIcon {
right = 'icon-icon_right_branch',
default = 'icon-icon_left_and_right_branch',
filetree = 'icon-icon_lower_branch1',
}
export default {};

View File

@ -2,11 +2,12 @@ import { defineStore } from 'pinia';
import type { MinderJsonNode } from '@/components/pure/ms-minder-editor/props';
import useLocalForage from '@/hooks/useLocalForage';
import { getGenerateId, mapTree } from '@/utils';
import { MinderEventName } from '@/enums/minderEnum';
import { MinderEventName, MinderKeyEnum } from '@/enums/minderEnum';
import { MinderNodePosition, MinderState } from './types';
import { MinderNodePosition, MinderState, MinderStoreLocalItem, ModeType } from './types';
// 脑图组件的 store
const useMinderStore = defineStore('minder', {
@ -22,7 +23,7 @@ const useMinderStore = defineStore('minder', {
nodeDom: undefined,
nodes: undefined,
},
mold: 0,
activeMode: 'right',
clipboard: [],
minderUnsaved: false,
}),
@ -30,6 +31,9 @@ const useMinderStore = defineStore('minder', {
getMinderUnsaved(): boolean {
return this.minderUnsaved;
},
getMinderActiveMode(): ModeType {
return this.activeMode;
},
},
actions: {
/**
@ -58,8 +62,30 @@ const useMinderStore = defineStore('minder', {
this.setClipboard(nodes);
}
},
setMold(val: number) {
this.mold = val;
async getMode(MinderKey: MinderKeyEnum) {
const { getItem } = useLocalForage();
const minderStoreLocalMap = await getItem<MinderStoreLocalItem>(MinderKey);
if (minderStoreLocalMap?.mode) {
return minderStoreLocalMap.mode;
}
return 'right';
},
async setMode(MinderKey: MinderKeyEnum, mode: ModeType) {
const { getItem, setItem } = useLocalForage();
this.activeMode = mode;
window.minder.execCommand('template', mode);
try {
const minderStoreLocalMap = await getItem<MinderStoreLocalItem>(MinderKey);
if (minderStoreLocalMap) {
minderStoreLocalMap.mode = mode;
await setItem(MinderKey, minderStoreLocalMap);
} else {
await setItem(MinderKey, { mode });
}
} catch (e) {
// eslint-disable-next-line no-console
console.log(e);
}
},
setClipboard(nodes?: MinderJsonNode[]) {
this.clipboard = mapTree(nodes || [], (node) => {

View File

@ -2,6 +2,12 @@ import type { MinderJsonNode } from '@/components/pure/ms-minder-editor/props';
import type { MinderEventName } from '@/enums/minderEnum';
export type ModeType = 'filetree' | 'default' | 'right';
export interface MinderStoreLocalItem {
mode?: ModeType;
}
export interface MinderNodePosition {
x: number;
y: number;
@ -26,7 +32,7 @@ export interface MinderCustomEvent {
export interface MinderState {
event: MinderCustomEvent;
mold: number;
activeMode: ModeType;
clipboard: MinderJsonNode[]; // 剪切板
minderUnsaved: boolean; // 脑图是否有未保存的内容
}