UNPKG

@arco-vue-pro-components/pro-components

Version:
652 lines (651 loc) 17.6 kB
import { defineComponent, inject, toRefs, toRef, ref, computed, reactive, watch, provide, watchEffect, createVNode, mergeProps } from "vue"; import { Table, Card } from "@arco-design/web-vue"; import { useFilterSorter } from "./hooks/useFilterSorter.js"; import FormSearch from "./form/form-search.js"; import useFetchData from "./form/use-fetch-data.js"; import ToolBar from "./tool-bar/index.js"; import Alert from "./alert/index.js"; import { genProColumnToColumn, loopFilter, flattenChildren, useActionType, mergePagination } from "./utils/index.js"; import { useRowSelection } from "./hooks/useRowSelection.js"; import LightFormSearch from "./form/light-form-search.js"; import { getPrefixCls } from "../_utils/index.js"; import { isArray } from "../_utils/is.js"; import { proTableInjectionKey } from "./form/context.js"; import { usePureProp } from "../_hooks/use-pure-prop.js"; import { configProviderInjectionKey } from "../_utils/context.js"; import useState from "../_hooks/use-state.js"; Table.inheritAttrs = false; var _ProTable = defineComponent({ name: "ProTable", inheritAttrs: false, props: { columns: { type: Array, default: () => [] }, rowKey: { type: String, default: "id" }, params: Object, request: { type: Function }, defaultData: Array, beforeSearchSubmit: { type: Function, default: (searchParams) => searchParams }, search: { type: [Boolean, Object], default: true }, type: { type: String, default: "table" }, toolBarRender: { type: [Boolean, Function], default: void 0 }, optionsRender: { type: [Boolean, Function], default: false }, options: { type: [Object, Boolean], default: false }, headerTitle: { type: [String, Boolean, Object, Function], default: "\u5217\u8868\u6570\u636E" }, defaultFormData: { type: Object }, searchType: { type: String, default: "query" }, lightSearchConfig: { type: Object }, formRef: { type: Function }, actionRef: { type: Function }, columnEmptyText: { type: [String, Boolean], default: "-" }, selected: { type: Array }, defaultSelected: { type: Array }, loading: { type: Boolean, default: void 0 }, data: { type: Array, default: () => [] }, bordered: { type: [Boolean, Object], default: true }, hoverable: { type: Boolean, default: true }, stripe: { type: Boolean, default: false }, tableLayoutFixed: { type: Boolean, default: false }, rowSelection: { type: Object }, expandable: { type: Object }, scroll: { type: Object }, pagination: { type: [Boolean, Object], default: true }, pagePosition: { type: String, default: "br" }, indentSize: { type: Number, default: 16 }, showHeader: { type: Boolean, default: true }, virtualListProps: { type: Object }, spanMethod: { type: Function }, spanAll: { type: Boolean, default: false }, components: { type: Object }, loadMore: { type: Function }, filterIconAlignLeft: { type: Boolean, default: false }, hideExpandButtonOnEmpty: { type: Boolean, default: false }, rowClass: { type: [String, Array, Object, Function] }, draggable: { type: Object }, rowNumber: { type: [Boolean, Object] }, columnResizable: { type: Boolean }, summary: { type: [Boolean, Function] }, summaryText: { type: String, default: "Summary" }, summarySpanMethod: { type: Function }, selectedKeys: { type: Array }, defaultSelectedKeys: { type: Array }, expandedKeys: { type: Array }, defaultExpandedKeys: { type: Array }, defaultExpandAllRows: { type: Boolean, default: false }, stickyHeader: { type: [Boolean, Number], default: false }, scrollbar: { type: [Object, Boolean], default: true }, size: { type: String, default: () => { var _a, _b; return (_b = (_a = inject(configProviderInjectionKey, void 0)) == null ? void 0 : _a.size) != null ? _b : "large"; } }, onChange: { type: Function }, onSubmit: { type: Function }, onReset: { type: Function }, onLoad: { type: Function }, onPageChange: { type: Function }, onPageSizeChange: { type: Function }, onExpand: { type: Function }, onExpandedChange: { type: Function }, onSelect: { type: Function }, onSelectAll: { type: Function }, onSelectionChange: { type: Function }, onSorterChange: { type: Function }, onFilterChange: { type: Function }, onCellClick: { type: Function }, onRowClick: { type: Function }, onHeaderClick: { type: Function }, onColumnResize: { type: Function }, columnsState: { type: Object }, alertRender: { type: [Function, Boolean], default: void 0 } }, setup(props, { attrs, emit, slots }) { const { rowSelection, selectedKeys, selected, defaultSelectedKeys, defaultSelected, pagination: propsPagination } = toRefs(props); const tableSize = usePureProp(props, "size"); const columnsState = toRef(props, "columnsState"); const columnsMap = ref({}); const setColumnsMap = (data) => { columnsMap.value = data; }; initStorageColumnsMap(); const setTableSize = (size) => { tableSize.value = size; }; const prefixCls = getPrefixCls("pro-table"); const tableRef = ref(); const formRef = ref(); const setFormRef = (ref2) => { formRef.value = ref2; if (typeof props.formRef === "function") { props.formRef(ref2); } }; const { selectedRowKeys, selectedRows } = useRowSelection({ selectedKeys, defaultSelectedKeys, selected, defaultSelected, rowSelection }); const actionRef = ref(); const formSearch = ref({}); const renderIndex = (data) => { if (slots.index) { return slots.index(data); } let text; let hasPage = false; if (pagination.value && pagination.value.current && pagination.value.pageSize) { hasPage = true; text = data.rowIndex + 1 + (pagination.value.current - 1) * pagination.value.pageSize; } else { text = data.rowIndex + 1; } if (data.column.valueType === "indexBorder") { return createVNode("div", { "class": [`${prefixCls}-column-indexBorder`, { [`${prefixCls}-column-indexBorder--top-three`]: hasPage ? pagination.value && pagination.value.current === 1 && data.rowIndex < 3 : data.rowIndex < 3 }] }, [text]); } return text; }; const [fullscreen, setFullscreen] = useState(false); const rootRef = ref(); const popupContainer = ref(); const setPopupContainer = (container) => { popupContainer.value = container; }; const tableColumns = computed(() => { return genProColumnToColumn({ columns: props.columns, type: props.type, columnEmptyText: props.columnEmptyText, action: actionRef, slots: { ...slots, index: renderIndex } }); }); const { _filters, _sorter, _sorters } = useFilterSorter({ columns: tableColumns }); const columns = computed(() => { if (Object.keys(columnsMap.value).length === 0) { return tableColumns.value; } return loopFilter(tableColumns.value, void 0, columnsMap); }); const fetchData = computed(() => { if (!props.request) { return void 0; } return async (pageParams) => { var _a; const actionParams = { ...pageParams || {}, ...formSearch.value, ...props.params }; delete actionParams._timestamp; const response = await ((_a = props.request) == null ? void 0 : _a.call(props, actionParams, _sorters.value, _filters.value)); return response; }; }); const fetchPagination = computed(() => typeof propsPagination.value === "object" ? propsPagination.value : { defaultCurrent: 1, defaultPageSize: 20, pageSize: 20, current: 1 }); const options = reactive({ pageInfo: fetchPagination.value, effects: [props.params, formSearch, _sorter, _filters], getPopupContainer: () => popupContainer.value }); const action = useFetchData(fetchData.value, props, emit, options); const dataSource = computed(() => { return props.request ? action.data.value : props.data || []; }); const noRowSelection = computed(() => !rowSelection.value); const dataSourceMap = computed(() => { return noRowSelection.value ? {} : flattenChildren(dataSource.value, props.rowKey); }); const selectedRowsMap = computed(() => { return noRowSelection.value ? {} : flattenChildren(selectedRows.value, props.rowKey); }); function initStorageColumnsMap() { const { persistenceType, persistenceKey } = columnsState.value || {}; if (persistenceKey && persistenceType && typeof window !== "undefined") { const storage = window[persistenceType]; try { const storageValue = storage == null ? void 0 : storage.getItem(persistenceKey); if (storageValue) { setColumnsMap(JSON.parse(storageValue)); } else { setColumnsMap({}); } } catch (error) { console.warn(error); } } } watch([columnsState], () => { initStorageColumnsMap(); }); watch([columnsState, columnsMap], ([columnsState2, columnsMap2]) => { if (!(columnsState2 == null ? void 0 : columnsState2.persistenceKey) || !(columnsState2 == null ? void 0 : columnsState2.persistenceType)) { return; } if (typeof window === "undefined") return; const { persistenceType, persistenceKey } = columnsState2; const storage = window[persistenceType]; try { storage == null ? void 0 : storage.setItem(persistenceKey, JSON.stringify(columnsMap2)); } catch (error) { console.warn(error); storage == null ? void 0 : storage.removeItem(persistenceKey); } }, { deep: true }); watch([selectedRowKeys, dataSourceMap, noRowSelection, action.loading], ([selectedRowKeys2, dataSourceMap2, noRowSelection2, loading]) => { if (loading || noRowSelection2) { return; } if (isArray(selectedRowKeys2) && selectedRowKeys2.length) { const rows = selectedRowKeys2.map((item) => { return dataSourceMap2[item] || selectedRowsMap.value[item]; }); selectedRows.value = rows; return; } else { selectedRows.value = []; } }, { immediate: true }); const onCleanSelected = () => { selectedRowKeys.value = []; selectedRows.value = []; emit("update:selectedKeys", []); }; const getSelected = () => { return { selectedKeys: selectedRowKeys.value, selectedRows: selectedRows.value }; }; useActionType(actionRef, action, { fullScreen: () => { if (!rootRef.value || !document.fullscreenEnabled) { return; } if (document.fullscreenElement) { document.exitFullscreen(); setFullscreen(false); setPopupContainer(null); } else { rootRef.value.requestFullscreen(); setFullscreen(true); setPopupContainer(rootRef.value); } }, getSelected, onCleanSelected: () => { onCleanSelected(); }, resetAll: () => { var _a; onCleanSelected(); action.setPageInfo({ current: 1 }); _filters.value = {}; _sorters.value = {}; _sorter.value = void 0; (_a = formRef == null ? void 0 : formRef.value) == null ? void 0 : _a.reset(); formSearch.value = {}; } }); provide(proTableInjectionKey, reactive({ tableSize, setTableSize, columns: tableColumns, action: actionRef, selectedRowKeys, selectedRows, fullscreen, popupContainer, setPopupContainer, columnsMap, setColumnsMap })); watchEffect(() => { if (typeof props.actionRef === "function" && actionRef.value) { props.actionRef(actionRef.value); } }); const pagination = computed(() => { return props.pagination !== false && mergePagination(props.pagination, action.pageInfo, action.setPageInfo, emit); }); const handleChange = (data, extra, currentData) => { var _a, _b, _c; _sorter.value = extra.sorter; if ((_a = extra.sorter) == null ? void 0 : _a.field) { _sorters.value = { [(_b = extra.sorter) == null ? void 0 : _b.field]: (_c = extra.sorter) == null ? void 0 : _c.direction }; } else { _sorters.value = {}; } _filters.value = extra.filters || {}; emit("change", data, extra, currentData); }; const onSubmit = (formData2, firstLoad = false) => { var _a; formSearch.value = props.beforeSearchSubmit({ ...formData2, _timestamp: Date.now() }); if (!firstLoad) { (_a = action.setPageInfo) == null ? void 0 : _a.call(action, { current: 1 }); } emit("submit", formData2); }; const onReset = (formData2 = {}) => { var _a; formSearch.value = props.beforeSearchSubmit({ ...formData2, _timestamp: Date.now() }); (_a = action.setPageInfo) == null ? void 0 : _a.call(action, { current: 1 }); emit("reset"); }; const formData = { onSubmit: (values) => { onSubmit({ ...formSearch.value, ...values }); }, onReset }; const render = () => { return createVNode("div", { "ref": rootRef, "class": `${prefixCls}` }, [createVNode(Card, { "bordered": false }, { default: () => { var _a, _b; return [(_a = slots["form-search"]) == null ? void 0 : _a.call(slots, formData), !slots["form-search"] && props.search && props.searchType === "light" && createVNode(LightFormSearch, { "columns": props.columns, "onSubmit": (values, firstLoad = false) => { onSubmit({ ...formSearch.value, ...values }, firstLoad); }, "onReset": onReset, "onSearch": (value) => { formSearch.value = { ...formSearch.value, ...value }; }, "type": props.type, "formSearch": formSearch.value, "formRef": setFormRef, "search": props.lightSearchConfig, "defaultFormData": props.defaultFormData }, slots), !slots["form-search"] && (props.search && props.searchType === "query" || props.type === "form") && createVNode(FormSearch, { "columns": props.columns, "onSubmit": onSubmit, "onReset": onReset, "type": props.type, "search": props.search, "formRef": setFormRef, "submitButtonLoading": props.loading || action.loading.value, "defaultFormData": props.defaultFormData }, slots), props.type !== "form" && createVNode("div", null, [props.toolBarRender !== false && (props.headerTitle || props.toolBarRender) && createVNode(ToolBar, { "headerTitle": props.headerTitle, "toolBarRender": props.toolBarRender, "optionsRender": props.optionsRender, "options": props.options }, slots), !noRowSelection.value ? createVNode(Alert, { "alertRender": props.alertRender, "alwaysShowAlert": (_b = rowSelection.value) == null ? void 0 : _b.alwaysShowAlert }, slots) : null, createVNode(Table, mergeProps({ "ref": tableRef }, props, attrs, { "size": tableSize.value, "columns": columns.value, "loading": props.loading || action.loading.value, "data": dataSource.value, "onChange": handleChange, "pagination": pagination.value, "selectedKeys": selectedRowKeys.value, "onUpdate:selectedKeys": ($event) => selectedRowKeys.value = $event }), { ...slots, index: renderIndex })])]; } })]); }; return { render, selectedRowKeys, selectedRows, getSelected }; }, render() { return this.render(); } }); export { _ProTable as default };