UNPKG

@skbkontur/db-viewer-ui

Version:

Database Viewer with custom configuration

284 lines 16.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ObjectTableContainer = void 0; const tslib_1 = require("tslib"); const jsx_runtime_1 = require("react/jsx-runtime"); const react_stack_layout_1 = require("@skbkontur/react-stack-layout"); const react_ui_1 = require("@skbkontur/react-ui"); const react_1 = require("react"); const react_router_1 = require("react-router"); const ErrorHandlingContainer_1 = require("../Components/ErrorHandling/ErrorHandlingContainer"); const CommonLayout_1 = require("../Components/Layouts/CommonLayout"); const ObjectTable_1 = require("../Components/ObjectTable/ObjectTable"); const ObjectTableLayoutHeader_1 = require("../Components/ObjectTableLayoutHeader/ObjectTableLayoutHeader"); const ObjectFieldFilterOperator_1 = require("../Domain/Api/DataTypes/ObjectFieldFilterOperator"); const ObjectFilterSortOrder_1 = require("../Domain/Api/DataTypes/ObjectFilterSortOrder"); const ObjectSearchQueryMapping_1 = require("../Domain/Objects/ObjectSearchQueryMapping"); const PropertyMetaInformationUtils_1 = require("../Domain/Objects/PropertyMetaInformationUtils"); const RouteUtils_1 = require("../Domain/Utils/RouteUtils"); const getDefaultQuery = () => ({ conditions: [], offset: 0, count: 20, hiddenColumns: [], sorts: [], }); const ObjectTableContainer = ({ dbViewerApi, customRenderer, useErrorHandlingContainer, isSuperUser, }) => { var _a; const { search, pathname } = (0, react_router_1.useLocation)(); const navigate = (0, react_router_1.useNavigate)(); const { objectId = "" } = (0, react_router_1.useParams)(); const [objects, setObjects] = (0, react_1.useState)(null); const [loading, setLoading] = (0, react_1.useState)(false); const [showModalFilter, setShowModalFilter] = (0, react_1.useState)(false); const [metaInformation, setMetaInformation] = (0, react_1.useState)(null); const [query, setQuery] = (0, react_1.useState)(getDefaultQuery()); const [downloading, setDownloading] = (0, react_1.useState)(false); const [shouldLoadObjects, setShouldLoadObjects] = (0, react_1.useState)(false); const [showDownloadModal, setShowDownloadModal] = (0, react_1.useState)(false); const [downloadCount, setDownloadCount] = (0, react_1.useState)(undefined); (0, react_1.useEffect)(() => { loadData(); }, []); (0, react_1.useEffect)(() => { if (metaInformation) { const nextQuery = parseQuery(search, metaInformation); setQuery(nextQuery); setShouldLoadObjects(true); } }, [search]); (0, react_1.useEffect)(() => { if (shouldLoadObjects) { setShouldLoadObjects(false); loadObjectsWithLoader(); } }, [query]); const handleChangeModalFilter = (value) => { if (!value) { updateQuery(getDefaultQuery()); } else { updateQuery(value); } }; const handleCheckCount = () => tslib_1.__awaiter(void 0, void 0, void 0, function* () { var _b; if (!metaInformation) { return; } setDownloading(true); try { const { conditions, sorts, hiddenColumns } = query; const newQuery = { conditions: conditions, sorts: sorts, excludedFields: hiddenColumns, }; const downloadResult = yield dbViewerApi.countObjects(metaInformation.identifier, newQuery); const count = (_b = downloadResult.count) !== null && _b !== void 0 ? _b : 0; if (count > downloadResult.countLimit) { setDownloading(false); setShowDownloadModal(true); setDownloadCount(downloadResult); return; } window.location.href = dbViewerApi.getDownloadObjectsUrl(metaInformation.identifier, JSON.stringify(newQuery)); } finally { setDownloading(false); } }); const handleDeleteObject = (index) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { if ((objects === null || objects === void 0 ? void 0 : objects.items) && objects.items.length >= index && metaInformation) { const conditions = getItemConditions(objects.items[index]); yield dbViewerApi.deleteObject(metaInformation.identifier, { conditions }); yield loadObjects(query); } }); const handleResetQuery = () => updateQuery(getDefaultQuery()); const handleOpenFilter = () => setShowModalFilter(true); const handleCloseDownloadModal = () => setShowDownloadModal(false); const handleChangeSort = (columnName) => { const { sorts } = query; const currentSortIndex = sorts.findIndex(x => x.path === columnName); if (currentSortIndex === -1) { updateQuery({ sorts: [ ...sorts, { path: columnName, sortOrder: ObjectFilterSortOrder_1.ObjectFilterSortOrder.Ascending, }, ], }); return; } const currentSortOrder = sorts[currentSortIndex].sortOrder; if (currentSortOrder === ObjectFilterSortOrder_1.ObjectFilterSortOrder.Ascending) { updateQuery({ sorts: [ ...sorts.slice(0, currentSortIndex), { path: columnName, sortOrder: ObjectFilterSortOrder_1.ObjectFilterSortOrder.Descending, }, ...sorts.slice(currentSortIndex + 1), ], }); return; } if (currentSortOrder === ObjectFilterSortOrder_1.ObjectFilterSortOrder.Descending) { updateQuery({ sorts: [...sorts.slice(0, currentSortIndex), ...sorts.slice(currentSortIndex + 1)], }); } }; const goToPage = (page) => { navigate(getQuery(query, { offset: (page - 1) * query.count })); }; const renderItemsCount = (offset, countPerPage, count, countLimit) => { const total = count > countLimit ? countLimit : count; const firstNumber = Math.min(total, offset); const lastNumber = Math.min(total, offset + countPerPage); return ((0, jsx_runtime_1.jsxs)(react_stack_layout_1.RowStack, { block: true, gap: 2, baseline: true, "data-tid": "ItemsCountInfo", children: [(0, jsx_runtime_1.jsxs)(react_stack_layout_1.Fit, { children: ["\u0417\u0430\u043F\u0438\u0441\u0438 \u0441 ", firstNumber, " \u043F\u043E ", lastNumber] }), (0, jsx_runtime_1.jsx)(react_stack_layout_1.Fit, { children: "|" }), (0, jsx_runtime_1.jsxs)(react_stack_layout_1.Fit, { children: ["\u0412\u0441\u0435\u0433\u043E ", count > countLimit ? `${countLimit.toString()}+` : count] })] })); }; const renderPageNavigation = () => { const { offset, count } = query; if (!objects) { return null; } const trueCount = objects.count || objects.items.length; const totalCount = trueCount > objects.countLimit ? objects.countLimit : trueCount; if (totalCount == null || totalCount === 0 || Math.ceil(totalCount / count) <= 1) { return null; } return ((0, jsx_runtime_1.jsx)(react_ui_1.Paging, { "data-tid": "Paging", activePage: Math.floor(offset / count) + 1, pagesCount: Math.ceil(totalCount / count), onPageChange: goToPage })); }; const { offset, count, sorts } = query; let properties = []; if ((_a = metaInformation === null || metaInformation === void 0 ? void 0 : metaInformation.typeMetaInformation) === null || _a === void 0 ? void 0 : _a.properties) { properties = PropertyMetaInformationUtils_1.PropertyMetaInformationUtils.getProperties(metaInformation.typeMetaInformation.properties); } const { allowReadAll, allowDelete, allowSort } = (metaInformation === null || metaInformation === void 0 ? void 0 : metaInformation.schemaDescription) || { allowReadAll: false, allowDelete: false, allowSort: false, }; return ((0, jsx_runtime_1.jsxs)(CommonLayout_1.CommonLayout, { withArrow: true, children: [(0, jsx_runtime_1.jsx)(CommonLayout_1.CommonLayout.GoBack, { to: RouteUtils_1.RouteUtils.backUrl(pathname) }), useErrorHandlingContainer && (0, jsx_runtime_1.jsx)(ErrorHandlingContainer_1.ErrorHandlingContainer, {}), (0, jsx_runtime_1.jsx)(CommonLayout_1.CommonLayout.Header, { title: objectId, tools: (0, jsx_runtime_1.jsx)(ObjectTableLayoutHeader_1.ObjectTableLayoutHeader, { query: query, allowReadAll: allowReadAll, properties: properties, onChange: handleChangeModalFilter, onDownloadClick: handleCheckCount, onDownloadAbort: handleCloseDownloadModal, downloading: downloading, showDownloadModal: showDownloadModal, showModalFilter: showModalFilter, downloadCount: downloadCount }) }), (0, jsx_runtime_1.jsx)(CommonLayout_1.CommonLayout.Content, { children: (0, jsx_runtime_1.jsx)(react_ui_1.Loader, { type: "big", active: loading, children: (0, jsx_runtime_1.jsxs)(react_stack_layout_1.ColumnStack, { gap: 4, children: [(0, jsx_runtime_1.jsx)(react_stack_layout_1.Fit, { children: objects && renderItemsCount(offset, count, objects.count || objects.items.length, objects.countLimit) }), (0, jsx_runtime_1.jsx)(react_stack_layout_1.Fit, { style: { maxWidth: "inherit" }, children: (objects === null || objects === void 0 ? void 0 : objects.items) && objects.items.length > 0 ? (properties && ((0, jsx_runtime_1.jsx)(ObjectTable_1.ObjectTable, { properties: getVisibleProperties(properties), objectType: (metaInformation === null || metaInformation === void 0 ? void 0 : metaInformation.identifier) || "", customRenderer: customRenderer, currentSorts: sorts, items: objects.count == null ? objects.items.slice(offset, offset + count) : objects.items, onDetailsClick: getDetailsUrl, onDeleteClick: handleDeleteObject, onChangeSortClick: handleChangeSort, allowDelete: isSuperUser && allowDelete, allowSort: allowSort }))) : ((0, jsx_runtime_1.jsxs)(react_stack_layout_1.RowStack, { block: true, gap: 1, baseline: true, "data-tid": "NothingFound", children: [(0, jsx_runtime_1.jsx)(react_stack_layout_1.Fit, { children: "\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E" }), (0, jsx_runtime_1.jsx)(react_stack_layout_1.Fit, { children: (0, jsx_runtime_1.jsx)(react_ui_1.Link, { onClick: handleResetQuery, children: "\u0421\u0431\u0440\u043E\u0441\u044C\u0442\u0435 \u0444\u0438\u043B\u044C\u0442\u0440" }) }), (0, jsx_runtime_1.jsx)(react_stack_layout_1.Fit, { children: "\u0438\u043B\u0438" }), (0, jsx_runtime_1.jsx)(react_stack_layout_1.Fit, { children: (0, jsx_runtime_1.jsx)(react_ui_1.Link, { onClick: handleOpenFilter, children: "\u0438\u0437\u043C\u0435\u043D\u0438\u0442\u0435" }) }), (0, jsx_runtime_1.jsx)(react_stack_layout_1.Fit, { children: "\u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u0444\u0438\u043B\u044C\u0442\u0440\u0430\u0446\u0438\u0438" })] })) }), (0, jsx_runtime_1.jsx)(react_stack_layout_1.Fit, { children: renderPageNavigation() })] }) }) })] })); function loadData() { return tslib_1.__awaiter(this, void 0, void 0, function* () { setLoading(true); try { const metaInformation = yield dbViewerApi.getMeta(objectId); const query = parseQuery(search, metaInformation); setMetaInformation(metaInformation); setQuery(query); yield loadObjectsIfAllowed(metaInformation, query); } finally { setLoading(false); } }); } function loadObjectsWithLoader() { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (!metaInformation) { return; } setLoading(true); try { yield loadObjectsIfAllowed(metaInformation, query); } finally { setLoading(false); } }); } function loadObjectsIfAllowed(meta, query) { var _a; return tslib_1.__awaiter(this, void 0, void 0, function* () { const allowReadAll = meta.schemaDescription.allowReadAll; const props = ((_a = meta.typeMetaInformation) === null || _a === void 0 ? void 0 : _a.properties) || []; const conditions = query.conditions || []; if (allowReadAll || PropertyMetaInformationUtils_1.PropertyMetaInformationUtils.hasFilledRequiredFields(conditions, props)) { yield loadObjects(query); } else { setShowModalFilter(true); setObjects(null); } }); } function loadObjects({ offset, count, conditions, sorts }) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const objects = yield dbViewerApi.searchObjects(objectId, { conditions, sorts, offset, count, excludedFields: [], }); setObjects(objects); }); } function getVisibleProperties(properties) { return properties.filter(({ name }) => !query.hiddenColumns.includes(name)); } function updateQuery(queryUpdate) { var _a; let offset = (_a = queryUpdate.offset) !== null && _a !== void 0 ? _a : query.offset; if (offset !== 0 && queryUpdate.count) { offset = Math.floor(offset / queryUpdate.count) * queryUpdate.count; } setShowModalFilter(false); const newQuery = Object.assign(Object.assign(Object.assign({}, query), queryUpdate), { offset }); setQuery(newQuery); navigate(getQuery(newQuery)); } function getItemConditions(item) { const properties = (metaInformation === null || metaInformation === void 0 ? void 0 : metaInformation.typeMetaInformation.properties) || []; return properties .filter(x => x.isIdentity) .map(x => ({ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore value: item[x.name], path: x.name, operator: ObjectFieldFilterOperator_1.ObjectFieldFilterOperator.Equals, })); } function getDetailsUrl(item) { const properties = (metaInformation === null || metaInformation === void 0 ? void 0 : metaInformation.typeMetaInformation.properties) || []; const query = {}; for (const prop of properties) { if (prop.isIdentity) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore query[prop.name] = item[prop.name]; } } return RouteUtils_1.RouteUtils.goTo(pathname, `details?${new URLSearchParams(query)}`); } function getQuery(newQuery, overrides = {}) { var _a; let properties = []; if ((_a = metaInformation === null || metaInformation === void 0 ? void 0 : metaInformation.typeMetaInformation) === null || _a === void 0 ? void 0 : _a.properties) { properties = PropertyMetaInformationUtils_1.PropertyMetaInformationUtils.getProperties(metaInformation.typeMetaInformation.properties); } return (pathname + ObjectSearchQueryMapping_1.ObjectSearchQueryMapping.stringify(Object.assign(Object.assign({}, newQuery), overrides), properties.map(x => x.name))); } function parseQuery(urlQuery, metaInformation) { var _a; let properties = []; if ((_a = metaInformation === null || metaInformation === void 0 ? void 0 : metaInformation.typeMetaInformation) === null || _a === void 0 ? void 0 : _a.properties) { properties = PropertyMetaInformationUtils_1.PropertyMetaInformationUtils.getProperties(metaInformation.typeMetaInformation.properties); } return ObjectSearchQueryMapping_1.ObjectSearchQueryMapping.parse(urlQuery, properties.map(x => x.name)); } }; exports.ObjectTableContainer = ObjectTableContainer; //# sourceMappingURL=ObjectTableContainer.js.map