feat: 表格列选择器增加简单模式

This commit is contained in:
RubyLiu 2024-01-17 18:48:21 +08:00 committed by Craftsman
parent a9da0370a4
commit 615e26a0c9
11 changed files with 181 additions and 23 deletions

View File

@ -58,14 +58,17 @@
<slot :name="item.titleSlotName" :column-config="item">
<div class="text-[var(--color-text-3)]">{{ t(item.title as string) }}</div>
</slot>
<icon-settings
<columnSelectorIcon
v-if="
props.showSetting &&
(item.slotName === SpecialColumnEnum.OPERATION || item.slotName === SpecialColumnEnum.ACTION)
"
class="setting-icon"
@click="handleShowSetting"
:table-key="(attrs.tableKey as string)"
:is-simple="(attrs.isSimpleSetting as boolean)"
@show-setting="handleShowSetting"
@init-data="handleInitColumn"
/>
<slot v-else-if="item.filterConfig" :name="item.filterConfig.filterSlotName">
<DefaultFilter
class="ml-[4px]"
@ -228,6 +231,7 @@
import MsCheckbox from '../ms-checkbox/MsCheckbox.vue';
import BatchAction from './batchAction.vue';
import ColumnSelector from './columnSelector.vue';
import columnSelectorIcon from './columnSelectorIcon.vue';
import DefaultFilter from './comp/defaultFilter.vue';
import SelectALL from './select-all.vue';

View File

@ -68,13 +68,13 @@
t('msTable.columnSetting.nonSort')
}}</span></a-divider
>
<VueDraggable v-model="couldSortColumn" ghost-class="ghost">
<VueDraggable v-model="couldSortColumn" handle=".sort-handle" ghost-class="ghost" @change="handleSwitchChange">
<div v-for="element in couldSortColumn" :key="element.dataIndex" class="column-drag-item">
<div class="flex w-[90%] items-center">
<MsIcon type="icon-icon_drag" class="text-[16px] text-[var(--color-text-4)]" />
<MsIcon type="icon-icon_drag" class="sort-handle cursor-move text-[16px] text-[var(--color-text-4)]" />
<span class="ml-[8px]">{{ t((element.title || element.columnTitle) as string) }}</span>
</div>
<a-switch v-model="element.showInTable" size="small" type="line" @update="handleSwitchChange" />
<a-switch v-model="element.showInTable" size="small" type="line" @change="handleSwitchChange" />
</div>
</VueDraggable>
</div>
@ -151,10 +151,6 @@
hasChange.value = true;
};
const handleDragChange = () => {
hasChange.value = true;
};
onBeforeMount(() => {
if (props.tableKey) {
tableStore.getMode(props.tableKey).then((res) => {

View File

@ -0,0 +1,146 @@
<template>
<a-popover
v-if="props.isSimple"
unmount-on-close
content-class="w-[240px]"
position="rt"
trigger="click"
@hide="handleCancel"
>
<icon-settings class="setting-icon" />
<template #content>
<div class="mb-2 flex items-center justify-between">
<div class="font-medium text-[var(--color-text-1)]">{{ t('msTable.columnSetting.display') }}</div>
<MsButton :disabled="!hasChange" @click="handleReset">{{ t('msTable.columnSetting.resetDefault') }}</MsButton>
</div>
<div class="flex-col">
<div v-for="item in nonSortColumn" :key="item.dataIndex" class="column-item">
<div>{{ t((item.title || item.columnTitle) as string) }}</div>
<a-switch v-model="item.showInTable" size="small" type="line" @change="handleSwitchChange" />
</div>
</div>
<a-divider v-if="nonSortColumn.length" orientation="center" class="non-sort"
><span class="one-line-text text-xs text-[var(--color-text-4)]">{{
t('msTable.columnSetting.nonSort')
}}</span></a-divider
>
<VueDraggable v-model="couldSortColumn" handle=".sort-handle" ghost-class="ghost" @change="handleSwitchChange">
<div v-for="element in couldSortColumn" :key="element.dataIndex" class="column-drag-item">
<div class="flex w-[90%] items-center">
<MsIcon type="icon-icon_drag" class="sort-handle cursor-move text-[16px] text-[var(--color-text-4)]" />
<span class="ml-[8px]">{{ t((element.title || element.columnTitle) as string) }}</span>
</div>
<a-switch
v-model="element.showInTable"
:disabled="element.columnSelectorDisabled"
size="small"
type="line"
@change="handleSwitchChange"
/>
</div>
</VueDraggable>
</template>
</a-popover>
<icon-settings v-else class="setting-icon" @click="handleShowSetting" />
</template>
<script setup lang="ts">
import { VueDraggable } from 'vue-draggable-plus';
import MsButton from '@/components/pure/ms-button/index.vue';
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
import { useI18n } from '@/hooks/useI18n';
import { useTableStore } from '@/store';
import { MsTableColumn } from './type';
//
const nonSortColumn = ref<MsTableColumn>([]);
//
const couldSortColumn = ref<MsTableColumn>([]);
const tableStore = useTableStore();
const { t } = useI18n();
//
const hasChange = ref(false);
const handleSwitchChange = () => {
hasChange.value = true;
};
const props = defineProps<{
tableKey: string;
isSimple: boolean;
}>();
const emit = defineEmits<{
(e: 'showSetting'): void; //
(e: 'initData'): void;
}>();
const handleCancel = async () => {
await tableStore.setColumns(props.tableKey, [...nonSortColumn.value, ...couldSortColumn.value], undefined, true);
hasChange.value = false;
emit('initData');
};
const loadColumn = (key: string) => {
tableStore.getColumns(key, true).then((res) => {
const { nonSort, couldSort } = res;
nonSortColumn.value = nonSort;
couldSortColumn.value = couldSort;
});
};
const handleReset = () => {
loadColumn(props.tableKey);
};
onBeforeMount(() => {
if (props.tableKey) {
loadColumn(props.tableKey);
}
});
const handleShowSetting = () => {
emit('showSetting');
};
</script>
<style lang="scss" scoped>
.setting-icon {
margin-left: 16px;
color: var(--color-text-4);
background-color: var(--color-text-10);
cursor: pointer;
&:hover {
color: rgba(var(--primary-5));
}
}
.column-item {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
&:hover {
border-radius: 6px;
background: var(--color-text-n9);
}
}
.column-drag-item {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
padding: 8px 0;
color: var(--color-text-1);
&:hover {
border-radius: 6px;
background-color: var(--color-text-n9);
}
}
.ghost {
border: 1px dashed rgba(var(--primary-5));
background-color: rgba(var(--primary-1));
}
</style>

View File

@ -18,7 +18,7 @@ export default {
clear: '清空',
},
columnSetting: {
display: '表显示设置',
display: '表显示设置',
mode: '模式设置',
drawer: '抽屉',
newWindow: '新窗口',

View File

@ -101,6 +101,7 @@ export interface MsTableProps<T> {
expandedKeys?: string[]; // 显示的展开行、子树(受控模式)
emptyDataShowLine?: boolean; // 空数据是否显示 "-"
showJumpMethod?: boolean; // 是否展示跳转方法
isSimpleSetting?: boolean; // 是否是简单的设置
[key: string]: any;
}

View File

@ -78,6 +78,7 @@ export default function useTableProps<T>(
/** Column Selector */
showJumpMethod: false, // 是否显示跳转方法
showFooterActionWrap: false, // 是否显示底部操作区域
isSimpleSetting: false, // 是否是简易column设置
...props,
};

View File

@ -1,6 +1,7 @@
import { filter, orderBy, sortBy } from 'lodash-es';
import localforage from 'localforage';
import { is } from '@/components/pure/minder-editor/script/tool/key';
import { MsTableColumn, MsTableColumnData } from '@/components/pure/ms-table/type';
import { useAppStore } from '@/store';
@ -58,15 +59,12 @@ export default function useTableStore() {
}
if (item.dataIndex === SpecialColumnEnum.ID) {
// dataIndex 为 id 的列默认不排序,且展示在列的最前面
item.showDrag = false;
item.sortIndex = 0;
} else if (item.dataIndex === SpecialColumnEnum.NAME) {
// dataIndex 为 name 的列默认不排序,且展示在列的第二位
item.showDrag = false;
item.sortIndex = 1;
} else if (item.dataIndex === SpecialColumnEnum.OPERATION || item.dataIndex === SpecialColumnEnum.ACTION) {
// dataIndex 为 operation 或 action 的列默认不排序,且展示在列的最后面
item.showDrag = false;
item.sortIndex = state.operationBaseIndex;
}
});
@ -112,7 +110,7 @@ export default function useTableStore() {
console.log(e);
}
}
async function setColumns(key: string, columns: MsTableColumn, mode?: TableOpenDetailMode) {
async function setColumns(key: string, columns: MsTableColumn, mode?: TableOpenDetailMode, isSimple?: boolean) {
try {
columns.forEach((item, idx) => {
if (item.showDrag) {
@ -123,6 +121,12 @@ export default function useTableStore() {
if (!selectorColumnMap) {
return;
}
if (isSimple) {
const oldColumns = selectorColumnMap[key].column;
const operationColumn = oldColumns.find((i) => i.dataIndex === SpecialColumnEnum.OPERATION);
if (operationColumn) columns.push(operationColumn);
}
selectorColumnMap[key] = {
mode,
column: JSON.parse(JSON.stringify(columns)),
@ -147,12 +151,15 @@ export default function useTableStore() {
}
return 'drawer';
}
async function getColumns(key: string) {
async function getColumns(key: string, isSimple?: boolean) {
const selectorColumnMap = await getSelectorColumnMap();
if (selectorColumnMap[key]) {
const tmpArr = selectorColumnMap[key].column;
const { nonSortableColumns, couldSortableColumns } = tmpArr.reduce(
(result: { nonSortableColumns: MsTableColumnData[]; couldSortableColumns: MsTableColumnData[] }, item) => {
if (isSimple && item.dataIndex === SpecialColumnEnum.OPERATION) {
return result;
}
if (item.showDrag) {
result.couldSortableColumns.push(item);
} else {

View File

@ -246,7 +246,7 @@
</a-modal>
</template>
<script setup lang="ts">
<script async setup lang="ts">
import MsButton from '@/components/pure/ms-button/index.vue';
import MsCodeEditor from '@/components/pure/ms-code-editor/index.vue';
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
@ -307,11 +307,13 @@
tableKey?: TableKeyEnum; // key showSettingtrue
disabled?: boolean; //
showSelectorAll?: boolean; //
isSimpleSetting?: boolean; // Column
}>(),
{
selectable: true,
showSetting: false,
tableKey: undefined,
isSimpleSetting: true,
defaultParamItem: () => ({
required: false,
name: '',
@ -350,6 +352,7 @@
showSetting: props.showSetting,
disabled: props.disabled,
showSelectorAll: props.showSelectorAll,
isSimpleSetting: props.isSimpleSetting,
});
watch(

View File

@ -55,7 +55,7 @@
import { useI18n } from '@/hooks/useI18n';
const activeKey = ref('assert');
const activeKey = ref('tcp');
const envForm = ref();
const canSave = ref(false);
const { t } = useI18n();

View File

@ -62,6 +62,7 @@
slotName: 'name',
showInTable: true,
showDrag: true,
columnSelectorDisabled: true,
},
{
title: 'project.environmental.paramType',
@ -69,6 +70,7 @@
slotName: 'type',
showInTable: true,
showDrag: true,
columnSelectorDisabled: true,
typeOptions: [
{
label: t('common.string'),
@ -104,6 +106,7 @@
slotName: 'value',
showInTable: true,
showDrag: true,
columnSelectorDisabled: true,
},
{
title: 'project.environmental.tag',
@ -124,6 +127,7 @@
title: '',
columnTitle: 'common.operation',
slotName: 'operation',
dataIndex: 'operation',
width: 50,
showInTable: true,
showDrag: true,

View File

@ -4,10 +4,6 @@
</div>
</template>
<script lang="ts" setup>
import { useI18n } from '@/hooks/useI18n';
const { t } = useI18n();
</script>
<script lang="ts" setup></script>
<style lang="less" scoped></style>