feat(脑图): 脑图快捷键屏蔽&脑图拖拽拦截&部分样式调整 (#31248)
Co-authored-by: baiqi <qi.bai@fit2cloud.com>
This commit is contained in:
parent
fdafb1236a
commit
800fcdb2ad
|
@ -469,7 +469,6 @@
|
|||
|
||||
/** radio **/
|
||||
.arco-radio-group-button {
|
||||
padding: 1px;
|
||||
background-color: var(--color-text-n8);
|
||||
.arco-radio-button {
|
||||
@apply bg-transparent;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
@content-change="handleContentChange"
|
||||
@node-select="handleNodeSelect"
|
||||
@action="handleAction"
|
||||
@before-exec-command="handleBeforeExecCommand"
|
||||
@save="handleMinderSave"
|
||||
>
|
||||
<template #extractTabContent>
|
||||
|
@ -44,7 +45,12 @@
|
|||
|
||||
import { FormItem } from '@/components/pure/ms-form-create/types';
|
||||
import MsMinderEditor from '@/components/pure/ms-minder-editor/minderEditor.vue';
|
||||
import type { MinderJson, MinderJsonNode, MinderJsonNodeData } from '@/components/pure/ms-minder-editor/props';
|
||||
import type {
|
||||
MinderEvent,
|
||||
MinderJson,
|
||||
MinderJsonNode,
|
||||
MinderJsonNodeData,
|
||||
} from '@/components/pure/ms-minder-editor/props';
|
||||
import { MsFileItem } from '@/components/pure/ms-upload/types';
|
||||
import attachment from './attachment.vue';
|
||||
import baseInfo from './basInfo.vue';
|
||||
|
@ -60,7 +66,7 @@
|
|||
} from '@/api/modules/case-management/featureCase';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import { MinderEvent } from '@/store/modules/components/minder-editor/types';
|
||||
import { MinderCustomEvent } from '@/store/modules/components/minder-editor/types';
|
||||
import { filterTree, getGenerateId, mapTree } from '@/utils';
|
||||
|
||||
import {
|
||||
|
@ -805,7 +811,7 @@
|
|||
* 处理脑图节点操作
|
||||
* @param event 脑图事件对象
|
||||
*/
|
||||
function handleAction(event: MinderEvent) {
|
||||
function handleAction(event: MinderCustomEvent) {
|
||||
const { node, name } = event;
|
||||
if (node) {
|
||||
switch (name) {
|
||||
|
@ -831,6 +837,13 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleBeforeExecCommand(event: MinderEvent) {
|
||||
if (event.commandName === 'movetoparent') {
|
||||
// TODO:拖拽拦截
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
|
|
@ -83,9 +83,8 @@
|
|||
class="list-item-action flex flex-row items-center gap-[8px] opacity-0"
|
||||
:class="{ '!opacity-100': element.id === currentId }"
|
||||
>
|
||||
<div class="icon-button">
|
||||
<div v-if="element.type === systemType" class="icon-button">
|
||||
<MsIcon
|
||||
v-if="element.type === systemType"
|
||||
v-permission="props.updatePermission"
|
||||
type="icon-icon_add_outlined"
|
||||
size="16"
|
||||
|
@ -213,9 +212,8 @@
|
|||
class="list-item-action flex flex-row items-center gap-[8px] opacity-0"
|
||||
:class="{ '!opacity-100': element.id === currentId }"
|
||||
>
|
||||
<div class="icon-button">
|
||||
<div v-if="element.type === systemType" class="icon-button">
|
||||
<MsIcon
|
||||
v-if="element.type === systemType"
|
||||
v-permission="props.updatePermission"
|
||||
type="icon-icon_add_outlined"
|
||||
size="16"
|
||||
|
@ -317,9 +315,8 @@
|
|||
class="list-item-action flex flex-row items-center gap-[8px] opacity-0"
|
||||
:class="{ '!opacity-100': element.id === currentId }"
|
||||
>
|
||||
<div class="icon-button">
|
||||
<div v-if="element.type === systemType" class="icon-button">
|
||||
<MsIcon
|
||||
v-if="element.type === systemType"
|
||||
v-permission="props.updatePermission"
|
||||
type="icon-icon_add_outlined"
|
||||
size="16"
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
import { debounce } from 'lodash-es';
|
||||
|
||||
import useMinderStore from '@/store/modules/components/minder-editor/index';
|
||||
import type { MinderEvent } from '@/store/modules/components/minder-editor/types';
|
||||
import type { MinderCustomEvent } from '@/store/modules/components/minder-editor/types';
|
||||
|
||||
import type { MinderJsonNode } from '../props';
|
||||
import type { MinderEvent, MinderJsonNode } from '../props';
|
||||
|
||||
export interface UseEventListenerProps {
|
||||
handleContentChange?: (node: MinderJsonNode) => void;
|
||||
handleSelectionChange?: (node: MinderJsonNode) => void;
|
||||
handleMinderEvent?: (event: MinderEvent) => void;
|
||||
handleMinderEvent?: (event: MinderCustomEvent) => void;
|
||||
handleBeforeExecCommand?: (event: MinderEvent) => void;
|
||||
}
|
||||
|
||||
export default function useEventListener(listener: UseEventListenerProps) {
|
||||
|
@ -34,6 +35,21 @@ export default function useEventListener(listener: UseEventListenerProps) {
|
|||
}, 300)
|
||||
);
|
||||
|
||||
// minder.on('dragStart', () => {
|
||||
// const node: MinderJsonNode = minder.getSelectedNode();
|
||||
// console.log('dragStart', node);
|
||||
// });
|
||||
|
||||
// minder.on('dragFinish', () => {
|
||||
// console.log('dragFinish', minder.history);
|
||||
// });
|
||||
|
||||
minder.on('beforeExecCommand', (e: any) => {
|
||||
if (listener.handleBeforeExecCommand) {
|
||||
listener.handleBeforeExecCommand(e);
|
||||
}
|
||||
});
|
||||
|
||||
// 监听脑图自定义事件
|
||||
watch(
|
||||
() => minderStore.event.timestamp,
|
|
@ -67,15 +67,16 @@
|
|||
import minderHeader from './main/header.vue';
|
||||
import mainEditor from './main/mainEditor.vue';
|
||||
|
||||
import { MinderEvent } from '@/store/modules/components/minder-editor/types';
|
||||
import { MinderCustomEvent } from '@/store/modules/components/minder-editor/types';
|
||||
|
||||
import useEventListener from './hooks/useEventListener';
|
||||
import useMinderEventListener from './hooks/useMinderEventListener';
|
||||
import {
|
||||
delProps,
|
||||
editMenuProps,
|
||||
headerProps,
|
||||
insertProps,
|
||||
mainEditorProps,
|
||||
MinderEvent,
|
||||
MinderJsonNode,
|
||||
moleProps,
|
||||
priorityProps,
|
||||
|
@ -90,7 +91,8 @@
|
|||
(e: 'enterNode', data: MinderJsonNode): void;
|
||||
(e: 'nodeSelect', data: MinderJsonNode): void;
|
||||
(e: 'contentChange', data: MinderJsonNode): void;
|
||||
(e: 'action', event: MinderEvent): void;
|
||||
(e: 'action', event: MinderCustomEvent): void;
|
||||
(e: 'beforeExecCommand', event: MinderEvent): void;
|
||||
}>();
|
||||
|
||||
const props = defineProps({
|
||||
|
@ -132,7 +134,7 @@
|
|||
}
|
||||
|
||||
onMounted(() => {
|
||||
useEventListener({
|
||||
useMinderEventListener({
|
||||
handleSelectionChange: () => {
|
||||
const selectedNode: MinderJsonNode = window.minder.getSelectedNode();
|
||||
if (Object.keys(window.minder).length > 0 && selectedNode) {
|
||||
|
@ -145,6 +147,9 @@
|
|||
handleMinderEvent: (event) => {
|
||||
emit('action', event);
|
||||
},
|
||||
handleBeforeExecCommand: (event) => {
|
||||
emit('beforeExecCommand', event);
|
||||
},
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -6,6 +6,19 @@ import type { MoveMode } from '@/models/common';
|
|||
|
||||
import type { PropType } from 'vue';
|
||||
|
||||
export interface MinderClass {
|
||||
stopPropagation: () => void; // 阻止事件冒泡
|
||||
stopPropagationImmediately: () => void; // 立即阻止事件冒泡
|
||||
[key: string]: any; // TODO: 其他事件属性
|
||||
}
|
||||
// TODO:脑图事件类型补充
|
||||
export interface MinderEvent extends MinderClass {
|
||||
command: any;
|
||||
commandArgs: Record<string, any>[];
|
||||
commandName: string;
|
||||
minder: any;
|
||||
type: string;
|
||||
}
|
||||
export interface MinderIconButtonItem {
|
||||
icon: string;
|
||||
tooltip: string;
|
||||
|
|
|
@ -22,11 +22,13 @@ function createDragRuntime(this: DragRuntimeOptions) {
|
|||
// when jumped to drag mode, enter
|
||||
fsm.when('* -> drag', () => {
|
||||
// now is drag mode
|
||||
minder.fire('dragStart');
|
||||
});
|
||||
|
||||
fsm.when('drag -> *', (exit: any, enter: any, reason: string) => {
|
||||
if (reason === 'drag-finish') {
|
||||
// now exit drag mode
|
||||
minder.fire('dragFinish');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -13,14 +13,6 @@ function handlerConditionMatch(condition: any, when: string, exit: string, enter
|
|||
return true;
|
||||
}
|
||||
|
||||
type Handler = () => void & {
|
||||
condition: {
|
||||
when: string;
|
||||
exit: string;
|
||||
enter: string;
|
||||
};
|
||||
};
|
||||
|
||||
class FSM {
|
||||
private currentState: string;
|
||||
|
||||
|
|
|
@ -180,6 +180,7 @@ export default function HistoryRuntime(this: { minder: any; hotbox: any; editTex
|
|||
hasUndo,
|
||||
hasRedo,
|
||||
};
|
||||
window.minderHistory = this.history;
|
||||
reset();
|
||||
minder.on('contentchange', changed);
|
||||
minder.on('import', reset);
|
||||
|
|
|
@ -7,7 +7,7 @@ export interface MinderNodePosition {
|
|||
y: number;
|
||||
}
|
||||
|
||||
export interface MinderEvent {
|
||||
export interface MinderCustomEvent {
|
||||
name: MinderEventName;
|
||||
timestamp: number;
|
||||
nodePosition?: MinderNodePosition;
|
||||
|
@ -16,6 +16,6 @@ export interface MinderEvent {
|
|||
}
|
||||
|
||||
export interface MinderState {
|
||||
event: MinderEvent;
|
||||
event: MinderCustomEvent;
|
||||
mold: number;
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
class="mb-[16px] flex items-center"
|
||||
:class="{ 'justify-between': hasAddPermission, 'justify-end': !hasAddPermission }"
|
||||
>
|
||||
<a-button v-permission="['ORGANIZATION_PROJECT:READ+ADD']" type="primary" @click="showAddProject">{{
|
||||
t('system.organization.createProject')
|
||||
}}</a-button>
|
||||
<a-button v-permission="['ORGANIZATION_PROJECT:READ+ADD']" type="primary" @click="showAddProject">
|
||||
{{ t('system.organization.createProject') }}
|
||||
</a-button>
|
||||
<a-input-search
|
||||
v-model="keyword"
|
||||
:placeholder="t('system.organization.searchIndexPlaceholder')"
|
||||
|
@ -22,15 +22,16 @@
|
|||
<a-tooltip class="tooltip-white">
|
||||
<template #content>
|
||||
<div class="flex flex-row">
|
||||
<span class="text-[var(--color-text-1)]">{{
|
||||
t('system.project.revokeDeleteToolTip', { count: record.remainDayCount })
|
||||
}}</span>
|
||||
<span class="text-[var(--color-text-1)]">
|
||||
{{ t('system.project.revokeDeleteToolTip', { count: record.remainDayCount }) }}
|
||||
</span>
|
||||
<MsButton
|
||||
v-if="hasAnyPermission(['ORGANIZATION_PROJECT:READ+RECOVER'])"
|
||||
class="ml-[8px]"
|
||||
@click="handleRevokeDelete(record)"
|
||||
>{{ t('common.revokeDelete') }}</MsButton
|
||||
>
|
||||
{{ t('common.revokeDelete') }}
|
||||
</MsButton>
|
||||
</div>
|
||||
</template>
|
||||
<MsIcon v-if="record.deleted" type="icon-icon_alarm_clock" class="ml-[4px] text-[rgb(var(--danger-6))]" />
|
||||
|
@ -44,34 +45,35 @@
|
|||
v-if="hasAnyPermission(['ORGANIZATION_PROJECT:READ+ADD_MEMBER', 'ORGANIZATION_PROJECT:READ'])"
|
||||
class="cursor-pointer text-[rgb(var(--primary-5))]"
|
||||
@click="showUserDrawer(record)"
|
||||
>{{ record.memberCount }}</span
|
||||
>
|
||||
{{ record.memberCount }}
|
||||
</span>
|
||||
<span v-else>{{ record.memberCount }}</span>
|
||||
</template>
|
||||
<template #operation="{ record }">
|
||||
<template v-if="record.deleted">
|
||||
<MsButton v-permission="['ORGANIZATION_PROJECT:READ+RECOVER']" @click="handleRevokeDelete(record)">{{
|
||||
t('common.revokeDelete')
|
||||
}}</MsButton>
|
||||
<MsButton v-permission="['ORGANIZATION_PROJECT:READ+RECOVER']" @click="handleRevokeDelete(record)">
|
||||
{{ t('common.revokeDelete') }}
|
||||
</MsButton>
|
||||
</template>
|
||||
<template v-else-if="!record.enable">
|
||||
<MsButton v-permission="['ORGANIZATION_PROJECT:READ+UPDATE']" @click="handleEnableOrDisableProject(record)">{{
|
||||
t('common.enable')
|
||||
}}</MsButton>
|
||||
<MsButton v-permission="['ORGANIZATION_PROJECT:READ+DELETE']" @click="handleDelete(record)">{{
|
||||
t('common.delete')
|
||||
}}</MsButton>
|
||||
<MsButton v-permission="['ORGANIZATION_PROJECT:READ+UPDATE']" @click="handleEnableOrDisableProject(record)">
|
||||
{{ t('common.enable') }}
|
||||
</MsButton>
|
||||
<MsButton v-permission="['ORGANIZATION_PROJECT:READ+DELETE']" @click="handleDelete(record)">
|
||||
{{ t('common.delete') }}
|
||||
</MsButton>
|
||||
</template>
|
||||
<template v-else>
|
||||
<MsButton v-permission="['ORGANIZATION_PROJECT:READ+UPDATE']" @click="showAddProjectModal(record)">{{
|
||||
t('common.edit')
|
||||
}}</MsButton>
|
||||
<MsButton v-permission="['ORGANIZATION_PROJECT:READ+ADD_MEMBER']" @click="showAddUserModal(record)">{{
|
||||
t('system.organization.addMember')
|
||||
}}</MsButton>
|
||||
<MsButton v-permission="['PROJECT_BASE_INFO:READ']" @click="enterProject(record.id)">{{
|
||||
t('system.project.enterProject')
|
||||
}}</MsButton>
|
||||
<MsButton v-permission="['ORGANIZATION_PROJECT:READ+UPDATE']" @click="showAddProjectModal(record)">
|
||||
{{ t('common.edit') }}
|
||||
</MsButton>
|
||||
<MsButton v-permission="['ORGANIZATION_PROJECT:READ+ADD_MEMBER']" @click="showAddUserModal(record)">
|
||||
{{ t('system.organization.addMember') }}
|
||||
</MsButton>
|
||||
<MsButton v-permission="['PROJECT_BASE_INFO:READ']" @click="enterProject(record.id)">
|
||||
{{ t('system.project.enterProject') }}
|
||||
</MsButton>
|
||||
<MsTableMoreAction
|
||||
v-permission="['ORGANIZATION_PROJECT:READ+DELETE']"
|
||||
:list="tableActions"
|
||||
|
|
|
@ -46,6 +46,13 @@ declare interface Window {
|
|||
minderEditor: Record<string, any>;
|
||||
km: Record<string, any>;
|
||||
canvg: (canvas: HTMLCanvasElement, xml: string, option: Record<string, any>) => void;
|
||||
minderHistory: {
|
||||
reset: () => void;
|
||||
undo: () => void;
|
||||
redo: () => void;
|
||||
hasUndo: () => boolean;
|
||||
hasRedo: () => boolean;
|
||||
};
|
||||
DTFrameLogin: (
|
||||
frameParams: IDTLoginFrameParams, // DOM包裹容器相关参数
|
||||
loginParams: IDTLoginLoginParams, // 统一登录参数
|
||||
|
|
Loading…
Reference in New Issue