<script lang="tsx">
|
import { fileListProps } from '../props';
|
import { isFunction, isDef } from '@/utils/is';
|
import { useSortable } from '@/hooks/web/useSortable';
|
import { useModalContext } from '@/components/Modal/src/hooks/useModalContext';
|
import { defineComponent, CSSProperties, watch, nextTick, ref, onMounted } from 'vue';
|
import { FileBasicColumn } from '../types/typing';
|
|
export default defineComponent({
|
name: 'FileList',
|
props: fileListProps,
|
setup(props, { emit }) {
|
const modalFn = useModalContext();
|
const sortableContainer = ref<HTMLTableSectionElement>();
|
|
watch(
|
() => props.dataSource,
|
() => {
|
nextTick(() => {
|
modalFn?.redoModalHeight?.();
|
});
|
},
|
);
|
|
if (props.openDrag) {
|
onMounted(() =>
|
useSortable(sortableContainer, {
|
...props.dragOptions,
|
onEnd: ({ oldIndex, newIndex }) => {
|
// position unchanged
|
if (oldIndex === newIndex) {
|
return;
|
}
|
const { onAfterEnd } = props.dragOptions;
|
|
if (isDef(oldIndex) && isDef(newIndex)) {
|
const data = [...props.dataSource];
|
|
const [oldItem] = data.splice(oldIndex, 1);
|
data.splice(newIndex, 0, oldItem);
|
|
nextTick(() => {
|
emit('update:dataSource', data);
|
|
isFunction(onAfterEnd) && onAfterEnd(data);
|
});
|
}
|
},
|
}).initSortable(),
|
);
|
}
|
|
return () => {
|
const { columns, actionColumn, dataSource } = props;
|
let columnList: FileBasicColumn[];
|
columnList = (
|
actionColumn ? [...columns, actionColumn] : [...columns]
|
) as FileBasicColumn[];
|
|
return (
|
// x scrollbar
|
<div class="overflow-x-auto">
|
<table class="file-table">
|
<colgroup>
|
{columnList.map((item) => {
|
const { width = 0, dataIndex } = item;
|
const style: CSSProperties = {
|
width: `${width}px`,
|
minWidth: `${width}px`,
|
};
|
return <col style={width ? style : {}} key={dataIndex} />;
|
})}
|
</colgroup>
|
<thead>
|
<tr class="file-table-tr">
|
{columnList.map((item) => {
|
const { title = '', align = 'center', dataIndex } = item;
|
return (
|
<th class={['file-table-th', align]} key={dataIndex}>
|
{title}
|
</th>
|
);
|
})}
|
</tr>
|
</thead>
|
<tbody ref={sortableContainer}>
|
{dataSource.map((record = {}, index) => {
|
return (
|
<tr class="file-table-tr" key={`${index + record.name || ''}`}>
|
{columnList.map((item) => {
|
const { dataIndex = '', customRender, align = 'center' } = item;
|
const render = customRender && isFunction(customRender);
|
return (
|
<td class={['file-table-td break-all', align]} key={dataIndex}>
|
{render
|
? customRender?.({ text: record[dataIndex], record })
|
: record[dataIndex]}
|
</td>
|
);
|
})}
|
</tr>
|
);
|
})}
|
</tbody>
|
</table>
|
</div>
|
);
|
};
|
},
|
});
|
</script>
|
<style lang="less">
|
.file-table {
|
width: 100%;
|
border-collapse: collapse;
|
|
.center {
|
text-align: center;
|
}
|
|
.left {
|
text-align: left;
|
}
|
|
.right {
|
text-align: right;
|
}
|
|
&-th,
|
&-td {
|
padding: 12px 8px;
|
}
|
|
thead {
|
background-color: @background-color-light;
|
}
|
|
table,
|
td,
|
th {
|
border: 1px solid @border-color-base;
|
}
|
}
|
</style>
|