add 流程设计面板

This commit is contained in:
LiuHao 2024-01-21 15:35:43 +08:00
parent 2c60905db2
commit aba0040f14
13 changed files with 1207 additions and 818 deletions

View File

@ -3,12 +3,12 @@
<div v-if="nodeName">{{ nodeName }}</div> <div v-if="nodeName">{{ nodeName }}</div>
<el-divider /> <el-divider />
<component :is="component" v-if="element" :element="element" :modeler="modeler" :users="users" :groups="groups" :categorys="categorys" /> <component :is="component" v-if="element" :element="element" :modeler="modeler" :users="users" :groups="groups" :categorys="categorys" />
<!-- <TaskPanel :element="element" :modeler="modeler" :users="users" :groups="groups" :categorys="categorys"></TaskPanel>-->
</div> </div>
</template> </template>
<script setup lang="ts" name="PropertyPanel"> <script setup lang="ts" name="PropertyPanel">
import { NodeName } from './assets/lang/zh'; import { NodeName } from './assets/lang/zh';
import TaskPanel from './panel/TaskPanel.vue'; import TaskPanel from './panel/TaskPanel.vue';
import ProcessPanel from './panel/ProcessPanel.vue';
interface propsType { interface propsType {
users: Array<any>; users: Array<any>;
groups: Array<any>; groups: Array<any>;
@ -53,7 +53,7 @@ const component = computed(() => {
if (taskType.includes(type)) return TaskPanel; if (taskType.includes(type)) return TaskPanel;
if (sequenceType.includes(type)) return 'sequenceFlowPanel'; if (sequenceType.includes(type)) return 'sequenceFlowPanel';
if (gatewayType.includes(type)) return 'gatewayPanel'; if (gatewayType.includes(type)) return 'gatewayPanel';
if (processType.includes(type)) return 'processPanel'; if (processType.includes(type)) return ProcessPanel;
return console.error('no ' + type + ' type panel'); return console.error('no ' + type + ' type panel');
}); });

File diff suppressed because it is too large Load Diff

View File

@ -5,4 +5,6 @@ import EnhancementContextPad from './ContextPad';
// 翻译模块 // 翻译模块
import TranslationModule from './Translate'; import TranslationModule from './Translate';
export default [EnhancementPaletteProvider, EnhancementContextPad, TranslationModule]; import { ModuleDeclaration } from 'didi';
const Module: ModuleDeclaration[] = [EnhancementPaletteProvider, EnhancementContextPad, TranslationModule];
export default Module;

View File

@ -0,0 +1,30 @@
import { Ref } from 'vue';
import showConfig from '@/components/BpmnDesign/assets/showConfig';
interface Options {
modeler: any;
element: any;
}
export default (ops: Options) => {
const { modeler, element } = ops;
const elementType = computed(() => {
const bizObj = element.businessObject;
return bizObj.eventDefinitions ? bizObj.eventDefinitions[0].$type : bizObj.$type;
});
const config = computed(() => showConfig[elementType.value] || {});
const updateProperties = (properties: any) => {
const modeling = modeler.get('modeling');
modeling.updateProperties(element, properties);
};
return {
elementType,
showConfig: config,
updateProperties
};
};

View File

@ -98,8 +98,8 @@ const groups = [
{ name: 'python组', id: 'python' } { name: 'python组', id: 'python' }
]; ];
const categorys = [ const categorys = [
{ name: 'OA', id: 'oa' }, { label: 'OA', id: 'oa', value: 'id' },
{ name: '财务', id: 'finance' } { label: '财务', id: 'finance', value: 'finance' }
]; ];
onMounted(() => { onMounted(() => {

View File

@ -0,0 +1,53 @@
<template>
<div>
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="80px">
<el-form-item label="流程分类" prop="processCategory">
<el-select v-model="formData.processCategory">
<el-option v-for="item in categorys" :key="item.id" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="流程标识" prop="id">
<el-input v-model="formData.id"></el-input>
</el-form-item>
<el-form-item label="流程名称" prop="name">
<el-input v-model="formData.name"></el-input>
</el-form-item>
<el-form-item label="节点描述" prop="description">
<el-input v-model="formData.description"></el-input>
</el-form-item>
<el-form-item label="执行监听器" style="margin-bottom: 0"> </el-form-item>
<ExecutionListener :modeler="modeler" :element="element"></ExecutionListener>
</el-form>
</div>
</template>
<script setup lang="ts" name="ProcessPanel">
import ExecutionListener from './property/ExecutionListener.vue';
import { ProcessPanel } from 'bpmnDesign';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
interface PropType {
modeler: any;
element: any;
categorys?: any[];
}
const props = withDefaults(defineProps<PropType>(), {
categorys: () => []
});
const formData = ref<ProcessPanel>({
processCategory: '',
id: '',
name: '',
description: ''
});
const formRules = ref<ElFormRules>({
processCategory: [{ required: true, message: '请选择', trigger: 'blur' }],
id: [{ required: true, message: '请输入', trigger: 'blur' }],
name: [{ required: true, message: '请输入', trigger: 'blur' }]
});
</script>
<style scoped lang="scss"></style>

View File

@ -1,9 +1,12 @@
<template> <template>
<div> <div>
<el-form ref="formRef"> <el-form ref="formRef" v-model="formData" label-width="80px">
<el-form-item prop="id" label="节点 id">
<el-input v-model="formData.id" placeholder="请输入"> </el-input>
</el-form-item>
<el-form-item label="任务监听器"> <el-form-item label="任务监听器">
<el-badge :value="taskListenerCount"> <el-badge :value="taskListenerCount">
<el-button @click="taskListenerRef.open()">编辑</el-button> <el-button @click="taskListenerRef.openDialog()">编辑</el-button>
</el-badge> </el-badge>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -31,6 +34,7 @@ const elementType = computed(() => {
const config = computed(() => showConfig[elementType.value] || {}); const config = computed(() => showConfig[elementType.value] || {});
const taskListenerRef = ref<InstanceType<typeof TaskListener>>(); const taskListenerRef = ref<InstanceType<typeof TaskListener>>();
const taskListenerCount = ref(0); const taskListenerCount = ref(0);
const formData = ref({});
const refreshTaskListener = (count?: number) => { const refreshTaskListener = (count?: number) => {
if (count) { if (count) {
@ -40,11 +44,6 @@ const refreshTaskListener = (count?: number) => {
props.element.businessObject.extensionElements?.values?.filter((item) => item.$type === 'flowable:TaskListener').length ?? 0; props.element.businessObject.extensionElements?.values?.filter((item) => item.$type === 'flowable:TaskListener').length ?? 0;
} }
}; };
const updateProperties = (properties: any) => {
const modeling = props.modeler.get('modeling');
modeling.updateProperties(props.element, properties);
};
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>

View File

@ -0,0 +1,269 @@
<template>
<div>
<vxe-toolbar>
<template #buttons>
<el-button type="primary" link size="small" @click="insertEvent">新增</el-button>
<el-button type="primary" link size="small" @click="removeSelectRowEvent">删除</el-button>
</template>
</vxe-toolbar>
<vxe-table
ref="tableRef"
size="mini"
height="100px"
border
show-overflow
keep-source
:data="tableData"
:menu-config="menuConfig"
:edit-rules="tableRules"
:edit-config="{ trigger: 'click', mode: 'row', showStatus: true }"
@cell-dblclick="cellDBLClickEvent"
@menu-click="contextMenuClickEvent"
>
<vxe-column type="checkbox" width="40"></vxe-column>
<vxe-column type="seq" width="40"></vxe-column>
<vxe-column field="event" title="事件" min-width="100px">
<template #default="slotParams">
<span>{{ eventSelect.find((e) => e.value === slotParams.row.event)?.label }}</span>
</template>
</vxe-column>
<vxe-column field="type" title="类型" min-width="100px">
<template #default="slotParams">
<span>{{ typeSelect.find((e) => e.value === slotParams.row.type)?.label }}</span>
</template>
</vxe-column>
<vxe-column field="className" title="Java 类名" min-width="100px"> </vxe-column>
</vxe-table>
<el-dialog
v-model="formDialog.visible.value"
:title="formDialog.title.value"
width="600px"
:close-on-click-modal="false"
:close-on-press-escape="false"
:show-close="false"
append-to-body
>
<el-form ref="formRef" :model="formData" :rules="tableRules" label-width="90px">
<el-form-item label="事件" prop="event">
<el-select v-model="formData.event">
<el-option v-for="item in eventSelect" :key="item.id" :value="item.value" :label="item.label"></el-option>
</el-select>
</el-form-item>
<el-form-item label="类型" prop="type">
<el-select v-model="formData.type">
<el-option v-for="item in typeSelect" :key="item.id" :value="item.value" :label="item.label"></el-option>
</el-select>
</el-form-item>
<el-form-item label="Java 类名" prop="className">
<el-input v-model="formData.className" type="text"></el-input>
</el-form-item>
</el-form>
<el-tabs type="border-card">
<el-tab-pane label="参数">
<ListenerParam ref="listenerParamRef" :table-data="formData.params" />
</el-tab-pane>
</el-tabs>
<template #footer>
<div class="dialog-footer">
<el-button @click="formDialog.closeDialog"> </el-button>
<el-button type="primary" @click="submitEvent"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import ListenerParam from './ListenerParam.vue';
import { VxeTableEvents, VxeTableInstance, VxeTablePropTypes } from 'vxe-table';
import { ExecutionListenerVO } from 'bpmnDesign';
import usePanel from '@/components/BpmnDesign/hooks/usePanel';
import useDialog from '@/hooks/useDialog';
const emit = defineEmits(['close']);
interface PropType {
modeler: any;
element: any;
categorys?: any[];
}
const props = withDefaults(defineProps<PropType>(), {
categorys: () => []
});
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const initData: ExecutionListenerVO = {
event: '',
type: '',
className: '',
params: []
};
const formData = reactive<ExecutionListenerVO>(initData);
const selectRow = ref<ExecutionListenerVO | null>();
const formDialog = useDialog({
title: selectRow.value ? '编辑&保存' : '新增&保存'
});
const { title, visible, openDialog, closeDialog } = useDialog({
title: '执行监听器'
});
const { showConfig, elementType, updateProperties } = usePanel({
modeler: props.modeler,
element: toRaw(props.element)
});
const listenerParamRef = ref<InstanceType<typeof ListenerParam>>();
const tableRef = ref<VxeTableInstance<ExecutionListenerVO>>();
const formRef = ref<ElFormInstance>();
const currentIndex = ref(0);
const tableData = ref<ExecutionListenerVO[]>([]);
const tableRules = ref<ElFormRules>({
event: [{ required: true, message: '请选择', trigger: 'blur' }],
type: [{ required: true, message: '请选择', trigger: 'blur' }],
className: [{ required: true, message: '请输入', trigger: 'blur' }]
});
const submitEvent = async () => {
const error = await listenerParamRef.value.validate();
await formRef.value.validate((validate) => {
if (validate && !error) {
const $table = tableRef.value;
if ($table) {
formData.params = listenerParamRef.value.getTableData();
if (selectRow.value) {
Object.assign(selectRow.value, formData);
} else {
$table.insertAt({ ...formData }, -1);
}
updateElement();
formDialog.closeDialog();
}
}
});
};
const removeSelectRowEvent = async () => {
const $table = tableRef.value;
if ($table) {
const selectCount = $table.getCheckboxRecords().length;
if (selectCount === 0) {
proxy?.$modal.msgWarning('请选择行');
} else {
await $table.removeCheckboxRow();
updateElement();
}
}
};
const insertEvent = async () => {
Object.assign(formData, initData);
selectRow.value = null;
formDialog.openDialog();
};
const editEvent = (row: ExecutionListenerVO) => {
Object.assign(formData, row);
selectRow.value = row;
formDialog.openDialog();
};
const removeEvent = async (row: ExecutionListenerVO) => {
await proxy?.$modal.confirm('您确定要删除该数据?');
const $table = tableRef.value;
if ($table) {
await $table.remove(row);
updateElement();
}
};
const updateElement = () => {
const $table = tableRef.value;
const data = $table.getTableData().fullData;
if (data.length) {
let extensionElements = props.element.businessObject.get('extensionElements');
if (!extensionElements) {
extensionElements = props.modeler.get('moddle').create('bpmn:ExtensionElements');
}
//
extensionElements.values = extensionElements.values?.filter((item) => item.$type !== 'flowable:ExecutionListener') ?? [];
data.forEach((item) => {
const executionListener = props.modeler.get('moddle').create('flowable:ExecutionListener');
executionListener['event'] = item.event;
executionListener[item.type] = item.className;
if (item.params && item.params.length) {
item.params.forEach((field) => {
const fieldElement = props.modeler.get('moddle').create('flowable:Field');
fieldElement['name'] = field.name;
fieldElement[field.type] = field.value;
executionListener.get('fields').push(fieldElement);
});
}
extensionElements.get('values').push(executionListener);
});
updateProperties({ extensionElements: extensionElements });
} else {
const extensionElements = props.element.businessObject[`extensionElements`];
if (extensionElements) {
extensionElements.values = extensionElements.values?.filter((item) => item.$type !== 'flowable:ExecutionListener') ?? [];
}
}
};
defineExpose({
openDialog
});
const cellDBLClickEvent: VxeTableEvents.CellDblclick<ExecutionListenerVO> = ({ row }) => {
editEvent(row);
};
const menuConfig = reactive<VxeTablePropTypes.MenuConfig<ExecutionListenerVO>>({
body: {
options: [
[
{ code: 'edit', name: '编辑', prefixIcon: 'vxe-icon-edit', disabled: false },
{ code: 'remove', name: '删除', prefixIcon: 'vxe-icon-delete', disabled: false }
]
]
},
visibleMethod({ options, column }) {
const isDisabled = !column;
options.forEach((list) => {
list.forEach((item) => {
item.disabled = isDisabled;
});
});
return true;
}
});
const contextMenuClickEvent: VxeTableEvents.MenuClick<ExecutionListenerVO> = ({ menu, row, column }) => {
const $table = tableRef.value;
if ($table) {
switch (menu.code) {
case 'edit':
editEvent(row);
break;
case 'remove':
removeEvent(row);
break;
}
}
};
const typeSelect = [
{ id: '742fdeb7-23b4-416b-ac66-cd4ec8b901b7', label: '类', value: 'class' },
{ id: '660c9c46-8fae-4bae-91a0-0335420019dc', label: '表达式', value: 'expression' },
{ id: '4b8135ab-6bc3-4a0f-80be-22f58bc6c5fd', label: '委托表达式', value: 'delegateExpression' }
];
const eventSelect = [
{ id: 'e6e0a51a-2d5d-4dc4-b847-b5c14f43a6ab', label: 'start', value: 'start' },
{ id: '6da97c1e-15fc-4445-8943-75d09f49778e', label: 'end', value: 'end' },
{ id: '6a2cbcec-e026-4f11-bef7-fff0b5c871e2', label: 'take', value: 'take' }
];
</script>
<style scoped lang="scss">
.el-badge {
:deep(.el-badge__content) {
top: 10px;
}
}
</style>

View File

@ -1,107 +1,89 @@
<template> <template>
<el-dialog <vxe-toolbar>
:model-value="visible" <template #buttons>
title="监听器参数" <el-button icon="Plus" @click="insertRow">新增</el-button>
width="700px"
:close-on-click-modal="false"
:close-on-press-escape="false"
:show-close="false"
append-to-body
>
<vxe-toolbar>
<template #buttons>
<el-button icon="Plus" @click="insertRow">新增</el-button>
</template>
</vxe-toolbar>
<vxe-table
ref="tableRef"
height="300px"
border
show-overflow
keep-source
:data="tableData"
:edit-rules="tableRules"
:edit-config="{ trigger: 'click', mode: 'row', showStatus: true }"
>
<vxe-column type="seq" width="40"></vxe-column>
<vxe-column field="type" title="类型" :edit-render="{}">
<template #default="slotParams">
<span>{{ typeSelect.find((e) => e.value === slotParams.row.type)?.label }}</span>
</template>
<template #edit="slotParams">
<vxe-select v-model="slotParams.row.type">
<vxe-option v-for="item in typeSelect" :key="item.id" :value="item.value" :label="item.label"></vxe-option>
</vxe-select>
</template>
</vxe-column>
<vxe-column field="name" title="名称" :edit-render="{}">
<template #edit="slotParams">
<vxe-input v-model="slotParams.row.name" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="value" title="值" :edit-render="{}">
<template #edit="slotParams">
<vxe-input v-model="slotParams.row.value" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column title="操作" width="100" show-overflow align="center">
<template #default="slotParams">
<el-tooltip content="删除" placement="top">
<el-button link type="danger" icon="Delete" @click="removeRow(slotParams.row)"></el-button>
</el-tooltip>
</template>
</vxe-column>
</vxe-table>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
</div>
</template> </template>
</el-dialog> </vxe-toolbar>
<vxe-table
ref="tableRef"
:height="height"
border
show-overflow
keep-source
:data="tableData"
:edit-rules="tableRules"
:edit-config="{ trigger: 'click', mode: 'row', showStatus: true }"
>
<vxe-column type="seq" width="40"></vxe-column>
<vxe-column field="type" title="类型" :edit-render="{}">
<template #default="slotParams">
<span>{{ typeSelect.find((e) => e.value === slotParams.row.type)?.label }}</span>
</template>
<template #edit="slotParams">
<vxe-select v-model="slotParams.row.type">
<vxe-option v-for="item in typeSelect" :key="item.id" :value="item.value" :label="item.label"></vxe-option>
</vxe-select>
</template>
</vxe-column>
<vxe-column field="name" title="名称" :edit-render="{}">
<template #edit="slotParams">
<vxe-input v-model="slotParams.row.name" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="value" title="值" :edit-render="{}">
<template #edit="slotParams">
<vxe-input v-model="slotParams.row.value" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column title="操作" width="100" show-overflow align="center">
<template #default="slotParams">
<el-tooltip content="删除" placement="top">
<el-button link type="danger" icon="Delete" @click="removeRow(slotParams.row)"></el-button>
</el-tooltip>
</template>
</vxe-column>
</vxe-table>
</template> </template>
<script setup lang="ts" name="ListenerParam"> <script setup lang="ts" name="ListenerParam">
import { VXETable, VxeTableInstance, VxeTablePropTypes } from 'vxe-table'; import { VXETable, VxeTableInstance, VxeTablePropTypes } from 'vxe-table';
import { ParamVO } from 'bpmnDesign'; import { ParamVO } from 'bpmnDesign';
import useDialog from '@/hooks/useDialog';
interface PropType { interface PropType {
modelValue: ParamVO[]; height?: string;
visible?: boolean; tableData?: ParamVO[];
} }
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const props = withDefaults(defineProps<PropType>(), { const props = withDefaults(defineProps<PropType>(), {
visible: false height: '200px',
tableData: () => []
}); });
const tableData = computed(() => props.modelValue);
const tableRules = ref<VxeTablePropTypes.EditRules>({ const tableRules = ref<VxeTablePropTypes.EditRules>({
type: [{ required: true, message: '请选择', trigger: 'blur' }], type: [{ required: true, message: '请选择', trigger: 'blur' }],
name: [{ required: true, message: '请输入', trigger: 'blur' }], name: [{ required: true, message: '请输入', trigger: 'blur' }],
value: [{ required: true, message: '请输入', trigger: 'blur' }] value: [{ required: true, message: '请输入', trigger: 'blur' }]
}); });
const emits = defineEmits(['update:modelValue', 'update:visible']); const { title, visible, openDialog, closeDialog } = useDialog({
title: '监听器参数'
});
const typeSelect = [ const typeSelect = [
{ id: '742fdeb7-23b4-416b-ac66-cd4ec8b901b7', label: '字符串', value: 'stringValue' }, { id: '742fdeb7-23b4-416b-ac66-cd4ec8b901b7', label: '字符串', value: 'stringValue' },
{ id: '660c9c46-8fae-4bae-91a0-0335420019dc', label: '表达式', value: 'expression' } { id: '660c9c46-8fae-4bae-91a0-0335420019dc', label: '表达式', value: 'expression' }
]; ];
const tableRef = ref<VxeTableInstance<ParamVO>>(); const tableRef = ref<VxeTableInstance<ParamVO>>();
const submitForm = async () => {
const getTableData = () => {
const $table = tableRef.value; const $table = tableRef.value;
if ($table) { if ($table) {
const errMap = await $table.validate(true); return $table.getTableData().fullData;
if (errMap) {
proxy?.$modal.msgError('校验不通过');
} else {
emits('update:modelValue', $table.getTableData().fullData);
emits('update:visible', false);
}
} }
return [];
}; };
const insertRow = async () => { const insertRow = async () => {
@ -120,6 +102,20 @@ const removeRow = async (row: ParamVO) => {
await $table.remove(row); await $table.remove(row);
} }
}; };
const validate = async () => {
const $table = tableRef.value;
if ($table) {
return await $table.validate(true);
}
};
defineExpose({
closeDialog,
openDialog,
validate,
getTableData
});
</script> </script>
<style scoped lang="scss"></style> <style scoped lang="scss"></style>

View File

@ -1,8 +1,8 @@
<template> <template>
<div> <div>
<el-dialog <el-dialog
:model-value="visible" v-model="visible"
title="任务监听器" :title="title"
width="900px" width="900px"
:close-on-click-modal="false" :close-on-click-modal="false"
:close-on-press-escape="false" :close-on-press-escape="false"
@ -66,20 +66,31 @@
</template> </template>
</vxe-column> </vxe-column>
</vxe-table> </vxe-table>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button type="primary" size="small" @click="submitForm"> </el-button> <el-button @click="closeDialog"> </el-button>
<el-button type="primary" @click="submitForm"> </el-button>
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
<ListenerParam v-if="showParamDialog" v-model:visible="showParamDialog" v-model="tableData[currentIndex].params" />
<ListenerParam
ref="listenerParamRef"
@update-data="
(data: ParamVO[]) => {
tableData[currentIndex].params = data;
}
"
/>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import ListenerParam from './ListenerParam.vue'; import ListenerParam from './ListenerParam.vue';
import showConfig from '../../assets/showConfig';
import { VxeTableInstance, VxeTablePropTypes } from 'vxe-table'; import { VxeTableInstance, VxeTablePropTypes } from 'vxe-table';
import { TaskListenerVO } from 'bpmnDesign'; import { ParamVO, TaskListenerVO } from 'bpmnDesign';
import usePanel from '@/components/BpmnDesign/hooks/usePanel';
import useDialog from '@/hooks/useDialog';
const emit = defineEmits(['close']); const emit = defineEmits(['close']);
@ -94,13 +105,15 @@ const props = withDefaults(defineProps<PropType>(), {
categorys: () => [] categorys: () => []
}); });
const elementType = computed(() => { const { title, visible, openDialog, closeDialog } = useDialog({
const bizObj = props.element.businessObject; title: '任务监听器'
return bizObj.eventDefinitions ? bizObj.eventDefinitions[0].$type : bizObj.$type; });
const { showConfig, elementType, updateProperties } = usePanel({
modeler: props.modeler,
element: toRaw(props.element)
}); });
const config = computed(() => showConfig[elementType.value] || {});
const visible = ref(false); const listenerParamRef = ref<InstanceType<typeof ListenerParam>>();
const tableRef = ref<VxeTableInstance<TaskListenerVO>>(); const tableRef = ref<VxeTableInstance<TaskListenerVO>>();
const currentIndex = ref(0); const currentIndex = ref(0);
const tableData = ref<TaskListenerVO[]>([]); const tableData = ref<TaskListenerVO[]>([]);
@ -126,18 +139,21 @@ const eventSelect = [
const configParam = (i: number) => { const configParam = (i: number) => {
currentIndex.value = i; currentIndex.value = i;
showParamDialog.value = true; showParamDialog.value = true;
listenerParamRef.value.openDialog();
}; };
const insertRow = async () => { const insertRow = async () => {
const $table = tableRef.value; const $table = tableRef.value;
if ($table) { if ($table) {
tableData.value.push({ const { row: newRow } = await $table.insertAt(
className: '', {
type: '', className: '',
name: '', type: '',
event: '', name: '',
params: [] event: '',
}); params: []
const { row: newRow } = await $table.insertAt({}, -1); },
-1
);
// //
await $table.validate(newRow); await $table.validate(newRow);
} }
@ -164,7 +180,6 @@ const submitForm = async () => {
} }
}; };
const open = () => (visible.value = true);
const updateElement = () => { const updateElement = () => {
if (tableData.value.length) { if (tableData.value.length) {
let extensionElements = props.element.businessObject.get('extensionElements'); let extensionElements = props.element.businessObject.get('extensionElements');
@ -199,12 +214,8 @@ const updateElement = () => {
} }
}; };
const updateProperties = (properties: any) => {
const modeling = props.modeler.get('modeling');
modeling.updateProperties(toRaw(props.element), properties);
};
defineExpose({ defineExpose({
open openDialog
}); });
</script> </script>

25
src/hooks/useDialog.ts Normal file
View File

@ -0,0 +1,25 @@
import { ref } from 'vue';
interface Options {
title?: string;
}
export default (ops?: Options) => {
const visible = ref(false);
const title = ref(ops.title || '');
const openDialog = () => {
visible.value = true;
};
const closeDialog = () => {
visible.value = false;
};
return {
title,
visible,
openDialog,
closeDialog
};
};

View File

@ -33,6 +33,9 @@ import i18n from '@/lang/index';
// vxeTable // vxeTable
import VXETable from 'vxe-table'; import VXETable from 'vxe-table';
import 'vxe-table/lib/style.css'; import 'vxe-table/lib/style.css';
VXETable.config({
zIndex: 999999
});
const app = createApp(App); const app = createApp(App);

14
src/types/bpmn.d.ts vendored
View File

@ -12,4 +12,18 @@ declare module 'bpmnDesign' {
className: string; className: string;
params: ParamVO[]; params: ParamVO[];
} }
export interface ExecutionListenerVO {
event: string;
type: string;
className: string;
params: ParamVO[];
}
export interface ProcessPanel {
processCategory: string;
id: string;
name: string;
description: string;
}
} }