@croz/nrich-registry-mui
Version:
Contains the UI implementation of registry for the MUI component library
511 lines (505 loc) • 18.4 kB
JavaScript
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
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 __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/component/RegistryEntity.tsx
import React4 from "react";
import {
Backdrop,
Box as Box2,
Button as Button2,
CircularProgress,
Modal,
Paper as Paper3
} from "@mui/material";
import { RegistryEntityContextProvider, useRegistryEntityAdministration } from "@croz/nrich-registry-core";
// src/component/RegistryFilter.tsx
import React from "react";
import SearchIcon from "@mui/icons-material/Search";
import {
FormControl,
InputAdornment,
InputLabel,
MenuItem,
OutlinedInput,
Select
} from "@mui/material";
import { useDebouncedUpdateEffect, useRegistryFilter } from "@croz/nrich-registry-core";
var RegistryFilter = ({ onFilterUpdate }) => {
const {
availableFields,
searchParameter,
handleFieldsChange,
handleQueryChange
} = useRegistryFilter();
useDebouncedUpdateEffect(() => {
onFilterUpdate(searchParameter);
}, 300, [searchParameter]);
return /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(FormControl, {
sx: { m: 1, width: 300 },
size: "small"
}, /* @__PURE__ */ React.createElement(InputLabel, {
htmlFor: "search-query"
}, "Search..."), /* @__PURE__ */ React.createElement(OutlinedInput, {
id: "search-query",
value: searchParameter.query,
onChange: handleQueryChange,
label: "Search...",
startAdornment: /* @__PURE__ */ React.createElement(InputAdornment, {
position: "start"
}, /* @__PURE__ */ React.createElement(SearchIcon, null))
})), /* @__PURE__ */ React.createElement(FormControl, {
sx: { m: 1, width: 300 },
size: "small"
}, /* @__PURE__ */ React.createElement(InputLabel, {
id: "demo-multiple-name-label"
}, "Properties"), /* @__PURE__ */ React.createElement(Select, {
labelId: "demo-multiple-name-label",
id: "demo-multiple-name",
multiple: true,
label: "Properties",
value: searchParameter.propertyNameList,
onChange: (event) => handleFieldsChange(event),
input: /* @__PURE__ */ React.createElement(OutlinedInput, null)
}, availableFields.map((field) => /* @__PURE__ */ React.createElement(MenuItem, {
key: field.value,
value: field.value
}, field.label)))));
};
// src/component/RegistryForm.tsx
import React2 from "react";
import {
Box,
Button,
FormControl as FormControl2,
FormHelperText,
InputLabel as InputLabel2,
MenuItem as MenuItem2,
OutlinedInput as OutlinedInput2,
Paper,
Select as Select2,
TextField,
Typography
} from "@mui/material";
import {
findIdField,
formatIdName,
useRegistryEntity,
useRegistryForm
} from "@croz/nrich-registry-core";
var SubEntityField = ({
configuration,
value,
onChange,
error
}) => {
var _a;
const { entityConfiguration, data } = useRegistryEntity(configuration.singularAssociationReferencedClass, { pageNumber: 0, pageSize: 1e3 });
const idField = findIdField(entityConfiguration);
return /* @__PURE__ */ React2.createElement(FormControl2, {
size: "small"
}, /* @__PURE__ */ React2.createElement(InputLabel2, {
id: `${configuration.name}-picker-label`
}, configuration.formLabel), /* @__PURE__ */ React2.createElement(Select2, {
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__ */ React2.createElement(OutlinedInput2, null)
}, ((data == null ? void 0 : data.content) || []).map((option) => /* @__PURE__ */ React2.createElement(MenuItem2, {
key: option[idField.name],
value: option[idField.name]
}, formatIdName(entityConfiguration.classFullName, idField.name, option[idField.name])))), !!error && /* @__PURE__ */ React2.createElement(FormHelperText, null, error));
};
var Field = ({
configuration,
value,
onChange,
error
}) => {
var _a;
switch (configuration.javascriptType) {
case "string":
return /* @__PURE__ */ React2.createElement(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__ */ React2.createElement(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__ */ React2.createElement(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__ */ React2.createElement(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__ */ React2.createElement(SubEntityField, {
configuration,
value,
onChange,
error
});
case "date":
return /* @__PURE__ */ React2.createElement(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__ */ React2.createElement(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
} = useRegistryForm(initialValues, type);
const [value, setValue] = React2.useState(finalInitialValues);
const [errors, setErrors] = React2.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__ */ React2.createElement(Paper, {
sx: paperStyle
}, /* @__PURE__ */ React2.createElement(Typography, {
variant: "h5"
}, type === "update" ? `Update ${entityConfiguration.name}` : `Create ${entityConfiguration.name}`), properties.map((field) => /* @__PURE__ */ React2.createElement(Field, {
key: field.name,
configuration: field,
value: value[field.name],
onChange: (newValue) => updateField(field.name, newValue),
error: errors[field.name]
})), /* @__PURE__ */ React2.createElement(Box, {
sx: { alignSelf: "end" }
}, /* @__PURE__ */ React2.createElement(Button, {
variant: "outlined",
onClick: onClose,
sx: { mr: 2 }
}, "Cancel"), /* @__PURE__ */ React2.createElement(Button, {
variant: "contained",
onClick: handleSubmit
}, type === "update" ? "Update" : "Create")));
};
// src/component/RegistryTable.tsx
import React3 from "react";
import DeleteIcon from "@mui/icons-material/Delete";
import EditIcon from "@mui/icons-material/Edit";
import { IconButton, Paper as Paper2, Table, TableBody, TableCell, TableContainer, TableHead, TablePagination, TableRow } from "@mui/material";
import TableSortLabel from "@mui/material/TableSortLabel";
import {
findIdField as findIdField2,
formatIdName as formatIdName2,
resolveId,
resolveValue,
useRegistryEntityContext,
useRegistrySort
} from "@croz/nrich-registry-core";
var RegistryTableHeadCell = ({ property, sortPropertyList, onSortChange }) => {
const {
sortDirection,
sortChangeHandler
} = useRegistrySort(property, sortPropertyList, onSortChange);
const muiSortDirection = sortDirection === void 0 ? false : sortDirection.toLowerCase();
return /* @__PURE__ */ React3.createElement(TableCell, {
key: property.name,
sortDirection: muiSortDirection
}, /* @__PURE__ */ React3.createElement(TableSortLabel, {
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 = findIdField2(configuration);
stringValue = formatIdName2(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__ */ React3.createElement(TableCell, null, stringValue);
};
var RegistryTableRow = ({
row,
onEdit,
onRemove
}) => {
const { entityConfiguration, singularAssociationsMap, finalProperties } = useRegistryEntityContext();
return /* @__PURE__ */ React3.createElement(TableRow, {
sx: { "&:last-child td, &:last-child th": { border: 0 } }
}, finalProperties.map((property) => /* @__PURE__ */ React3.createElement(PropertyCell, {
key: property.name,
propertyConfiguration: property,
value: resolveValue(property, row),
subEntityMap: singularAssociationsMap
})), (entityConfiguration.updateable || entityConfiguration.deletable) && /* @__PURE__ */ React3.createElement(TableCell, null, entityConfiguration.updateable && /* @__PURE__ */ React3.createElement(IconButton, {
onClick: () => onEdit(resolveId(entityConfiguration, row), row)
}, /* @__PURE__ */ React3.createElement(EditIcon, null)), entityConfiguration.deletable && /* @__PURE__ */ React3.createElement(IconButton, {
onClick: () => onRemove(resolveId(entityConfiguration, row))
}, /* @__PURE__ */ React3.createElement(DeleteIcon, null))));
};
var RegistryTable = ({
data,
request,
onRequestChange,
onEdit,
onRemove
}) => {
var _a;
const { entityConfiguration, finalProperties } = 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__ */ React3.createElement(Paper2, null, /* @__PURE__ */ React3.createElement(TableContainer, null, /* @__PURE__ */ React3.createElement(Table, {
sx: { minWidth: 650 },
size: "small"
}, /* @__PURE__ */ React3.createElement(TableHead, null, /* @__PURE__ */ React3.createElement(TableRow, null, finalProperties.map((property) => {
var _a2;
return /* @__PURE__ */ React3.createElement(RegistryTableHeadCell, {
key: property.name,
property,
sortPropertyList: (_a2 = request.sortPropertyList) != null ? _a2 : [],
onSortChange
});
}), (entityConfiguration.updateable || entityConfiguration.deletable) && /* @__PURE__ */ React3.createElement(TableCell, null))), /* @__PURE__ */ React3.createElement(TableBody, null, ((_a = data.content) != null ? _a : []).map((row, index) => /* @__PURE__ */ React3.createElement(RegistryTableRow, {
key: index,
row,
onEdit,
onRemove
}))))), /* @__PURE__ */ React3.createElement(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
} = useRegistryEntityAdministration(entityName);
return /* @__PURE__ */ React4.createElement(RegistryEntityContextProvider, {
entityConfiguration
}, /* @__PURE__ */ React4.createElement(Paper3, {
sx: {
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center"
}
}, /* @__PURE__ */ React4.createElement(RegistryFilter, {
onFilterUpdate: handleFilterUpdate
}), /* @__PURE__ */ React4.createElement("div", null, entityConfiguration.creatable && /* @__PURE__ */ React4.createElement(Button2, {
variant: "contained",
onClick: handleAddClick
}, "Add"))), /* @__PURE__ */ React4.createElement(RegistryTable, {
data,
request,
onRequestChange: handlePagingUpdate,
onEdit: handleEditClick,
onRemove: remove
}), formModalOpen && /* @__PURE__ */ React4.createElement(Modal, {
open: formModalOpen,
onClose: (_, reason) => reason !== "backdropClick" && closeFormModal()
}, /* @__PURE__ */ React4.createElement(Box2, {
sx: modalStyle
}, /* @__PURE__ */ React4.createElement(RegistryForm, {
type: formType,
initialValues: formData,
onClose: closeFormModal,
onSubmit: handleSubmitClick
}))), loading && /* @__PURE__ */ React4.createElement(Backdrop, {
sx: { color: "#fff", zIndex: (theme) => theme.zIndex.drawer + 1 },
open: true
}, /* @__PURE__ */ React4.createElement(CircularProgress, {
color: "inherit"
})));
};
// src/component/RegistryEntityPicker.tsx
import React5 from "react";
import {
FormControl as FormControl3,
InputLabel as InputLabel3,
MenuItem as MenuItem3,
OutlinedInput as OutlinedInput3,
Select as Select3
} from "@mui/material";
import { useRegistryConfigurationStore } from "@croz/nrich-registry-core";
var RegistryEntityPicker = ({ value, setValue }) => {
const entityConfigurations = useRegistryConfigurationStore((state) => state.groupConfigurations.flatMap((groupConfiguration) => groupConfiguration.entityConfigurationList));
return /* @__PURE__ */ React5.createElement(FormControl3, {
sx: { m: 1, width: 300 },
size: "small"
}, /* @__PURE__ */ React5.createElement(InputLabel3, {
id: "registry-entity-picker-label"
}, "Entity"), /* @__PURE__ */ React5.createElement(Select3, {
labelId: "registry-entity-picker-label",
id: "registry-entity-picker",
label: "Entity",
value,
onChange: (event) => setValue(event.target.value),
input: /* @__PURE__ */ React5.createElement(OutlinedInput3, null)
}, entityConfigurations.map((entity) => /* @__PURE__ */ React5.createElement(MenuItem3, {
key: entity.name,
value: entity.name
}, entity.name))));
};
export {
RegistryEntity,
RegistryEntityPicker,
RegistryFilter,
RegistryForm,
RegistryTable
};
//# sourceMappingURL=index.mjs.map