UNPKG

@croz/nrich-registry-mui

Version:

Contains the UI implementation of registry for the MUI component library

500 lines (493 loc) 21.6 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/index.ts var src_exports = {}; __export(src_exports, { RegistryEntity: () => RegistryEntity, RegistryEntityPicker: () => RegistryEntityPicker, RegistryFilter: () => RegistryFilter, RegistryForm: () => RegistryForm, RegistryTable: () => RegistryTable }); module.exports = __toCommonJS(src_exports); // src/component/RegistryEntity.tsx var import_react4 = __toESM(require("react")); var import_material4 = require("@mui/material"); var import_nrich_registry_core4 = require("@croz/nrich-registry-core"); // src/component/RegistryFilter.tsx var import_react = __toESM(require("react")); var import_Search = __toESM(require("@mui/icons-material/Search")); var import_material = require("@mui/material"); var import_nrich_registry_core = require("@croz/nrich-registry-core"); var RegistryFilter = ({ onFilterUpdate }) => { const { availableFields, searchParameter, handleFieldsChange, handleQueryChange } = (0, import_nrich_registry_core.useRegistryFilter)(); (0, import_nrich_registry_core.useDebouncedUpdateEffect)(() => { onFilterUpdate(searchParameter); }, 300, [searchParameter]); return /* @__PURE__ */ import_react.default.createElement("div", null, /* @__PURE__ */ import_react.default.createElement(import_material.FormControl, { sx: { m: 1, width: 300 }, size: "small" }, /* @__PURE__ */ import_react.default.createElement(import_material.InputLabel, { htmlFor: "search-query" }, "Search..."), /* @__PURE__ */ import_react.default.createElement(import_material.OutlinedInput, { id: "search-query", value: searchParameter.query, onChange: handleQueryChange, label: "Search...", startAdornment: /* @__PURE__ */ import_react.default.createElement(import_material.InputAdornment, { position: "start" }, /* @__PURE__ */ import_react.default.createElement(import_Search.default, null)) })), /* @__PURE__ */ import_react.default.createElement(import_material.FormControl, { sx: { m: 1, width: 300 }, size: "small" }, /* @__PURE__ */ import_react.default.createElement(import_material.InputLabel, { id: "demo-multiple-name-label" }, "Properties"), /* @__PURE__ */ import_react.default.createElement(import_material.Select, { labelId: "demo-multiple-name-label", id: "demo-multiple-name", multiple: true, label: "Properties", value: searchParameter.propertyNameList, onChange: (event) => handleFieldsChange(event), input: /* @__PURE__ */ import_react.default.createElement(import_material.OutlinedInput, null) }, availableFields.map((field) => /* @__PURE__ */ import_react.default.createElement(import_material.MenuItem, { key: field.value, value: field.value }, field.label))))); }; // src/component/RegistryForm.tsx var import_react2 = __toESM(require("react")); var import_material2 = require("@mui/material"); var import_nrich_registry_core2 = require("@croz/nrich-registry-core"); var SubEntityField = ({ configuration, value, onChange, error }) => { var _a; const { entityConfiguration, data } = (0, import_nrich_registry_core2.useRegistryEntity)(configuration.singularAssociationReferencedClass, { pageNumber: 0, pageSize: 1e3 }); const idField = (0, import_nrich_registry_core2.findIdField)(entityConfiguration); return /* @__PURE__ */ import_react2.default.createElement(import_material2.FormControl, { size: "small" }, /* @__PURE__ */ import_react2.default.createElement(import_material2.InputLabel, { id: `${configuration.name}-picker-label` }, configuration.formLabel), /* @__PURE__ */ import_react2.default.createElement(import_material2.Select, { labelId: `${configuration.name}-picker-label`, id: `${configuration.name}-picker`, label: configuration.formLabel, value: (_a = value == null ? void 0 : value[idField.name]) != null ? _a : "", onChange: (event) => onChange({ [idField.name]: event.target.value }), error: !!error, input: /* @__PURE__ */ import_react2.default.createElement(import_material2.OutlinedInput, null) }, ((data == null ? void 0 : data.content) || []).map((option) => /* @__PURE__ */ import_react2.default.createElement(import_material2.MenuItem, { key: option[idField.name], value: option[idField.name] }, (0, import_nrich_registry_core2.formatIdName)(entityConfiguration.classFullName, idField.name, option[idField.name])))), !!error && /* @__PURE__ */ import_react2.default.createElement(import_material2.FormHelperText, null, error)); }; var Field = ({ configuration, value, onChange, error }) => { var _a; switch (configuration.javascriptType) { case "string": return /* @__PURE__ */ import_react2.default.createElement(import_material2.TextField, { error: !!error, helperText: error, label: configuration.formLabel, value: value != null ? value : "", size: "small", onChange: (event) => onChange(event.target.value), disabled: !configuration.editable }); case "number": if (configuration.decimal) { return /* @__PURE__ */ import_react2.default.createElement(import_material2.TextField, { error: !!error, helperText: error, label: configuration.formLabel, value: value != null ? value : "", size: "small", inputProps: { inputMode: "numeric", pattern: "[0-9.,]*" }, disabled: !configuration.editable, onChange: (event) => onChange(+event.target.value) }); } return /* @__PURE__ */ import_react2.default.createElement(import_material2.TextField, { error: !!error, helperText: error, label: configuration.formLabel, value: value != null ? value : "", size: "small", inputProps: { inputMode: "numeric", pattern: "[0-9]*" }, disabled: !configuration.editable, onChange: (event) => onChange(+event.target.value) }); case "boolean": return /* @__PURE__ */ import_react2.default.createElement(import_material2.TextField, { error: !!error, helperText: error, label: configuration.formLabel, value: value != null ? value : "", size: "small", onChange: (event) => onChange(event.target.value), disabled: !configuration.editable }); case "object": return /* @__PURE__ */ import_react2.default.createElement(SubEntityField, { configuration, value, onChange, error }); case "date": return /* @__PURE__ */ import_react2.default.createElement(import_material2.TextField, { error: !!error, helperText: error, label: configuration.formLabel, value: (_a = value == null ? void 0 : value.split("T")[0]) != null ? _a : "", type: "date", size: "small", onChange: (event) => onChange(event.target.value), disabled: !configuration.editable, InputLabelProps: { shrink: true } }); default: return /* @__PURE__ */ import_react2.default.createElement(import_material2.TextField, { error: !!error, helperText: error, label: configuration.formLabel, value: value != null ? value : null, size: "small", onChange: (event) => onChange(event.target.value), disabled: !configuration.editable }); } }; var paperStyle = { display: "flex", flexDirection: "column", p: 4, gap: 2 }; var RegistryForm = ({ initialValues, type, onSubmit, onClose }) => { const { entityConfiguration, yupSchema, finalInitialValues, properties } = (0, import_nrich_registry_core2.useRegistryForm)(initialValues, type); const [value, setValue] = import_react2.default.useState(finalInitialValues); const [errors, setErrors] = import_react2.default.useState({}); const clearError = (fieldName) => { setErrors((oldErrors) => __spreadProps(__spreadValues({}, oldErrors), { [fieldName]: void 0 })); }; const updateField = (fieldName, newValue) => { setValue((oldValue) => __spreadProps(__spreadValues({}, oldValue), { [fieldName]: newValue })); clearError(fieldName); }; const handleSubmit = () => __async(void 0, null, function* () { try { yield yupSchema.validate(value, { abortEarly: false }); onSubmit(value); } catch (e) { setErrors(e.inner.reduce((all, error) => __spreadProps(__spreadValues({}, all), { [error.path]: error.message }), {})); } }); return /* @__PURE__ */ import_react2.default.createElement(import_material2.Paper, { sx: paperStyle }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { variant: "h5" }, type === "update" ? `Update ${entityConfiguration.name}` : `Create ${entityConfiguration.name}`), properties.map((field) => /* @__PURE__ */ import_react2.default.createElement(Field, { key: field.name, configuration: field, value: value[field.name], onChange: (newValue) => updateField(field.name, newValue), error: errors[field.name] })), /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: { alignSelf: "end" } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Button, { variant: "outlined", onClick: onClose, sx: { mr: 2 } }, "Cancel"), /* @__PURE__ */ import_react2.default.createElement(import_material2.Button, { variant: "contained", onClick: handleSubmit }, type === "update" ? "Update" : "Create"))); }; // src/component/RegistryTable.tsx var import_react3 = __toESM(require("react")); var import_Delete = __toESM(require("@mui/icons-material/Delete")); var import_Edit = __toESM(require("@mui/icons-material/Edit")); var import_material3 = require("@mui/material"); var import_TableSortLabel = __toESM(require("@mui/material/TableSortLabel")); var import_nrich_registry_core3 = require("@croz/nrich-registry-core"); var RegistryTableHeadCell = ({ property, sortPropertyList, onSortChange }) => { const { sortDirection, sortChangeHandler } = (0, import_nrich_registry_core3.useRegistrySort)(property, sortPropertyList, onSortChange); const muiSortDirection = sortDirection === void 0 ? false : sortDirection.toLowerCase(); return /* @__PURE__ */ import_react3.default.createElement(import_material3.TableCell, { key: property.name, sortDirection: muiSortDirection }, /* @__PURE__ */ import_react3.default.createElement(import_TableSortLabel.default, { active: muiSortDirection !== false, direction: muiSortDirection !== false ? muiSortDirection : void 0, onClick: property.sortable ? () => sortChangeHandler() : () => { } }, property.columnHeader)); }; var PropertyCell = ({ propertyConfiguration, value, subEntityMap }) => { let stringValue = value; if (value === void 0 || value === null) { stringValue = "-"; } else if (propertyConfiguration.javascriptType === "object") { const configuration = subEntityMap[propertyConfiguration.singularAssociationReferencedClass]; const idField = (0, import_nrich_registry_core3.findIdField)(configuration); stringValue = (0, import_nrich_registry_core3.formatIdName)(configuration.classFullName, idField.name, value[idField.name]); } else if (propertyConfiguration.javascriptType === "date") { stringValue = new Date(value).toLocaleDateString(); } else if (propertyConfiguration.javascriptType === "number") { if (propertyConfiguration.decimal) { stringValue = Number(value).toFixed(2); } else { stringValue = value; } } else if (propertyConfiguration.javascriptType === "boolean") { stringValue = value ? "Yes" : "No"; } return /* @__PURE__ */ import_react3.default.createElement(import_material3.TableCell, null, stringValue); }; var RegistryTableRow = ({ row, onEdit, onRemove }) => { const { entityConfiguration, singularAssociationsMap, finalProperties } = (0, import_nrich_registry_core3.useRegistryEntityContext)(); return /* @__PURE__ */ import_react3.default.createElement(import_material3.TableRow, { sx: { "&:last-child td, &:last-child th": { border: 0 } } }, finalProperties.map((property) => /* @__PURE__ */ import_react3.default.createElement(PropertyCell, { key: property.name, propertyConfiguration: property, value: (0, import_nrich_registry_core3.resolveValue)(property, row), subEntityMap: singularAssociationsMap })), (entityConfiguration.updateable || entityConfiguration.deletable) && /* @__PURE__ */ import_react3.default.createElement(import_material3.TableCell, null, entityConfiguration.updateable && /* @__PURE__ */ import_react3.default.createElement(import_material3.IconButton, { onClick: () => onEdit((0, import_nrich_registry_core3.resolveId)(entityConfiguration, row), row) }, /* @__PURE__ */ import_react3.default.createElement(import_Edit.default, null)), entityConfiguration.deletable && /* @__PURE__ */ import_react3.default.createElement(import_material3.IconButton, { onClick: () => onRemove((0, import_nrich_registry_core3.resolveId)(entityConfiguration, row)) }, /* @__PURE__ */ import_react3.default.createElement(import_Delete.default, null)))); }; var RegistryTable = ({ data, request, onRequestChange, onEdit, onRemove }) => { var _a; const { entityConfiguration, finalProperties } = (0, import_nrich_registry_core3.useRegistryEntityContext)(); const onPageChange = (event, newPage) => { onRequestChange(__spreadProps(__spreadValues({}, request), { pageNumber: newPage })); }; const onPageSizeChange = (event) => { onRequestChange(__spreadProps(__spreadValues({}, request), { pageSize: +event.target.value, pageNumber: 0 })); }; const onSortChange = (sortPropertyList) => { onRequestChange(__spreadProps(__spreadValues({}, request), { sortPropertyList })); }; return /* @__PURE__ */ import_react3.default.createElement(import_material3.Paper, null, /* @__PURE__ */ import_react3.default.createElement(import_material3.TableContainer, null, /* @__PURE__ */ import_react3.default.createElement(import_material3.Table, { sx: { minWidth: 650 }, size: "small" }, /* @__PURE__ */ import_react3.default.createElement(import_material3.TableHead, null, /* @__PURE__ */ import_react3.default.createElement(import_material3.TableRow, null, finalProperties.map((property) => { var _a2; return /* @__PURE__ */ import_react3.default.createElement(RegistryTableHeadCell, { key: property.name, property, sortPropertyList: (_a2 = request.sortPropertyList) != null ? _a2 : [], onSortChange }); }), (entityConfiguration.updateable || entityConfiguration.deletable) && /* @__PURE__ */ import_react3.default.createElement(import_material3.TableCell, null))), /* @__PURE__ */ import_react3.default.createElement(import_material3.TableBody, null, ((_a = data.content) != null ? _a : []).map((row, index) => /* @__PURE__ */ import_react3.default.createElement(RegistryTableRow, { key: index, row, onEdit, onRemove }))))), /* @__PURE__ */ import_react3.default.createElement(import_material3.TablePagination, { rowsPerPageOptions: [5, 10, 25], component: "div", count: data.totalElements, rowsPerPage: request.pageSize, page: request.pageNumber, onPageChange, onRowsPerPageChange: onPageSizeChange })); }; // src/component/RegistryEntity.tsx var modalStyle = { position: "absolute", top: "50%", left: "50%", transform: "translate(-50%, -50%)", width: 600, bgcolor: "background.paper", boxShadow: 12 }; var RegistryEntity = ({ entityName }) => { const { entityConfiguration, data, request, handlePagingUpdate, handleFilterUpdate, handleAddClick, handleEditClick, handleSubmitClick, formType, formData, formModalOpen, closeFormModal, loading, remove } = (0, import_nrich_registry_core4.useRegistryEntityAdministration)(entityName); return /* @__PURE__ */ import_react4.default.createElement(import_nrich_registry_core4.RegistryEntityContextProvider, { entityConfiguration }, /* @__PURE__ */ import_react4.default.createElement(import_material4.Paper, { sx: { display: "flex", flexDirection: "row", justifyContent: "space-between", alignItems: "center" } }, /* @__PURE__ */ import_react4.default.createElement(RegistryFilter, { onFilterUpdate: handleFilterUpdate }), /* @__PURE__ */ import_react4.default.createElement("div", null, entityConfiguration.creatable && /* @__PURE__ */ import_react4.default.createElement(import_material4.Button, { variant: "contained", onClick: handleAddClick }, "Add"))), /* @__PURE__ */ import_react4.default.createElement(RegistryTable, { data, request, onRequestChange: handlePagingUpdate, onEdit: handleEditClick, onRemove: remove }), formModalOpen && /* @__PURE__ */ import_react4.default.createElement(import_material4.Modal, { open: formModalOpen, onClose: (_, reason) => reason !== "backdropClick" && closeFormModal() }, /* @__PURE__ */ import_react4.default.createElement(import_material4.Box, { sx: modalStyle }, /* @__PURE__ */ import_react4.default.createElement(RegistryForm, { type: formType, initialValues: formData, onClose: closeFormModal, onSubmit: handleSubmitClick }))), loading && /* @__PURE__ */ import_react4.default.createElement(import_material4.Backdrop, { sx: { color: "#fff", zIndex: (theme) => theme.zIndex.drawer + 1 }, open: true }, /* @__PURE__ */ import_react4.default.createElement(import_material4.CircularProgress, { color: "inherit" }))); }; // src/component/RegistryEntityPicker.tsx var import_react5 = __toESM(require("react")); var import_material5 = require("@mui/material"); var import_nrich_registry_core5 = require("@croz/nrich-registry-core"); var RegistryEntityPicker = ({ value, setValue }) => { const entityConfigurations = (0, import_nrich_registry_core5.useRegistryConfigurationStore)((state) => state.groupConfigurations.flatMap((groupConfiguration) => groupConfiguration.entityConfigurationList)); return /* @__PURE__ */ import_react5.default.createElement(import_material5.FormControl, { sx: { m: 1, width: 300 }, size: "small" }, /* @__PURE__ */ import_react5.default.createElement(import_material5.InputLabel, { id: "registry-entity-picker-label" }, "Entity"), /* @__PURE__ */ import_react5.default.createElement(import_material5.Select, { labelId: "registry-entity-picker-label", id: "registry-entity-picker", label: "Entity", value, onChange: (event) => setValue(event.target.value), input: /* @__PURE__ */ import_react5.default.createElement(import_material5.OutlinedInput, null) }, entityConfigurations.map((entity) => /* @__PURE__ */ import_react5.default.createElement(import_material5.MenuItem, { key: entity.name, value: entity.name }, entity.name)))); }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { RegistryEntity, RegistryEntityPicker, RegistryFilter, RegistryForm, RegistryTable }); //# sourceMappingURL=index.js.map