Skip to content

Commit

Permalink
feat(form): groupList支持复制单条记录,支持移动单条记得到指定位置,table支持复制单条记录
Browse files Browse the repository at this point in the history
  • Loading branch information
roymondchen committed Jan 3, 2025
1 parent 833dbcd commit a831413
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 30 deletions.
10 changes: 9 additions & 1 deletion packages/form/src/containers/GroupList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
:disabled="disabled"
:group-model="model[name]"
@remove-item="removeHandler"
@copy-item="copyHandler"
@swap-item="swapHandler"
@change="changeHandler"
@addDiffCount="onAddDiffCount()"
Expand All @@ -41,6 +42,7 @@
<script setup lang="ts">
import { computed, inject } from 'vue';
import { Grid } from '@element-plus/icons-vue';
import { cloneDeep } from 'lodash-es';
import { TMagicButton } from '@tmagic/design';
Expand Down Expand Up @@ -131,11 +133,17 @@ const removeHandler = (index: number) => {
emit('change', props.model[props.name]);
};
const copyHandler = (index: number) => {
props.model[props.name].push(cloneDeep(props.model[props.name][index]));
};
const swapHandler = (idx1: number, idx2: number) => {
if (!props.name) return false;
const { length } = props.model[props.name];
const [currRow] = props.model[props.name].splice(idx1, 1);
props.model[props.name].splice(idx2, 0, currRow);
props.model[props.name].splice(Math.min(Math.max(idx2, 0), length - 1), 0, currRow);
emit('change', props.model[props.name]);
};
Expand Down
108 changes: 91 additions & 17 deletions packages/form/src/containers/GroupListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,83 @@
</TMagicButton>

<TMagicButton
v-show="showDelete(parseInt(String(index)))"
style="color: #f56c6c"
v-show="showDelete"
type="danger"
size="small"
link
:icon="Delete"
:disabled="disabled"
@click="removeHandler"
></TMagicButton>

<template v-if="movable()">
<TMagicButton v-show="index !== 0" link :disabled="disabled" size="small" @click="changeOrder(-1)"
>上移<TMagicIcon><CaretTop /></TMagicIcon
></TMagicButton>
<TMagicButton v-show="index !== length - 1" :disabled="disabled" link size="small" @click="changeOrder(1)"
>下移<TMagicIcon><CaretBottom /></TMagicIcon
></TMagicButton>
<TMagicButton
v-if="copyable"
link
size="small"
type="primary"
:icon="DocumentCopy"
:disabled="disabled"
@click="copyHandler"
>复制</TMagicButton
>

<template v-if="movable">
<TMagicButton
v-show="index !== 0"
link
size="small"
:disabled="disabled"
:icon="CaretTop"
@click="changeOrder(-1)"
>上移</TMagicButton
>
<TMagicButton
v-show="index !== length - 1"
link
size="small"
:disabled="disabled"
:icon="CaretBottom"
@click="changeOrder(1)"
>下移</TMagicButton
>
</template>

<TMagicPopover
v-if="config.moveSpecifyLocation"
trigger="click"
placement="top"
width="200"
:visible="moveSpecifyLocationVisible"
>
<template #reference>
<TMagicButton
link
size="small"
type="primary"
:icon="Position"
:disabled="disabled"
@click="moveSpecifyLocationVisible = true"
>移动至</TMagicButton
>
</template>
<div>
<div>
第<TMagicInputNumber
style="margin: 0 5px"
v-model="moveSpecifyLocationIndex"
size="small"
:min="1"
:disabled="disabled"
></TMagicInputNumber
>行
</div>
<div style="text-align: right; margin-top: 20px">
<TMagicButton size="small" text @click="moveSpecifyLocationVisible = false">取消</TMagicButton>
<TMagicButton size="small" type="primary" @click="moveSpecifyLocationHandler">确认</TMagicButton>
</div>
</div>
</TMagicPopover>

<span v-if="itemExtra" v-html="itemExtra" class="m-form-tip"></span>
</div>

Expand All @@ -44,9 +104,9 @@

<script setup lang="ts">
import { computed, inject, ref } from 'vue';
import { CaretBottom, CaretRight, CaretTop, Delete } from '@element-plus/icons-vue';
import { CaretBottom, CaretRight, CaretTop, Delete, DocumentCopy, Position } from '@element-plus/icons-vue';
import { TMagicButton, TMagicIcon } from '@tmagic/design';
import { TMagicButton, TMagicIcon, TMagicInputNumber, TMagicPopover } from '@tmagic/design';
import type { ContainerChangeEventData, FormState, GroupListConfig } from '../schema';
import { filterFunction } from '../utils/form';
Expand All @@ -70,7 +130,7 @@ const props = defineProps<{
disabled?: boolean;
}>();
const emit = defineEmits(['swap-item', 'remove-item', 'change', 'addDiffCount']);
const emit = defineEmits(['swap-item', 'remove-item', 'change', 'addDiffCount', 'copy-item']);
const mForm = inject<FormState | undefined>('mForm');
const expand = ref(props.config.expandAll || !props.index);
Expand Down Expand Up @@ -112,18 +172,18 @@ const expandHandler = () => {
};
// 希望支持单行可控制是否显示删除按钮,不会影响现有逻辑
const showDelete = (index: number) => {
const showDelete = computed(() => {
const deleteFunc = props.config.delete;
if (deleteFunc && typeof deleteFunc === 'function') {
return deleteFunc(props.model, index, mForm?.values);
return deleteFunc(props.model, props.index, mForm?.values);
}
return true;
};
});
// 调换顺序
const changeOrder = (offset = 0) => emit('swap-item', props.index, props.index + offset);
const movable = () => {
const movable = computed(() => {
const { movable } = props.config;
// 没有设置时,默认可移动
Expand All @@ -132,6 +192,20 @@ const movable = () => {
return movable(mForm, props.index || 0, props.model, props.groupModel);
}
return movable;
};
});
const copyable = computed(() => filterFunction<boolean>(mForm, props.config.copyable, props));
const onAddDiffCount = () => emit('addDiffCount');
const copyHandler = () => {
emit('copy-item', props.index);
};
const moveSpecifyLocationVisible = ref(false);
const moveSpecifyLocationIndex = ref(1);
const moveSpecifyLocationHandler = () => {
moveSpecifyLocationVisible.value = false;
emit('swap-item', props.index, moveSpecifyLocationIndex.value - 1);
};
</script>
47 changes: 40 additions & 7 deletions packages/form/src/containers/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,32 @@

<TMagicTableColumn
label="操作"
:width="config.operateColWidth || 55"
:width="config.operateColWidth || 100"
align="center"
:fixed="config.fixed === false ? undefined : 'left'"
>
<template v-slot="scope">
<slot name="operateCol" :scope="scope"></slot>
<TMagicIcon
<TMagicButton
v-show="showDelete(scope.$index + 1 + pagecontext * pagesize - 1)"
class="m-table-delete-icon"
size="small"
type="danger"
link
title="删除"
:icon="Delete"
@click="removeHandler(scope.$index + 1 + pagecontext * pagesize - 1)"
><Delete
/></TMagicIcon>
></TMagicButton>

<TMagicButton
v-if="copyable(scope.$index + 1 + pagecontext * pagesize - 1)"
link
size="small"
type="primary"
title="复制"
:icon="DocumentCopy"
:disabled="disabled"
@click="copyHandler(scope.$index + 1 + pagecontext * pagesize - 1)"
></TMagicButton>
</template>
</TMagicTableColumn>

Expand Down Expand Up @@ -189,13 +203,12 @@

<script setup lang="ts">
import { computed, inject, onMounted, ref, toRefs, watchEffect } from 'vue';
import { ArrowDown, ArrowUp, Delete, FullScreen, Grid } from '@element-plus/icons-vue';
import { ArrowDown, ArrowUp, Delete, DocumentCopy, FullScreen, Grid } from '@element-plus/icons-vue';
import { cloneDeep } from 'lodash-es';
import Sortable, { SortableEvent } from 'sortablejs';
import {
TMagicButton,
TMagicIcon,
tMagicMessage,
TMagicPagination,
TMagicTable,
Expand Down Expand Up @@ -550,6 +563,22 @@ const showDelete = (index: number) => {
return true;
};
const copyable = (index: number) => {
const copyableFunc = props.config.copyable;
if (copyableFunc && typeof copyableFunc === 'function') {
return copyableFunc(mForm, {
values: mForm?.initValues || {},
model: props.model,
parent: mForm?.parentValues || {},
formValue: mForm?.values || props.model,
prop: props.prop,
config: props.config,
index,
});
}
return true;
};
const clearHandler = () => {
const len = props.model[modelName.value].length;
props.model[modelName.value].splice(0, len);
Expand Down Expand Up @@ -594,6 +623,10 @@ const handleCurrentChange = (val: number) => {
pagecontext.value = val - 1;
};
const copyHandler = (index: number) => {
props.model[modelName.value].push(cloneDeep(props.model[modelName.value][index]));
};
const toggleMode = () => {
const calcLabelWidth = (label: string) => {
if (!label) return '0px';
Expand Down
3 changes: 3 additions & 0 deletions packages/form/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,7 @@ export interface TableConfig extends FormItem {
addable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean;
/** 是否显示删除按钮 */
delete?: (model: any, index: number, values: any) => boolean | boolean;
copyable?: (model: any, data: any) => boolean | boolean;
/** 是否显示导入按钮 */
importable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean;
/** 是否显示checkbox */
Expand Down Expand Up @@ -718,12 +719,14 @@ export interface GroupListConfig extends FormItem {
addable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean;
defaultAdd?: (mForm: FormState | undefined, data: any) => any;
delete?: (model: any, index: number | string | symbol, values: any) => boolean | boolean;
copyable?: FilterFunction<boolean>;
movable?: (
mForm: FormState | undefined,
index: number | string | symbol,
model: any,
groupModel: any,
) => boolean | boolean;
moveSpecifyLocation?: boolean;
[key: string]: any;
}

Expand Down
5 changes: 0 additions & 5 deletions packages/form/src/theme/table.scss
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,4 @@
.el-form-item {
margin-bottom: 0;
}

.m-table-delete-icon {
color: #f56c6c;
cursor: pointer;
}
}
3 changes: 3 additions & 0 deletions playground/src/configs/formDsl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ export default createForm([
{
type: 'table',
name: 'table',
copyable: true,
defautSort: { prop: 'name', order: 'descending' },
extra: 'extra',
itemExtra: (vm: any, { model }: any): any => `${model.text}itemExtra`,
Expand All @@ -232,6 +233,8 @@ export default createForm([
type: 'groupList',
name: 'groupList',
extra: '分组xxxxxxxxxxxx',
copyable: true,
moveSpecifyLocation: true,
itemExtra: (vm: any, { model }: any) => `${model.name}extra`,
items: [
{
Expand Down

0 comments on commit a831413

Please sign in to comment.