UNPKG

react-antd-admin-panel

Version:

Easy prototyping admin panel using React and Antd

321 lines 14.9 kB
import React, { useEffect, useState } from "react"; import { ConfigProvider, Table } from "antd"; import { CloseCircleOutlined } from "@ant-design/icons/lib"; import handleSearchProps from "./extensions/ListSearch"; import handleActionProps from "./extensions/ListActions"; import ListEdit from "./extensions/ListEdit"; import Section from "../Section"; import { Helpers } from "../../typescript"; import handleMenuProps from "./extensions/ListMenu"; import handleDefaultProps from "./extensions/ListDefault"; const List = (props) => { var _a, _b, _c, _d, _e; const model = props.model; const addProps = {}; const [deletedKey, setDeletedKey] = useState([]); const [editingKey, setEditingKey] = useState([]); const [expandedRowKeys, setExpandedRowKeys] = useState([]); const [searchValue, setSearchValue] = useState([]); const [columnValue, setColumnValue] = useState([]); const [sourceData, setSourceDataState] = useState({ d: [], h: [], f: model.getDefaultFilter(), p: (_a = model._pageSize) !== null && _a !== void 0 ? _a : 20, s: { text: '', column: '' } }); const setSourceData = (data, who) => { var _a, _b, _c, _d, _e; setSourceDataState({ d: (_a = data.d) !== null && _a !== void 0 ? _a : sourceData.d, h: (_b = data.h) !== null && _b !== void 0 ? _b : sourceData.h, f: (_c = data.f) !== null && _c !== void 0 ? _c : sourceData.f, p: (_d = data.p) !== null && _d !== void 0 ? _d : sourceData.p, s: (_e = data.s) !== null && _e !== void 0 ? _e : sourceData.s, }); }; // Create the header-object and the row-render function. const handleCreateHeader = (data) => { if (!data[0]) return []; let remove = ['key', 'index']; return Object.keys(data[0]._object) .filter(r => !remove.includes(r)) .map((r) => { return ListEdit.handleRowProps(r, { model: model }); }); }; const handleHeader = (data, filters) => { let header = model._headerCreate ? handleCreateHeader(data) : []; props.model._headerAppend.forEach((r) => { r._render = ListEdit.handleRowProps(r._key, { model: model, render: r._renderCustom }).render; header = [...[r.getObject()], ...header]; }); props.model._headerPrepend.forEach((r) => { r._render = ListEdit.handleRowProps(r._key, { model: model, render: r._renderCustom }).render; header = [...header, ...[r.getObject()]]; }); // Hide headers and build default header object header = header .filter((r) => !props.model._headerHide.includes(r.key) && !r.key.startsWith('_')) .map((col) => { return handleDefaultProps(col, { data: data }); }); header = header .map((col) => { if (col.filterable || col.searchable) col.filteredValue = filters[col.dataIndex] || null; return col; }); // Make the column searchable header = header.map((col) => { if (!col.searchable) return col; return Object.assign(Object.assign({}, col), handleSearchProps(col, { filteredInfo: sourceData.f })); }); // Dummy column. if (props.model._addDummyColumn || props.model._emptyColumn) { header = [...[{ key: '', title: '', width: '12px', align: 'right' }], ...header]; } // Action column. if (props.model._actions.length) { header = [...header, ...[handleActionProps({ model: model, props: props })]]; } // Menu column. if (props.model._menuSection) { header = [...header, ...[handleMenuProps({ model: model, props: props })]]; } return header; }; const customizeRenderEmpty = () => { return (React.createElement("div", { style: { textAlign: 'center' } }, model._emptyIcon ? React.createElement(model._emptyIcon, { style: { fontSize: 20, marginTop: 8 } }) : React.createElement(CloseCircleOutlined, { style: { fontSize: 20, marginTop: 12 } }), model._emptyText ? React.createElement("p", null, model._emptyText) : React.createElement("p", null, "The list is empty"))); }; const onExpandedRowsChange = (keys) => { if (model._expandableSingles && expandedRowKeys.length) { setExpandedRowKeys([keys[keys.length - 1]]); } else { setExpandedRowKeys(keys); } }; if ((_c = (_b = model._expandableSectionActive) === null || _b === void 0 ? void 0 : _b.call(model)) !== null && _c !== void 0 ? _c : model._expandableSection) { addProps['expandable'] = { expandRowByClick: model._expandableByClick, expandedRowKeys: expandedRowKeys, rowExpandable: (record) => { var _a, _b; return (_b = (_a = model._expandable) === null || _a === void 0 ? void 0 : _a.call(model, record)) !== null && _b !== void 0 ? _b : false; }, onExpandedRowsChange: onExpandedRowsChange, expandedRowRender: (record) => { return (model._expandableSection) ? (React.createElement("div", { style: { paddingLeft: 26 } }, React.createElement(Section, { key: `${model._key}-${record.key}`, main: props.main, form: props.form, section: record._expandableSection, style: { width: '100%' } }))) : null; }, /* expandIcon: ({ expanded, onExpand, record }: any) => { if (!model._expandable?.(record)) return null; return expanded ? ( <FontAwesomeIcon icon={faChevronDown} style={{ paddingLeft: 6, paddingTop: 6, marginRight: -6, opacity: 0.4, fontSize: 18 }} onClick={(e: any) => onExpand(record, e)} /> ) : ( <FontAwesomeIcon icon={faChevronUp} style={{ paddingLeft: 6, paddingTop: 6, marginRight: -6, opacity: 0.4, fontSize: 18 }} onClick={(e: any) => onExpand(record, e)} /> ) } */ }; } if (model._selectable) { addProps['rowSelection'] = { type: 'checkbox', onChange: (selectedRowKeys, selectedRows) => { var _a, _b; (_a = model._selectableModel) === null || _a === void 0 ? void 0 : _a.formulaSetChildren(model._formula); (_b = model._selectableModel) === null || _b === void 0 ? void 0 : _b.value(model._selectableFormat(selectedRows)); }, getCheckboxProps: (record) => { var _a; return ({ disabled: (_a = record._object.disabled) !== null && _a !== void 0 ? _a : false, }); } }; } /** Implement component specific functions for LIST.TS. */ model.clearExpandedKeys = () => setExpandedRowKeys([]); model.clearDeletedKeys = () => setDeletedKey([]); model.getDeletedKeys = () => deletedKey; model.getEditingKeys = () => editingKey; model.getRecords = () => sourceData.d; model.getHeaders = () => sourceData.h; model.editRecord = (record) => { if (editingKey.includes(record.key)) { let filter = editingKey.filter((r) => r !== record.key); setEditingKey(filter); } else { setEditingKey([...editingKey, ...[record.key]]); } }; model.deleteRecord = (record) => { if (deletedKey.includes(record.key)) { let filter = deletedKey.filter((r) => r !== record.key); setDeletedKey(filter); } else { setDeletedKey([...deletedKey, ...[record.key]]); } }; model.removeRecords = (records) => { let newSourceData = sourceData.d.filter((r) => !records.some((k) => k.key === r.key)); newSourceData = model.setItems(newSourceData); setSourceData({ d: model.setItems(newSourceData), h: handleHeader(newSourceData, sourceData.f), f: sourceData.f, }, 'removeRecords'); }; model.removeRecord = (record) => { let newSourceData = sourceData.d.filter((r) => r.key !== record.key); newSourceData = model.setItems(newSourceData); setSourceData({ d: model.setItems(newSourceData), h: handleHeader(newSourceData, sourceData.f), f: sourceData.f, }, 'removeRecord'); }; model.setRecordValue = (record, dataIndex, value, object) => { setSourceData({ h: sourceData.h, d: sourceData.d.map((r) => { if (r.key === record.key && record[dataIndex] !== value) { record[dataIndex] = value; if (object) record._objects[dataIndex] = object; model._onRecordWasEdited(record); } return r; }), f: sourceData.f, }, 'setRecordValue'); }; model.setRecord = (record) => { let newSourceData = sourceData.d; newSourceData.push(record); newSourceData = model.setItems(newSourceData); setSourceData({ d: newSourceData, h: handleHeader(newSourceData, sourceData.f), f: sourceData.f, }, 'setRecord'); }; model.moveRecord = (record, offset = 0) => { let index = sourceData.d.findIndex((r) => r.key === record.key); if (isNaN(index)) return; let arr = sourceData.d; if (index + offset < 0) { [arr[index], arr[0]] = [arr[0], arr[index]]; } else if (index + offset > sourceData.d.length - 1) { [arr[index], arr[sourceData.d.length - 1]] = [arr[sourceData.d.length - 1], arr[index]]; } else { [arr[index], arr[index + offset]] = [arr[index + offset], arr[index]]; } let newSourceData = model.setItems(arr); setSourceData({ d: newSourceData, h: handleHeader(arr, sourceData.f), f: sourceData.f, }, 'moveRecord'); }; /** Implement component specific functions for DEFAULT.TS */ model._onComplete = (response, data) => { var _a; if (!(response === null || response === void 0 ? void 0 : response.data)) { return; } let newSourceData = model.setItems((_a = data !== null && data !== void 0 ? data : response.data) !== null && _a !== void 0 ? _a : []); setSourceData({ d: newSourceData, h: handleHeader(newSourceData, sourceData.f), f: sourceData.f, }, '_onComplete'); if (model._expandableExpandAll) { setExpandedRowKeys(newSourceData.map((r) => r._object.key)); } }; const onClear = () => setSourceData({ d: [], h: handleHeader([], []), f: [] }, 'onClear'); const onStart = () => { var _a; model._componentIsBuild = true; if (model._defaultObject || ((_a = model._get) === null || _a === void 0 ? void 0 : _a._data)) { let items = model.setItems(); let headers = handleHeader(items, sourceData.f); setSourceData({ d: model.setItems(), h: headers, f: sourceData.f, }, 'onStart'); } else { onClear(); } }; model.tsxSetExpandable = (item) => { // TODO: This only works if the element keeps its index - it should work for any index let indicesOf = Helpers.getIndicesOf('-', item.key, false); let removeFrom = indicesOf[indicesOf.length - 1]; let key = item.key.substr(0, removeFrom); onExpandedRowsChange([...[`${key}-${model._random}`], ...expandedRowKeys]); }; let handleChange = (pagination, filters) => { setSourceData({ p: pagination.pageSize, d: sourceData.d, h: handleHeader(sourceData.d, filters), f: filters, }, 'handleChange'); Object.keys(filters).forEach((key) => { let header = sourceData.h.find((h) => h.key === key); if (header) { window.localStorage.setItem(`filter:${header.key}`, JSON.stringify(filters[key])); } }); }; useEffect(() => { if (model._useCache && model._key) model.defaultFromCache(); onStart(); }, []); useEffect(() => { var _a; model._defaultObject = { dataSource: sourceData.d.map((r) => r._object) }; (_a = model._onChange) === null || _a === void 0 ? void 0 : _a.call(model, sourceData.d); if (model._formula && model._key) { model.value(sourceData.d); } /** Debug purposes */ if (model._useCache && model._key) { window.localStorage.setItem(`list:${model._key}`, JSON.stringify(model._defaultObject)); } }, [sourceData]); return (React.createElement("div", { style: (_d = model._style) !== null && _d !== void 0 ? _d : {} }, React.createElement(ConfigProvider, { renderEmpty: customizeRenderEmpty }, React.createElement(Table, Object.assign({ size: props.model._dense ? 'small' : 'middle', style: { width: '100%' }, onRow: (record, index) => ({ onClick: e => { var _a; return (_a = model._onRowClicked) === null || _a === void 0 ? void 0 : _a.call(model, e, record, index); } }), rowKey: 'key', rowClassName: (record) => { switch (true) { case (model === null || model === void 0 ? void 0 : model.getDeletedKeys().includes(record.key)): return 'rowClassName-deleted'; default: return ''; } }, pagination: props.model._footer ? { pageSize: sourceData.p, showSizeChanger: true } : false, showHeader: props.model._header ? undefined : false, columns: sourceData.h, dataSource: sourceData.d, showSorterTooltip: false, onChange: handleChange, bordered: (_e = props.model._bordered) !== null && _e !== void 0 ? _e : false }, addProps))))); }; export default List; //# sourceMappingURL=List.js.map