@gct-paas/v-ben 0.1.6-dev.9 → 6.0.0-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -0
- package/dist/index.min.css +1 -1
- package/dist/loader.esm.min.js +2 -1
- package/es/_virtual/_rolldown/runtime.mjs +13 -0
- package/es/components/index.mjs +1 -0
- package/es/components/v-ben-button/src/BasicButton.vue_vue_type_script_setup_true_lang.mjs +0 -1
- package/es/components/v-ben-button/src/PopConfirmButton.vue_vue_type_script_lang.mjs +1 -1
- package/es/components/v-ben-table/index.d.ts +2 -0
- package/es/components/v-ben-table/index.mjs +1 -0
- package/es/components/v-ben-table/src/BasicTable.vue.d.ts +49 -25
- package/es/components/v-ben-table/src/BasicTable.vue.mjs +34 -16
- package/es/components/v-ben-table/src/BasicTable.vue_vue_type_script_lang.mjs +113 -17
- package/es/components/v-ben-table/src/BasicTable.vue_vue_type_style_index_0_lang.css +81 -0
- package/es/components/v-ben-table/src/components/TableAction.vue_vue_type_script_setup_true_lang.mjs +4 -10
- package/es/components/v-ben-table/src/components/TableAction.vue_vue_type_style_index_0_lang.css +13 -12
- package/es/components/v-ben-table/src/components/TableActionAuto.vue_vue_type_script_setup_true_lang.mjs +3 -3
- package/es/components/v-ben-table/src/components/TableActionAuto.vue_vue_type_style_index_0_lang.css +13 -12
- package/es/components/v-ben-table/src/components/TableHeader.vue.d.ts +2 -0
- package/es/components/v-ben-table/src/components/TableHeader.vue.mjs +13 -0
- package/es/components/v-ben-table/src/components/TableHeader.vue_vue_type_script_lang.mjs +5 -0
- package/es/components/v-ben-table/src/components/TableHeader.vue_vue_type_style_index_0_lang.css +9 -0
- package/es/components/v-ben-table/src/const.d.ts +12 -0
- package/es/components/v-ben-table/src/const.mjs +14 -0
- package/es/components/v-ben-table/src/hooks/useColumns.d.ts +8 -0
- package/es/components/v-ben-table/src/hooks/useColumns.mjs +180 -0
- package/es/components/v-ben-table/src/hooks/usePagination.d.ts +10 -0
- package/es/components/v-ben-table/src/hooks/usePagination.mjs +63 -0
- package/es/components/v-ben-table/src/hooks/useTable.d.ts +6 -0
- package/es/components/v-ben-table/src/hooks/useTable.mjs +21 -0
- package/es/components/v-ben-table/src/hooks/useTableExpand.d.ts +9 -0
- package/es/components/v-ben-table/src/hooks/useTableExpand.mjs +62 -0
- package/es/components/v-ben-table/src/hooks/useTableHeader.d.ts +4 -0
- package/es/components/v-ben-table/src/hooks/useTableHeader.mjs +11 -0
- package/es/components/v-ben-table/src/hooks/useTableRowDrag.d.ts +7 -0
- package/es/components/v-ben-table/src/hooks/useTableRowDrag.mjs +148 -0
- package/es/components/v-ben-table/src/hooks/useTableScroll.d.ts +17 -0
- package/es/components/v-ben-table/src/hooks/useTableScroll.mjs +126 -0
- package/es/components/v-ben-table/src/props.d.ts +8 -1
- package/es/components/v-ben-table/src/props.mjs +46 -1
- package/es/components/v-ben-table/src/types/pagination.d.ts +1 -1
- package/es/components/v-ben-table/src/types/table.d.ts +16 -0
- package/es/components/v-ben-table/src/utils/dom-utils.d.ts +13 -0
- package/es/components/v-ben-table/src/utils/dom-utils.mjs +36 -0
- package/es/components/v-ben-table/src/utils/tsxHelper.d.ts +13 -0
- package/es/components/v-ben-table/src/utils/tsxHelper.mjs +17 -0
- package/es/hooks/useDesign.mjs +10 -0
- package/es/hooks/useRefs.d.ts +5 -0
- package/es/hooks/useRefs.mjs +17 -0
- package/es/index.d.ts +2 -0
- package/es/index.mjs +4 -1
- package/es/locale/auto-register.d.ts +2 -0
- package/es/locale/auto-register.mjs +13 -0
- package/es/locale/sys/component.d.ts +6 -0
- package/es/locale/sys/component.mjs +6 -0
- package/es/locale/sys.mjs +9 -0
- package/es/setup-app.d.ts +2 -0
- package/es/setup-app.mjs +7 -0
- package/es/types/sortablejs.d.ts +24 -0
- package/package.json +8 -8
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { isBoolean } from "../../../../utils/is.mjs";
|
|
2
|
+
import { PAGE_SIZE_OPTIONS } from "../const.mjs";
|
|
3
|
+
import { LeftOutlined, RightOutlined } from "@ant-design/icons-vue";
|
|
4
|
+
import { computed, h, ref, unref, watch } from "vue";
|
|
5
|
+
import { t } from "@gct-paas/core";
|
|
6
|
+
//#region src/components/v-ben-table/src/hooks/usePagination.ts
|
|
7
|
+
function itemRender({ page, type, originalElement }) {
|
|
8
|
+
if (type === "prev") return page === 0 ? null : h(LeftOutlined);
|
|
9
|
+
if (type === "next") return page === 1 ? null : h(RightOutlined);
|
|
10
|
+
return originalElement;
|
|
11
|
+
}
|
|
12
|
+
function usePagination(refProps) {
|
|
13
|
+
const configRef = ref({});
|
|
14
|
+
const show = ref(true);
|
|
15
|
+
watch(() => unref(refProps).pagination, (pagination) => {
|
|
16
|
+
if (!isBoolean(pagination) && pagination) configRef.value = {
|
|
17
|
+
...unref(configRef),
|
|
18
|
+
...pagination
|
|
19
|
+
};
|
|
20
|
+
}, { deep: true });
|
|
21
|
+
const getPaginationInfo = computed(() => {
|
|
22
|
+
const { pagination } = unref(refProps);
|
|
23
|
+
if (!unref(show) || isBoolean(pagination) && !pagination) return false;
|
|
24
|
+
return {
|
|
25
|
+
current: 1,
|
|
26
|
+
pageSize: 20,
|
|
27
|
+
size: "small",
|
|
28
|
+
defaultPageSize: 20,
|
|
29
|
+
showTotal: (total) => t("sys.component.table.total", { total }),
|
|
30
|
+
showSizeChanger: true,
|
|
31
|
+
pageSizeOptions: PAGE_SIZE_OPTIONS,
|
|
32
|
+
itemRender,
|
|
33
|
+
showQuickJumper: true,
|
|
34
|
+
...isBoolean(pagination) ? {} : pagination ?? {},
|
|
35
|
+
...unref(configRef)
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
function setPagination(info) {
|
|
39
|
+
const paginationInfo = unref(getPaginationInfo);
|
|
40
|
+
configRef.value = {
|
|
41
|
+
...!isBoolean(paginationInfo) ? paginationInfo : {},
|
|
42
|
+
...info
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function getPagination() {
|
|
46
|
+
return unref(getPaginationInfo);
|
|
47
|
+
}
|
|
48
|
+
function getShowPagination() {
|
|
49
|
+
return unref(show);
|
|
50
|
+
}
|
|
51
|
+
async function setShowPagination(flag) {
|
|
52
|
+
show.value = flag;
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
getPagination,
|
|
56
|
+
getPaginationInfo,
|
|
57
|
+
setShowPagination,
|
|
58
|
+
getShowPagination,
|
|
59
|
+
setPagination
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { usePagination };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { onUnmounted, ref, unref } from "vue";
|
|
2
|
+
//#region src/components/v-ben-table/src/hooks/useTable.ts
|
|
3
|
+
function useTable() {
|
|
4
|
+
const tableRef = ref(null);
|
|
5
|
+
function register(instance, _formInstance) {
|
|
6
|
+
onUnmounted(() => {
|
|
7
|
+
tableRef.value = null;
|
|
8
|
+
});
|
|
9
|
+
tableRef.value = instance;
|
|
10
|
+
}
|
|
11
|
+
function getTableInstance() {
|
|
12
|
+
const table = unref(tableRef);
|
|
13
|
+
if (!table) console.error("The table instance has not been obtained yet, please make sure the table is presented when performing the table operation!");
|
|
14
|
+
return table;
|
|
15
|
+
}
|
|
16
|
+
return [register, { expandAll: () => {
|
|
17
|
+
getTableInstance().expandAll();
|
|
18
|
+
} }];
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { useTable };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ComputedRef } from 'vue';
|
|
2
|
+
import { BasicTableProps } from '../types/table';
|
|
3
|
+
export declare function useTableExpand(propsRef: ComputedRef<BasicTableProps>, tableData: ComputedRef<Recordable[]>, hasExpandableSlot: ComputedRef<boolean>, emit: (event: 'expanded-rows-change', keys: string[]) => void): {
|
|
4
|
+
getExpandOption: ComputedRef<IObject>;
|
|
5
|
+
expandedRowKeys: import('vue').Ref<string[], string[]>;
|
|
6
|
+
expandAll: () => void;
|
|
7
|
+
expandRows: (keys: string[]) => void;
|
|
8
|
+
collapseAll: () => void;
|
|
9
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { computed, ref, toRaw, unref, watch } from "vue";
|
|
2
|
+
//#region src/components/v-ben-table/src/hooks/useTableExpand.ts
|
|
3
|
+
var NO_TREE_CHILDREN_COLUMN = "__NO_TREE_CHILDREN__";
|
|
4
|
+
function useTableExpand(propsRef, tableData, hasExpandableSlot, emit) {
|
|
5
|
+
const { expandedRowKeys: propsExpandedRowKeys = [] } = unref(propsRef);
|
|
6
|
+
const expandedRowKeys = ref([...propsExpandedRowKeys]);
|
|
7
|
+
const shouldManageExpand = computed(() => {
|
|
8
|
+
return !!unref(propsRef).isTreeTable || unref(hasExpandableSlot);
|
|
9
|
+
});
|
|
10
|
+
const getAutoCreateKey = computed(() => {
|
|
11
|
+
return unref(propsRef).autoCreateKey && !unref(propsRef).rowKey;
|
|
12
|
+
});
|
|
13
|
+
const getRowKey = computed(() => {
|
|
14
|
+
const { rowKey } = unref(propsRef);
|
|
15
|
+
return unref(getAutoCreateKey) ? "key" : rowKey;
|
|
16
|
+
});
|
|
17
|
+
watch(() => unref(propsRef).expandedRowKeys, (val) => {
|
|
18
|
+
if (val !== void 0 && val !== null) expandedRowKeys.value = [...val];
|
|
19
|
+
});
|
|
20
|
+
watch(expandedRowKeys, (keys) => {
|
|
21
|
+
if (unref(shouldManageExpand)) emit("expanded-rows-change", keys);
|
|
22
|
+
}, { deep: true });
|
|
23
|
+
const getExpandOption = computed(() => {
|
|
24
|
+
if (!unref(shouldManageExpand)) return {};
|
|
25
|
+
const { isTreeTable, childrenColumnName } = unref(propsRef);
|
|
26
|
+
const options = {};
|
|
27
|
+
if (unref(hasExpandableSlot) && !isTreeTable && !childrenColumnName) options.childrenColumnName = NO_TREE_CHILDREN_COLUMN;
|
|
28
|
+
return options;
|
|
29
|
+
});
|
|
30
|
+
function expandAll() {
|
|
31
|
+
expandedRowKeys.value = getAllKeys();
|
|
32
|
+
}
|
|
33
|
+
function expandRows(keys) {
|
|
34
|
+
if (!unref(shouldManageExpand)) return;
|
|
35
|
+
expandedRowKeys.value = [...expandedRowKeys.value, ...keys];
|
|
36
|
+
}
|
|
37
|
+
function getAllKeys(data) {
|
|
38
|
+
const keys = [];
|
|
39
|
+
const { isTreeTable, childrenColumnName } = unref(propsRef);
|
|
40
|
+
const childrenField = childrenColumnName || "children";
|
|
41
|
+
toRaw(data || unref(tableData)).forEach((item) => {
|
|
42
|
+
keys.push(String(item[unref(getRowKey)]));
|
|
43
|
+
if (isTreeTable) {
|
|
44
|
+
const children = item[childrenField];
|
|
45
|
+
if (children?.length) keys.push(...getAllKeys(children));
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return keys;
|
|
49
|
+
}
|
|
50
|
+
function collapseAll() {
|
|
51
|
+
expandedRowKeys.value = [];
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
getExpandOption,
|
|
55
|
+
expandedRowKeys,
|
|
56
|
+
expandAll,
|
|
57
|
+
expandRows,
|
|
58
|
+
collapseAll
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
export { useTableExpand };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import TableHeader_default from "../components/TableHeader.vue.mjs";
|
|
2
|
+
import { getSlot } from "../utils/tsxHelper.mjs";
|
|
3
|
+
import { computed, h } from "vue";
|
|
4
|
+
//#region src/components/v-ben-table/src/hooks/useTableHeader.ts
|
|
5
|
+
function useTableHeader(slots) {
|
|
6
|
+
return { getHeaderProps: computed(() => {
|
|
7
|
+
return { title: !slots.headerTop ? null : () => h(TableHeader_default, {}, { ...slots.headerTop ? { headerTop: () => getSlot(slots, "headerTop") } : {} }) };
|
|
8
|
+
}) };
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { useTableHeader };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { BasicColumn, BasicTableProps, RowDragEndPayload } from '../types/table';
|
|
2
|
+
import { ComputedRef, Ref, Slots } from 'vue';
|
|
3
|
+
export declare function useTableRowDrag(wrapRef: Ref<HTMLElement | null>, getProps: ComputedRef<BasicTableProps>, getBindValues: ComputedRef<IObject>, getViewColumns: ComputedRef<BasicColumn[]>, expandedRowKeys: Ref<string[]>, slots: Slots, emit: (event: 'row-drag-end', payload: RowDragEndPayload) => void): {
|
|
4
|
+
showDragIcon: (slotName: string, data: IObject) => boolean;
|
|
5
|
+
initRowDrag: () => void;
|
|
6
|
+
destroyRowDrag: () => void;
|
|
7
|
+
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { unref } from "vue";
|
|
2
|
+
import { cloneDeep } from "lodash-es";
|
|
3
|
+
import SortableJs from "sortablejs";
|
|
4
|
+
//#region src/components/v-ben-table/src/hooks/useTableRowDrag.ts
|
|
5
|
+
function useTableRowDrag(wrapRef, getProps, getBindValues, getViewColumns, expandedRowKeys, slots, emit) {
|
|
6
|
+
let sortableEl = null;
|
|
7
|
+
function getTargetIndex(list, id, arr = []) {
|
|
8
|
+
return list.reduce((total, item, index) => {
|
|
9
|
+
if (String(item.id) === id) return [...total, index];
|
|
10
|
+
const children = item.children;
|
|
11
|
+
if (children?.length) {
|
|
12
|
+
let childArr = getTargetIndex(children, id, [...arr, index]);
|
|
13
|
+
if (childArr.length === [...arr, index].length) childArr = total;
|
|
14
|
+
return childArr;
|
|
15
|
+
}
|
|
16
|
+
return total;
|
|
17
|
+
}, arr);
|
|
18
|
+
}
|
|
19
|
+
function getRecordKey(record) {
|
|
20
|
+
const { rowKey } = unref(getProps);
|
|
21
|
+
if (typeof rowKey === "function") return rowKey(record);
|
|
22
|
+
if (rowKey) return record[rowKey];
|
|
23
|
+
return record.id ?? record.key;
|
|
24
|
+
}
|
|
25
|
+
function showDragIcon(slotName, data) {
|
|
26
|
+
const { rowDraggable } = unref(getProps);
|
|
27
|
+
if (!rowDraggable) return false;
|
|
28
|
+
const slotKeys = Object.keys(slots);
|
|
29
|
+
const firstDataIndex = unref(getViewColumns)?.[0]?.dataIndex;
|
|
30
|
+
return slotKeys.includes("expandIcon") && slotName === "expandIcon" || !slotKeys.includes("expandIcon") && slotName === "bodyCell" && data.column?.dataIndex === firstDataIndex;
|
|
31
|
+
}
|
|
32
|
+
function destroyRowDrag() {
|
|
33
|
+
sortableEl?.destroy();
|
|
34
|
+
sortableEl = null;
|
|
35
|
+
}
|
|
36
|
+
function initRowDrag() {
|
|
37
|
+
if (!unref(getProps).rowDraggable) return;
|
|
38
|
+
destroyRowDrag();
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
const tbody = unref(wrapRef)?.querySelector("tbody.ant-table-tbody");
|
|
41
|
+
if (!tbody) return;
|
|
42
|
+
let savedExpandKeysList = [];
|
|
43
|
+
let targetRowKey;
|
|
44
|
+
let relatedRowKey;
|
|
45
|
+
let dragIndexArr = [];
|
|
46
|
+
let isInsertAfter = false;
|
|
47
|
+
let parentMenu;
|
|
48
|
+
sortableEl = SortableJs.create(tbody, {
|
|
49
|
+
group: "basic-table-rows",
|
|
50
|
+
animation: 150,
|
|
51
|
+
handle: ".gct-handle",
|
|
52
|
+
dataIdAttr: "data-row-key",
|
|
53
|
+
filter: ".unsortable",
|
|
54
|
+
onStart({ item }) {
|
|
55
|
+
targetRowKey = item?.dataset?.rowKey;
|
|
56
|
+
if (!unref(getProps).isTreeTable || !targetRowKey) return;
|
|
57
|
+
dragIndexArr = [];
|
|
58
|
+
savedExpandKeysList = cloneDeep(unref(expandedRowKeys));
|
|
59
|
+
dragIndexArr = getTargetIndex(unref(getBindValues).dataSource, targetRowKey.toString());
|
|
60
|
+
if (dragIndexArr.length > 1) {
|
|
61
|
+
const dataSource = unref(getBindValues).dataSource;
|
|
62
|
+
const parentChildren = dataSource[dragIndexArr[0]]?.children;
|
|
63
|
+
parentMenu = dragIndexArr.length === 2 ? dataSource[dragIndexArr[0]] : parentChildren?.[dragIndexArr[1]];
|
|
64
|
+
const siblingChildren = parentMenu?.children;
|
|
65
|
+
expandedRowKeys.value = unref(expandedRowKeys).filter((key) => {
|
|
66
|
+
return !siblingChildren?.map((n) => n.id).includes(key);
|
|
67
|
+
});
|
|
68
|
+
} else {
|
|
69
|
+
parentMenu = void 0;
|
|
70
|
+
expandedRowKeys.value = [];
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
onMove(evt) {
|
|
74
|
+
const { related, willInsertAfter } = evt;
|
|
75
|
+
if (unref(getProps).isTreeTable) {
|
|
76
|
+
if (!related?.dataset?.rowKey) return false;
|
|
77
|
+
const relatedIndexArr = getTargetIndex(unref(getBindValues).dataSource, related.dataset.rowKey.toString());
|
|
78
|
+
const canMove = relatedIndexArr.length === dragIndexArr.length && relatedIndexArr.slice(0, -1).every((item, index) => item === dragIndexArr[index]);
|
|
79
|
+
if (canMove) {
|
|
80
|
+
relatedRowKey = related.dataset.rowKey;
|
|
81
|
+
isInsertAfter = !!willInsertAfter;
|
|
82
|
+
}
|
|
83
|
+
return canMove;
|
|
84
|
+
}
|
|
85
|
+
if ((related?.children?.[0]?.outerHTML ?? "").indexOf("unsortable") > -1) return false;
|
|
86
|
+
if (related?.dataset?.rowKey) {
|
|
87
|
+
relatedRowKey = related.dataset.rowKey;
|
|
88
|
+
isInsertAfter = !!willInsertAfter;
|
|
89
|
+
}
|
|
90
|
+
return true;
|
|
91
|
+
},
|
|
92
|
+
onEnd: async () => {
|
|
93
|
+
const isTreeTable = unref(getProps).isTreeTable;
|
|
94
|
+
const dataSource = unref(getBindValues).dataSource;
|
|
95
|
+
let relatedItem;
|
|
96
|
+
let targetItem;
|
|
97
|
+
if (isTreeTable) {
|
|
98
|
+
expandedRowKeys.value = savedExpandKeysList;
|
|
99
|
+
if (parentMenu?.children) parentMenu.children.forEach((item) => {
|
|
100
|
+
if (String(item.id) === relatedRowKey) relatedItem = item;
|
|
101
|
+
if (String(item.id) === targetRowKey) targetItem = item;
|
|
102
|
+
});
|
|
103
|
+
else dataSource.forEach((item) => {
|
|
104
|
+
if (String(item.id) === relatedRowKey) relatedItem = item;
|
|
105
|
+
if (String(item.id) === targetRowKey) targetItem = item;
|
|
106
|
+
});
|
|
107
|
+
} else dataSource.forEach((item) => {
|
|
108
|
+
const id = getRecordKey(item);
|
|
109
|
+
if (String(id) === relatedRowKey) relatedItem = item;
|
|
110
|
+
if (String(id) === targetRowKey) targetItem = item;
|
|
111
|
+
});
|
|
112
|
+
if (!relatedItem || !targetItem) return;
|
|
113
|
+
const ids = dataSource.map((item) => item.id);
|
|
114
|
+
const tempList = sortableEl?.toArray()?.filter((i) => ids.includes(i));
|
|
115
|
+
const reqParams = isTreeTable ? {
|
|
116
|
+
id: targetItem.id,
|
|
117
|
+
parentId: parentMenu?.id || "ROOT",
|
|
118
|
+
sortNum: isInsertAfter ? relatedItem.sortNum : relatedItem.sortNum + 1
|
|
119
|
+
} : {
|
|
120
|
+
id: getRecordKey(targetItem),
|
|
121
|
+
targetSortNum: isInsertAfter ? relatedItem.sortNum : relatedItem.sortNum + 1,
|
|
122
|
+
sortList: tempList
|
|
123
|
+
};
|
|
124
|
+
const { rowDragApi } = unref(getProps);
|
|
125
|
+
if (rowDragApi && typeof rowDragApi === "function") await rowDragApi(reqParams);
|
|
126
|
+
const dragEndList = [];
|
|
127
|
+
sortableEl?.toArray()?.forEach((key) => {
|
|
128
|
+
const dataItem = dataSource.find((item) => String(getRecordKey(item)) === String(key));
|
|
129
|
+
if (dataItem) dragEndList.push(dataItem);
|
|
130
|
+
});
|
|
131
|
+
emit("row-drag-end", {
|
|
132
|
+
dragEndList,
|
|
133
|
+
expandKeysList: unref(expandedRowKeys),
|
|
134
|
+
dragItemKey: targetRowKey,
|
|
135
|
+
showMessage: true
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}, 0);
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
showDragIcon,
|
|
143
|
+
initRowDrag,
|
|
144
|
+
destroyRowDrag
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
//#endregion
|
|
148
|
+
export { useTableRowDrag };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { PaginationProps } from '../types/pagination';
|
|
2
|
+
import { BasicColumn, BasicTableProps, TableRowSelection } from '../types/table';
|
|
3
|
+
import { ComputedRef, Ref } from 'vue';
|
|
4
|
+
type TableComponentRef = {
|
|
5
|
+
$el: HTMLElement;
|
|
6
|
+
} | null;
|
|
7
|
+
type FormComponentRef = {
|
|
8
|
+
$el: HTMLElement;
|
|
9
|
+
} | null;
|
|
10
|
+
export declare function useTableScroll(propsRef: ComputedRef<BasicTableProps>, tableElRef: Ref<TableComponentRef>, columnsRef: ComputedRef<BasicColumn[]>, rowSelectionRef: ComputedRef<TableRowSelection | null>, getPaginationRef: ComputedRef<PaginationProps | boolean>, getDataSourceRef: ComputedRef<Recordable[]>, wrapRef: Ref<HTMLElement | null>, formRef: Ref<FormComponentRef>): {
|
|
11
|
+
getScrollRef: ComputedRef<{
|
|
12
|
+
x?: number | string | true;
|
|
13
|
+
y?: number | string;
|
|
14
|
+
} | undefined>;
|
|
15
|
+
redoHeight: () => void;
|
|
16
|
+
};
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { isBoolean } from "../../../../utils/is.mjs";
|
|
2
|
+
import { getViewportOffset } from "../utils/dom-utils.mjs";
|
|
3
|
+
import { computed, nextTick, onActivated, onMounted, ref, unref, watch } from "vue";
|
|
4
|
+
import { useDebounceFn, useEventListener } from "@vueuse/core";
|
|
5
|
+
//#region src/components/v-ben-table/src/hooks/useTableScroll.ts
|
|
6
|
+
function useTableScroll(propsRef, tableElRef, columnsRef, rowSelectionRef, getPaginationRef, getDataSourceRef, wrapRef, formRef) {
|
|
7
|
+
const tableHeightRef = ref(215);
|
|
8
|
+
const debounceRedoHeight = useDebounceFn(redoHeight, 100);
|
|
9
|
+
const getCanResize = computed(() => {
|
|
10
|
+
const { canResize, scroll } = unref(propsRef);
|
|
11
|
+
return canResize && !(scroll || {}).y;
|
|
12
|
+
});
|
|
13
|
+
watch(() => [unref(getCanResize), unref(getDataSourceRef)?.length], () => {
|
|
14
|
+
debounceRedoHeight();
|
|
15
|
+
}, { flush: "post" });
|
|
16
|
+
function redoHeight() {
|
|
17
|
+
nextTick(() => {
|
|
18
|
+
calcTableHeight();
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function setHeight(height) {
|
|
22
|
+
tableHeightRef.value = height;
|
|
23
|
+
}
|
|
24
|
+
let paginationEl = null;
|
|
25
|
+
let footerEl = null;
|
|
26
|
+
let bodyEl = null;
|
|
27
|
+
async function calcTableHeight() {
|
|
28
|
+
const { resizeHeightOffset, maxHeight, isCanResizeParent, useSearchForm } = unref(propsRef);
|
|
29
|
+
const pagination = unref(getPaginationRef);
|
|
30
|
+
const tableData = unref(getDataSourceRef);
|
|
31
|
+
const table = unref(tableElRef);
|
|
32
|
+
if (!table) return;
|
|
33
|
+
const tableEl = table.$el;
|
|
34
|
+
if (!tableEl) return;
|
|
35
|
+
if (!bodyEl) {
|
|
36
|
+
bodyEl = tableEl.querySelector(".ant-table-body");
|
|
37
|
+
if (!bodyEl) return;
|
|
38
|
+
}
|
|
39
|
+
const hasScrollBarY = bodyEl.scrollHeight > bodyEl.clientHeight;
|
|
40
|
+
const hasScrollBarX = bodyEl.scrollWidth > bodyEl.clientWidth;
|
|
41
|
+
if (hasScrollBarY) {
|
|
42
|
+
if (tableEl.classList.contains("hide-scrollbar-y")) tableEl.classList.remove("hide-scrollbar-y");
|
|
43
|
+
} else if (!tableEl.classList.contains("hide-scrollbar-y")) tableEl.classList.add("hide-scrollbar-y");
|
|
44
|
+
if (hasScrollBarX) {
|
|
45
|
+
if (tableEl.classList.contains("hide-scrollbar-x")) tableEl.classList.remove("hide-scrollbar-x");
|
|
46
|
+
} else if (!tableEl.classList.contains("hide-scrollbar-x")) tableEl.classList.add("hide-scrollbar-x");
|
|
47
|
+
bodyEl.style.height = "unset";
|
|
48
|
+
if (!unref(getCanResize) || !unref(tableData) || tableData.length === 0) return;
|
|
49
|
+
await nextTick();
|
|
50
|
+
const headEl = tableEl.querySelector(".ant-table-thead ");
|
|
51
|
+
if (!headEl) return;
|
|
52
|
+
let paddingHeight = 32;
|
|
53
|
+
let paginationHeight = 12;
|
|
54
|
+
if (!isBoolean(pagination)) {
|
|
55
|
+
paginationEl = tableEl.querySelector(".ant-pagination");
|
|
56
|
+
if (paginationEl) {
|
|
57
|
+
const offsetHeight = paginationEl.offsetHeight;
|
|
58
|
+
paginationHeight += offsetHeight || 0;
|
|
59
|
+
} else paginationHeight += 24;
|
|
60
|
+
} else paginationHeight = -8;
|
|
61
|
+
let footerHeight = 0;
|
|
62
|
+
if (!isBoolean(pagination)) if (!footerEl) footerEl = tableEl.querySelector(".ant-table-footer");
|
|
63
|
+
else {
|
|
64
|
+
const offsetHeight = footerEl.offsetHeight;
|
|
65
|
+
footerHeight += offsetHeight || 0;
|
|
66
|
+
}
|
|
67
|
+
let headerHeight = 0;
|
|
68
|
+
if (headEl) headerHeight = headEl.offsetHeight;
|
|
69
|
+
let bottomIncludeBody = 0;
|
|
70
|
+
if (unref(wrapRef) && isCanResizeParent) {
|
|
71
|
+
const tablePadding = 12;
|
|
72
|
+
const formMargin = 16;
|
|
73
|
+
let paginationMargin = 10;
|
|
74
|
+
const wrapHeight = unref(wrapRef)?.offsetHeight ?? 0;
|
|
75
|
+
let formHeight = unref(formRef)?.$el.offsetHeight ?? 0;
|
|
76
|
+
if (formHeight) formHeight += formMargin;
|
|
77
|
+
if (isBoolean(pagination) && !pagination) paginationMargin = 0;
|
|
78
|
+
if (isBoolean(useSearchForm) && !useSearchForm) paddingHeight = 0;
|
|
79
|
+
const headerCellHeight = tableEl.querySelector(".ant-table-title")?.offsetHeight ?? 0;
|
|
80
|
+
bottomIncludeBody = wrapHeight - formHeight - headerCellHeight - tablePadding - paginationMargin;
|
|
81
|
+
} else bottomIncludeBody = getViewportOffset(headEl).bottomIncludeBody;
|
|
82
|
+
let height = bottomIncludeBody - (resizeHeightOffset || 0) - paddingHeight - paginationHeight - footerHeight - headerHeight;
|
|
83
|
+
height = (height > maxHeight ? maxHeight : height) ?? height;
|
|
84
|
+
setHeight(height);
|
|
85
|
+
if (pagination && !isBoolean(pagination)) {
|
|
86
|
+
const body = tableEl.querySelector(".ant-table-body");
|
|
87
|
+
if (body) body.style.height = `${height}px`;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
useEventListener(window, "resize", useDebounceFn(calcTableHeight, 280));
|
|
91
|
+
function mountCalcHeight() {
|
|
92
|
+
calcTableHeight();
|
|
93
|
+
nextTick(() => {
|
|
94
|
+
debounceRedoHeight();
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
onMounted(mountCalcHeight);
|
|
98
|
+
onActivated(mountCalcHeight);
|
|
99
|
+
const getScrollX = computed(() => {
|
|
100
|
+
let width = 0;
|
|
101
|
+
if (unref(rowSelectionRef)) width += 60;
|
|
102
|
+
const NORMAL_WIDTH = 150;
|
|
103
|
+
const columns = unref(columnsRef).filter((item) => !item.defaultHidden);
|
|
104
|
+
columns.forEach((item) => {
|
|
105
|
+
width += Number.parseFloat(String(item.width)) || 0;
|
|
106
|
+
});
|
|
107
|
+
const len = columns.filter((item) => !Reflect.has(item, "width")).length;
|
|
108
|
+
if (len !== 0) width += len * NORMAL_WIDTH;
|
|
109
|
+
return (unref(tableElRef)?.$el?.offsetWidth ?? 0) > width ? void 0 : width;
|
|
110
|
+
});
|
|
111
|
+
return {
|
|
112
|
+
getScrollRef: computed(() => {
|
|
113
|
+
const tableHeight = unref(tableHeightRef);
|
|
114
|
+
const { canResize, scroll } = unref(propsRef);
|
|
115
|
+
return {
|
|
116
|
+
x: unref(getScrollX),
|
|
117
|
+
y: canResize ? tableHeight : null,
|
|
118
|
+
scrollToFirstRowOnChange: false,
|
|
119
|
+
...scroll
|
|
120
|
+
};
|
|
121
|
+
}),
|
|
122
|
+
redoHeight
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
//#endregion
|
|
126
|
+
export { useTableScroll };
|
|
@@ -38,6 +38,11 @@ export declare const basicProps: {
|
|
|
38
38
|
type: BooleanConstructor;
|
|
39
39
|
default: boolean;
|
|
40
40
|
};
|
|
41
|
+
/** 是否开启列宽拖拽(ant-design-vue resizable) */
|
|
42
|
+
resizable: {
|
|
43
|
+
type: BooleanConstructor;
|
|
44
|
+
default: boolean;
|
|
45
|
+
};
|
|
41
46
|
api: {
|
|
42
47
|
type: PropType<(...arg: unknown[]) => Promise<unknown>>;
|
|
43
48
|
default: null;
|
|
@@ -166,7 +171,7 @@ export declare const basicProps: {
|
|
|
166
171
|
* 拖拽完成自动请求的api
|
|
167
172
|
*/
|
|
168
173
|
rowDragApi: {
|
|
169
|
-
type:
|
|
174
|
+
type: PropType<Fn>;
|
|
170
175
|
default: null;
|
|
171
176
|
};
|
|
172
177
|
/**
|
|
@@ -184,3 +189,5 @@ export declare const basicProps: {
|
|
|
184
189
|
default: boolean;
|
|
185
190
|
};
|
|
186
191
|
};
|
|
192
|
+
/** BasicTable 自有配置,不传给 ant-design-vue Table */
|
|
193
|
+
export declare const basicTableInternalPropKeys: readonly ["clickToRowSelect", "isTreeTable", "tableSetting", "inset", "showTableSetting", "autoCreateKey", "striped", "showSummary", "summaryFunc", "summaryData", "indentSize", "canColDrag", "resizable", "api", "beforeFetch", "afterFetch", "handleSearchInfoFn", "immediate", "emptyDataIsShowTable", "searchInfo", "defSort", "useSearchForm", "showIndexColumn", "indexColumnProps", "actionColumn", "ellipsis", "isCanResizeParent", "canResize", "clearSelectOnPageChange", "resizeHeightOffset", "titleHelpMessage", "beforeEditSubmit", "rowDraggable", "supportSameLevel", "rowDragApi", "emptyFull", "expandedRowKeys"];
|
|
@@ -36,6 +36,11 @@ var basicProps = {
|
|
|
36
36
|
type: Boolean,
|
|
37
37
|
default: true
|
|
38
38
|
},
|
|
39
|
+
/** 是否开启列宽拖拽(ant-design-vue resizable) */
|
|
40
|
+
resizable: {
|
|
41
|
+
type: Boolean,
|
|
42
|
+
default: true
|
|
43
|
+
},
|
|
39
44
|
api: {
|
|
40
45
|
type: Function,
|
|
41
46
|
default: null
|
|
@@ -168,5 +173,45 @@ var basicProps = {
|
|
|
168
173
|
default: false
|
|
169
174
|
}
|
|
170
175
|
};
|
|
176
|
+
/** BasicTable 自有配置,不传给 ant-design-vue Table */
|
|
177
|
+
var basicTableInternalPropKeys = [
|
|
178
|
+
"clickToRowSelect",
|
|
179
|
+
"isTreeTable",
|
|
180
|
+
"tableSetting",
|
|
181
|
+
"inset",
|
|
182
|
+
"showTableSetting",
|
|
183
|
+
"autoCreateKey",
|
|
184
|
+
"striped",
|
|
185
|
+
"showSummary",
|
|
186
|
+
"summaryFunc",
|
|
187
|
+
"summaryData",
|
|
188
|
+
"indentSize",
|
|
189
|
+
"canColDrag",
|
|
190
|
+
"resizable",
|
|
191
|
+
"api",
|
|
192
|
+
"beforeFetch",
|
|
193
|
+
"afterFetch",
|
|
194
|
+
"handleSearchInfoFn",
|
|
195
|
+
"immediate",
|
|
196
|
+
"emptyDataIsShowTable",
|
|
197
|
+
"searchInfo",
|
|
198
|
+
"defSort",
|
|
199
|
+
"useSearchForm",
|
|
200
|
+
"showIndexColumn",
|
|
201
|
+
"indexColumnProps",
|
|
202
|
+
"actionColumn",
|
|
203
|
+
"ellipsis",
|
|
204
|
+
"isCanResizeParent",
|
|
205
|
+
"canResize",
|
|
206
|
+
"clearSelectOnPageChange",
|
|
207
|
+
"resizeHeightOffset",
|
|
208
|
+
"titleHelpMessage",
|
|
209
|
+
"beforeEditSubmit",
|
|
210
|
+
"rowDraggable",
|
|
211
|
+
"supportSameLevel",
|
|
212
|
+
"rowDragApi",
|
|
213
|
+
"emptyFull",
|
|
214
|
+
"expandedRowKeys"
|
|
215
|
+
];
|
|
171
216
|
//#endregion
|
|
172
|
-
export { basicProps };
|
|
217
|
+
export { basicProps, basicTableInternalPropKeys };
|
|
@@ -66,7 +66,7 @@ export interface PaginationProps {
|
|
|
66
66
|
* to display the total number and range
|
|
67
67
|
* @type Function
|
|
68
68
|
*/
|
|
69
|
-
showTotal?: (total: number, range
|
|
69
|
+
showTotal?: (total: number, range?: [number, number]) => string;
|
|
70
70
|
/**
|
|
71
71
|
* specify the size of Pagination, can be set to small
|
|
72
72
|
* @default ''
|
|
@@ -40,6 +40,12 @@ export interface TableCustomRecord<T = Recordable> {
|
|
|
40
40
|
record?: T;
|
|
41
41
|
index?: number;
|
|
42
42
|
}
|
|
43
|
+
export interface RowDragEndPayload {
|
|
44
|
+
dragEndList: Recordable[];
|
|
45
|
+
expandKeysList: string[];
|
|
46
|
+
dragItemKey?: string;
|
|
47
|
+
showMessage?: boolean;
|
|
48
|
+
}
|
|
43
49
|
export interface SorterResult {
|
|
44
50
|
column: ColumnProps;
|
|
45
51
|
order: SortOrder;
|
|
@@ -120,6 +126,7 @@ export interface BasicTableProps<T = unknown> {
|
|
|
120
126
|
summaryData?: Recordable[];
|
|
121
127
|
showSummary?: boolean;
|
|
122
128
|
canColDrag?: boolean;
|
|
129
|
+
resizable?: boolean;
|
|
123
130
|
api?: (...arg: unknown[]) => Promise<IObject>;
|
|
124
131
|
beforeFetch?: Fn;
|
|
125
132
|
afterFetch?: Fn;
|
|
@@ -291,6 +298,12 @@ export interface BasicTableProps<T = unknown> {
|
|
|
291
298
|
key: string | number;
|
|
292
299
|
value: unknown;
|
|
293
300
|
}) => Promise<IObject>;
|
|
301
|
+
/** 行拖拽 */
|
|
302
|
+
rowDraggable?: boolean;
|
|
303
|
+
/** 仅支持同层级拖拽 */
|
|
304
|
+
supportSameLevel?: boolean;
|
|
305
|
+
/** 拖拽完成自动请求的 api */
|
|
306
|
+
rowDragApi?: Fn | null;
|
|
294
307
|
/**
|
|
295
308
|
* Callback executed when pagination, filters or sorter is changed
|
|
296
309
|
* @param pagination
|
|
@@ -317,6 +330,9 @@ export type CellFormat = string | ((text: string, record: Recordable, index: num
|
|
|
317
330
|
export interface BasicColumn extends ColumnProps<Recordable> {
|
|
318
331
|
children?: BasicColumn[];
|
|
319
332
|
filters?: ColumnFilterItem[];
|
|
333
|
+
resizable?: boolean;
|
|
334
|
+
minWidth?: number;
|
|
335
|
+
maxWidth?: number;
|
|
320
336
|
flag?: 'INDEX' | 'DEFAULT' | 'CHECKBOX' | 'RADIO' | 'ACTION';
|
|
321
337
|
customTitle?: VueNode;
|
|
322
338
|
slots?: Recordable;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface IViewportOffsetResult {
|
|
2
|
+
left: number;
|
|
3
|
+
top: number;
|
|
4
|
+
right: number;
|
|
5
|
+
bottom: number;
|
|
6
|
+
rightIncludeBody: number;
|
|
7
|
+
bottomIncludeBody: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function getBoundingClientRect(element: Element): DOMRect | number;
|
|
10
|
+
/**
|
|
11
|
+
* 获取元素相对视口的偏移,用于计算表格可用高度
|
|
12
|
+
*/
|
|
13
|
+
export declare function getViewportOffset(element: Element): IViewportOffsetResult;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region src/components/v-ben-table/src/utils/dom-utils.ts
|
|
2
|
+
function getBoundingClientRect(element) {
|
|
3
|
+
if (!element || !element.getBoundingClientRect) return 0;
|
|
4
|
+
return element.getBoundingClientRect();
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* 获取元素相对视口的偏移,用于计算表格可用高度
|
|
8
|
+
*/
|
|
9
|
+
function getViewportOffset(element) {
|
|
10
|
+
const doc = document.documentElement;
|
|
11
|
+
const docScrollLeft = doc.scrollLeft;
|
|
12
|
+
const docScrollTop = doc.scrollTop;
|
|
13
|
+
const docClientLeft = doc.clientLeft;
|
|
14
|
+
const docClientTop = doc.clientTop;
|
|
15
|
+
const pageXOffset = window.pageXOffset;
|
|
16
|
+
const pageYOffset = window.pageYOffset;
|
|
17
|
+
const { left: retLeft, top: rectTop, width: rectWidth, height: rectHeight } = getBoundingClientRect(element);
|
|
18
|
+
const scrollLeft = (pageXOffset || docScrollLeft) - (docClientLeft || 0);
|
|
19
|
+
const scrollTop = (pageYOffset || docScrollTop) - (docClientTop || 0);
|
|
20
|
+
const offsetLeft = retLeft + pageXOffset;
|
|
21
|
+
const offsetTop = rectTop + pageYOffset;
|
|
22
|
+
const left = offsetLeft - scrollLeft;
|
|
23
|
+
const top = offsetTop - scrollTop;
|
|
24
|
+
const clientWidth = window.document.documentElement.clientWidth;
|
|
25
|
+
const clientHeight = window.document.documentElement.clientHeight;
|
|
26
|
+
return {
|
|
27
|
+
left,
|
|
28
|
+
top,
|
|
29
|
+
right: clientWidth - rectWidth - left,
|
|
30
|
+
bottom: clientHeight - rectHeight - top,
|
|
31
|
+
rightIncludeBody: clientWidth - left,
|
|
32
|
+
bottomIncludeBody: clientHeight - top
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { getViewportOffset };
|