react-antd-admin-panel
Version:
Easy prototyping admin panel using React and Antd
321 lines • 14.9 kB
JavaScript
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