@@ -0,0 +1,157 @@
<template>
{{ computedData.length }}
<el-transfer
:button-texts="buttonTexts"
:data="computedData"
:model-value="computedValue"
:titles="titles"
class="transfer"
filterable
@change="onChange"
@left-check-change="onLeftCheckChange"
@right-check-change="onRightCheckChange"
>
<template #default="{option}">
{{ option.label }}
</template>
</el-transfer>
</template>

<script lang="ts">
import {computed, defineComponent, ref} from 'vue';
import {DataItem, Key} from 'element-plus/lib/el-transfer/src/transfer';
import {UNUSED_KEY_LEFT, UNUSED_KEY_RIGHT} from '@/constants/transfer';
import {cloneArray} from '@/utils/object';
export default defineComponent({
name: 'Transfer',
props: {
value: {
type: Array,
required: false,
default: () => {
return [];
}
},
data: {
type: Array,
required: false,
default: () => {
return [];
}
},
titles: {
type: Array,
required: false,
},
buttonTexts: {
type: Array,
required: false,
},
},
emits: [
'change',
],
setup(props, {emit}) {
const leftChecked = ref<Key[]>([]);
const rightChecked = ref<Key[]>([]);
// temporary workaround for el-transfer bug: https://github.com/element-plus/element-plus/issues/1539
const computedValue = computed<Key[]>(() => {
const {value} = props as TransferProps;
if (!value) return [UNUSED_KEY_RIGHT];
const computedValue = cloneArray(value);
computedValue.push(UNUSED_KEY_RIGHT);
return computedValue;
});
// temporary workaround for el-transfer bug: https://github.com/element-plus/element-plus/issues/1539
const computedData = computed<DataItem[]>(() => {
const {data} = props as TransferProps;
if (!data) {
return [
{
key: UNUSED_KEY_LEFT,
label: '',
disabled: true,
},
{
key: UNUSED_KEY_RIGHT,
label: '',
disabled: true,
},
];
}
const computedData = cloneArray(data) as DataItem[];
computedData.push({
key: UNUSED_KEY_LEFT,
label: '',
disabled: true,
});
computedData.push({
key: UNUSED_KEY_RIGHT,
label: '',
disabled: true,
});
return computedData;
});
// temporary workaround for el-transfer bug: https://github.com/element-plus/element-plus/issues/1539
const afterCheck = () => {
// TODO: implement
const {value, data} = props as TransferProps;
const rightTotal = value.length;
const leftTotal = data.length - rightTotal;
return;
};
const onChange = (value: string[]) => {
console.log(value);
// temporary workaround for el-transfer bug: https://github.com/element-plus/element-plus/issues/1539
value = value.filter(d => ![UNUSED_KEY_LEFT, UNUSED_KEY_RIGHT].includes(d));
emit('change', value);
};
const onLeftCheckChange = (value: Key[]) => {
leftChecked.value = value;
setTimeout(afterCheck, 10);
};
const onRightCheckChange = (value: Key[]) => {
rightChecked.value = value;
setTimeout(afterCheck, 10);
};
return {
computedValue,
computedData,
onChange,
onLeftCheckChange,
onRightCheckChange,
};
},
});
</script>

<style lang="scss" scoped>
.transfer {
min-height: 480px;
}
</style>
<style scoped>
.transfer >>> .el-transfer-panel {
width: 240px;
}
.transfer >>> .el-transfer-panel,
.transfer >>> .el-transfer-panel .el-transfer-panel__body,
.transfer >>> .el-transfer-panel .el-transfer-panel__body .el-transfer-panel__list {
height: 480px;
}
/* temporary workaround for el-transfer bug: https://github.com/element-plus/element-plus/issues/1539 */
.transfer >>> .el-transfer-panel .el-transfer-panel__list > .el-checkbox:last-child {
display: none !important;
}
</style>
@@ -0,0 +1 @@
export const COLUMN_NAME_ACTIONS = 'actions';
@@ -0,0 +1,2 @@
export const UNUSED_KEY_LEFT = 'unused-key-left';
export const UNUSED_KEY_RIGHT = 'unused-key-right';
@@ -4,6 +4,7 @@ declare global {
interface TableProps {
data: any[];
columns: TableColumn[];
selectedColumnKeys: string[];
}

interface TableColumn<T = any> {
@@ -18,6 +19,7 @@ declare global {
buttons?: TableColumnButton[];
value?: TableValueFunction<T> | any;
filterItems?: TableFilterItemsFunction | SelectOption[] | string[];
disableTransfer?: boolean;
}

interface TableColumnButton {
@@ -0,0 +1,5 @@
interface TableColumnsTransferProps {
visible: boolean;
columns: TableColumn[];
selectedColumnKeys: string[];
}
@@ -0,0 +1,10 @@
import {DataItem, Key} from 'element-plus/lib/el-transfer/src/transfer';

declare global {
interface TransferProps {
value: Key[];
data: DataItem[];
titles?: string[];
buttonTexts?: string[];
}
}
@@ -2,3 +2,7 @@ export const plainClone = (obj: any) => {
if (obj === undefined || obj === null) return obj;
return JSON.parse(JSON.stringify(obj));
};

export const cloneArray = (arr: any[]) => {
return Array.from(arr);
};
@@ -26,6 +26,7 @@ import NavActions from '@/components/nav/NavActions.vue';
import NavActionGroup from '@/components/nav/NavActionGroup.vue';
import NavActionItem from '@/components/nav/NavActionItem.vue';
import {useRouter} from 'vue-router';
import {COLUMN_NAME_ACTIONS} from '@/constants/table';
export default defineComponent({
name: 'SpiderList',
@@ -117,7 +118,7 @@ export default defineComponent({
width: '140',
},
{
key: 'actions',
key: COLUMN_NAME_ACTIONS,
label: 'Actions',
width: '180',
fixed: 'right',