mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2026-11-03 08:30:42 +00:00
203 lines
5.2 KiB
Vue
203 lines
5.2 KiB
Vue
<template>
|
|
<template v-for="(action, actionIndex) in config.actions" :key="actionIndex">
|
|
<ActionPopconfirm
|
|
v-if="action.popconfirm"
|
|
:action="action"
|
|
:row="row"
|
|
:index="index"
|
|
:visible="display(action.display, row) && !editState[index]"
|
|
@confirm="actionHandler"
|
|
/>
|
|
|
|
<TMagicPopover
|
|
v-else-if="action.type === 'sub-actions'"
|
|
v-model:visible="popoverVisible"
|
|
trigger="click"
|
|
:placement="action.subActionConfig?.placement || 'bottom'"
|
|
:width="action.subActionConfig?.popoverWidth"
|
|
:popper-class="action.subActionConfig?.popoverClass"
|
|
:destroy-on-close="action.subActionConfig?.popoverDestroyOnClose ?? true"
|
|
@clickoutside="popoverVisible = false"
|
|
>
|
|
<template #reference>
|
|
<TMagicButton
|
|
v-show="action.subActionConfig?.items?.length && display(action.display, row) && !editState[index]"
|
|
class="action-btn"
|
|
link
|
|
size="small"
|
|
:type="action.buttonType || 'primary'"
|
|
:icon="popoverVisible ? ArrowDown : ArrowRight"
|
|
@click.stop="togglePopover"
|
|
></TMagicButton>
|
|
</template>
|
|
<div class="tmagic-table-sub-actions">
|
|
<template v-for="(subAction, subIndex) in action.subActionConfig?.items" :key="subIndex">
|
|
<ActionPopconfirm
|
|
v-if="subAction.popconfirm"
|
|
:action="subAction"
|
|
:row="row"
|
|
:index="index"
|
|
btn-class="sub-action-btn"
|
|
:visible="display(subAction.display, row)"
|
|
@confirm="actionHandler"
|
|
/>
|
|
|
|
<ActionButton
|
|
v-else
|
|
:action="subAction"
|
|
:row="row"
|
|
:index="index"
|
|
btn-class="sub-action-btn"
|
|
:visible="display(subAction.display, row)"
|
|
@click="actionHandler"
|
|
/>
|
|
</template>
|
|
</div>
|
|
</TMagicPopover>
|
|
|
|
<ActionButton
|
|
v-else
|
|
:action="action"
|
|
:row="row"
|
|
:index="index"
|
|
:visible="display(action.display, row) && !editState[index]"
|
|
@click="actionHandler"
|
|
/>
|
|
</template>
|
|
|
|
<TMagicButton
|
|
class="action-btn"
|
|
v-show="editState[index]"
|
|
link
|
|
type="primary"
|
|
size="small"
|
|
@click="save(index, config)"
|
|
>保存</TMagicButton
|
|
>
|
|
<TMagicButton
|
|
class="action-btn"
|
|
v-show="editState[index]"
|
|
link
|
|
type="danger"
|
|
size="small"
|
|
@click="cancel(index, config)"
|
|
>取消</TMagicButton
|
|
>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { ref } from 'vue';
|
|
|
|
// 所有行共享:同一时间仅允许一个 sub-actions 气泡展开,激活新的会自动关闭上一个
|
|
const activePopoverId = ref<symbol | null>(null);
|
|
</script>
|
|
|
|
<script lang="ts" setup>
|
|
import { watch } from 'vue';
|
|
import { ArrowDown, ArrowRight } from '@element-plus/icons-vue';
|
|
import { cloneDeep } from 'lodash-es';
|
|
|
|
import { TMagicButton, tMagicMessage, TMagicPopover } from '@tmagic/design';
|
|
|
|
import ActionButton from './ActionButton.vue';
|
|
import { display } from './actionHelpers';
|
|
import ActionPopconfirm from './ActionPopconfirm.vue';
|
|
import { ColumnActionConfig, ColumnConfig } from './schema';
|
|
|
|
defineOptions({
|
|
name: 'MTableActionsColumn',
|
|
});
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
columns: ColumnConfig[];
|
|
config: ColumnConfig;
|
|
rowkeyName?: string;
|
|
editState?: any;
|
|
row: any;
|
|
index: number;
|
|
}>(),
|
|
{
|
|
columns: () => [],
|
|
config: () => ({}),
|
|
rowkeyName: 'c_id',
|
|
editState: () => [],
|
|
},
|
|
);
|
|
|
|
const popoverId = Symbol('sub-actions-popover');
|
|
const popoverVisible = ref(false);
|
|
|
|
watch(popoverVisible, (visible) => {
|
|
if (visible) {
|
|
activePopoverId.value = popoverId;
|
|
} else if (activePopoverId.value === popoverId) {
|
|
activePopoverId.value = null;
|
|
}
|
|
});
|
|
|
|
watch(activePopoverId, (id) => {
|
|
if (id !== popoverId && popoverVisible.value) {
|
|
popoverVisible.value = false;
|
|
}
|
|
});
|
|
|
|
const togglePopover = () => {
|
|
popoverVisible.value = !popoverVisible.value;
|
|
};
|
|
|
|
const emit = defineEmits<{
|
|
'after-action': [{ index: number }];
|
|
'after-action-cancel': [{ index: number }];
|
|
}>();
|
|
|
|
const actionHandler = async (action: ColumnActionConfig, row: any, index: number) => {
|
|
await action.before?.(row, index);
|
|
if (action.type === 'edit') {
|
|
props.editState[index] = cloneDeep(row);
|
|
} else {
|
|
await action.handler?.(row, index);
|
|
}
|
|
await action.after?.(row, index);
|
|
popoverVisible.value = false;
|
|
};
|
|
|
|
const save = async (index: number, config: ColumnConfig) => {
|
|
const action = config.actions?.find((item) => item.type === 'edit')?.action;
|
|
if (!action) return;
|
|
|
|
const res: any = await action({
|
|
data: props.editState[index],
|
|
index,
|
|
});
|
|
|
|
if (res) {
|
|
if (res.ret === 0) {
|
|
tMagicMessage.success('保存成功');
|
|
props.editState[index] = undefined;
|
|
emit('after-action', { index });
|
|
} else {
|
|
tMagicMessage.error(res.msg || '保存失败');
|
|
}
|
|
} else {
|
|
props.editState[index] = undefined;
|
|
emit('after-action', { index });
|
|
}
|
|
};
|
|
|
|
const cancel = async (index: number, config: ColumnConfig) => {
|
|
props.editState[index] = undefined;
|
|
const cancel = config.actions?.find((item) => item.type === 'edit')?.cancel;
|
|
if (cancel) {
|
|
await cancel({ index });
|
|
}
|
|
emit('after-action-cancel', { index });
|
|
};
|
|
|
|
defineExpose({
|
|
actionHandler,
|
|
save,
|
|
cancel,
|
|
});
|
|
</script>
|