@skbkontur/db-viewer-ui
Version:
Database Viewer with custom configuration
284 lines • 16.4 kB
JavaScript
;
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