UNPKG

@croz/nrich-registry-core

Version:

Contains core utilities related to the nrich-registry module

622 lines (604 loc) 23.7 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, { DEFAULT_INITIAL_REQUEST: () => DEFAULT_INITIAL_REQUEST, RegistryEntityContext: () => RegistryEntityContext, RegistryEntityContextProvider: () => RegistryEntityContextProvider, RegistryProvider: () => RegistryProvider, bulkLoadEntities: () => bulkLoadEntities, createEntity: () => createEntity, findIdField: () => findIdField, formatIdName: () => formatIdName, loadEntities: () => loadEntities, loadRegistryConfiguration: () => loadRegistryConfiguration, removeEntity: () => removeEntity, resolveId: () => resolveId, resolveValue: () => resolveValue, restructureSubmitValue: () => restructureSubmitValue, updateEntity: () => updateEntity, useDebouncedUpdateEffect: () => useDebouncedUpdateEffect, useRegistryConfigurationStore: () => useRegistryConfigurationStore, useRegistryEntity: () => useRegistryEntity, useRegistryEntityAdministration: () => useRegistryEntityAdministration, useRegistryEntityContext: () => useRegistryEntityContext, useRegistryEntityYupFormConfiguration: () => useRegistryEntityYupFormConfiguration, useRegistryFilter: () => useRegistryFilter, useRegistryForm: () => useRegistryForm, useRegistrySort: () => useRegistrySort, useUpdateEffect: () => useUpdateEffect }); module.exports = __toCommonJS(src_exports); // src/component/RegistryEntityContext.tsx var import_react = __toESM(require("react")); // src/store/registry-configuration-store.ts var import_zustand = __toESM(require("zustand")); var useRegistryConfigurationStore = (0, import_zustand.default)((set) => ({ groupConfigurations: [], load: (groupConfigurations) => set(() => ({ groupConfigurations })), entityFormatters: {}, setEntityFormatters: (entityFormatters) => set(() => ({ entityFormatters })), registryConfiguration: {}, setRegistryConfiguration: (registryConfiguration) => set(() => ({ registryConfiguration })) })); // src/component/RegistryEntityContext.tsx var RegistryEntityContext = import_react.default.createContext(void 0); var useRegistryEntityContext = () => { const context = (0, import_react.useContext)(RegistryEntityContext); if (!context) { throw new Error("Cannot use RegistryEntityContext without RegistryEntityContextProvider!"); } return context; }; var RegistryEntityContextProvider = ({ entityConfiguration, children }) => { const entityConfigurations = useRegistryConfigurationStore((state) => state.groupConfigurations.flatMap((groupConfiguration) => groupConfiguration.entityConfigurationList)); const singularAssociationsMap = import_react.default.useMemo(() => { const singularAssociations = [...entityConfiguration.propertyConfigurationList, ...entityConfiguration.embeddedIdPropertyConfigurationList].filter((property) => property.singularAssociation).map((property) => property.singularAssociationReferencedClass); return singularAssociations.reduce( (all, current) => __spreadProps(__spreadValues({}, all), { [current]: entityConfigurations.find((configuration) => configuration.classFullName === current) }), {} ); }, [entityConfiguration]); const finalProperties = import_react.default.useMemo(() => { if (entityConfiguration.embeddedIdentity) { return entityConfiguration.propertyConfigurationList.flatMap((property) => { if (property.id) { return entityConfiguration.embeddedIdPropertyConfigurationList; } return property; }); } return entityConfiguration.propertyConfigurationList; }, [entityConfiguration]); const value = import_react.default.useMemo(() => ({ entityConfiguration, finalProperties, singularAssociationsMap }), [entityConfiguration]); return /* @__PURE__ */ import_react.default.createElement(RegistryEntityContext.Provider, { value }, children); }; // src/component/RegistryProvider.tsx var import_react2 = __toESM(require("react")); // src/service/service.ts var loadRegistryConfiguration = () => __async(void 0, null, function* () { var _a; const { registryConfiguration } = useRegistryConfigurationStore.getState(); const additionalOptions = ((_a = registryConfiguration.requestOptionsResolver) == null ? void 0 : _a.call(registryConfiguration)) || {}; const finalBaseUrl = registryConfiguration.baseURL || "/nrich/registry"; const response = yield fetch(`${finalBaseUrl}/configuration/fetch`, __spreadValues({ method: "POST" }, additionalOptions)); const data = yield response.json(); return data; }); var loadEntities = (request) => __async(void 0, null, function* () { var _a; const { registryConfiguration } = useRegistryConfigurationStore.getState(); const additionalOptions = ((_a = registryConfiguration.requestOptionsResolver) == null ? void 0 : _a.call(registryConfiguration)) || {}; const finalBaseUrl = registryConfiguration.baseURL || "/nrich/registry"; const response = yield fetch(`${finalBaseUrl}/data/list`, __spreadValues({ method: "POST", body: JSON.stringify(request), headers: { "Content-Type": "application/json" } }, additionalOptions)); const data = yield response.json(); return data; }); var bulkLoadEntities = (requests) => __async(void 0, null, function* () { var _a; const { registryConfiguration } = useRegistryConfigurationStore.getState(); const additionalOptions = ((_a = registryConfiguration.requestOptionsResolver) == null ? void 0 : _a.call(registryConfiguration)) || {}; const finalBaseUrl = registryConfiguration.baseURL || "/nrich/registry"; const response = yield fetch(`${finalBaseUrl}/data/list-bulk`, __spreadValues({ method: "POST", body: JSON.stringify({ registryRequestList: requests }), headers: { "Content-Type": "application/json" } }, additionalOptions)); const data = yield response.json(); return data; }); var createEntity = (classFullName, createData) => __async(void 0, null, function* () { var _a; const { registryConfiguration } = useRegistryConfigurationStore.getState(); const additionalOptions = ((_a = registryConfiguration.requestOptionsResolver) == null ? void 0 : _a.call(registryConfiguration)) || {}; const finalBaseUrl = registryConfiguration.baseURL || "/nrich/registry"; const response = yield fetch(`${finalBaseUrl}/data/create`, __spreadValues({ method: "POST", body: JSON.stringify({ classFullName, jsonEntityData: JSON.stringify(createData) }), headers: { "Content-Type": "application/json" } }, additionalOptions)); const data = yield response.json(); return data; }); var updateEntity = (classFullName, id, updateData) => __async(void 0, null, function* () { var _a; const { registryConfiguration } = useRegistryConfigurationStore.getState(); const additionalOptions = ((_a = registryConfiguration.requestOptionsResolver) == null ? void 0 : _a.call(registryConfiguration)) || {}; const finalBaseUrl = registryConfiguration.baseURL || "/nrich/registry"; const response = yield fetch(`${finalBaseUrl}/data/update`, __spreadValues({ method: "POST", body: JSON.stringify({ classFullName, id, jsonEntityData: JSON.stringify(updateData) }), headers: { "Content-Type": "application/json" } }, additionalOptions)); const data = yield response.json(); return data; }); var removeEntity = (classFullName, id) => __async(void 0, null, function* () { var _a; const { registryConfiguration } = useRegistryConfigurationStore.getState(); const additionalOptions = ((_a = registryConfiguration.requestOptionsResolver) == null ? void 0 : _a.call(registryConfiguration)) || {}; const finalBaseUrl = registryConfiguration.baseURL || "/nrich/registry"; const response = yield fetch(`${finalBaseUrl}/data/delete`, __spreadValues({ method: "POST", body: JSON.stringify({ classFullName, id }), headers: { "Content-Type": "application/json" } }, additionalOptions)); return response; }); // src/component/RegistryProvider.tsx var RegistryProvider = ({ children, registryConfiguration = {}, entityFormatters = {} }) => { const { load, setRegistryConfiguration, setEntityFormatters } = useRegistryConfigurationStore(); const [loading, setLoading] = import_react2.default.useState(true); import_react2.default.useEffect(() => { const loadConfiguration = () => __async(void 0, null, function* () { setRegistryConfiguration(__spreadValues({}, registryConfiguration)); setEntityFormatters(entityFormatters); const configuration = yield loadRegistryConfiguration(); load(configuration); setLoading(false); }); loadConfiguration(); }, []); if (loading) { return /* @__PURE__ */ import_react2.default.createElement("div", null, "Loading..."); } return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, children); }; // src/hook/use-registry-entity.ts var import_react3 = __toESM(require("react")); // src/hook/use-entity-configuration.ts var useEntityConfiguration = (name) => { const entityConfiguration = useRegistryConfigurationStore((state) => state.groupConfigurations.flatMap((groupConfiguration) => groupConfiguration.entityConfigurationList).find((configuration) => configuration.name === name || configuration.classFullName === name)); if (entityConfiguration === void 0) { return void 0; } const entityIdProperty = entityConfiguration.propertyConfigurationList.find((property) => property.id); return { entityConfiguration, entityIdProperty }; }; // src/hook/use-registry-entity.ts var INITIAL_PAGE_SIZE = 25; var DEFAULT_INITIAL_REQUEST = { pageNumber: 0, pageSize: INITIAL_PAGE_SIZE }; var useRegistryEntity = (name, initialRequest = DEFAULT_INITIAL_REQUEST) => { const { entityConfiguration, entityIdProperty } = useEntityConfiguration(name); const [data, setData] = import_react3.default.useState({ content: [], empty: true, first: true, last: true, sort: { sorted: false, unsorted: true }, numberOfElements: 0, totalElements: 0, totalPages: 0 }); const load = (request) => __async(void 0, null, function* () { const loadedData = yield loadEntities(__spreadValues({ classFullName: entityConfiguration.classFullName }, request)); setData(loadedData); }); import_react3.default.useEffect(() => { load(initialRequest); }, []); const add = (createData) => __async(void 0, null, function* () { const response = yield createEntity(entityConfiguration.classFullName, createData); yield load(initialRequest); return response; }); const edit = (id, updateData) => __async(void 0, null, function* () { const response = yield updateEntity(entityConfiguration.classFullName, id, updateData); yield load(initialRequest); return response; }); const remove = (id) => __async(void 0, null, function* () { const response = yield removeEntity(entityConfiguration.classFullName, id); yield load(initialRequest); return response; }); return { entityConfiguration, entityIdProperty, data, load, add, edit, remove }; }; // src/hook/use-registry-entity-administration.ts var import_react5 = __toESM(require("react")); // src/util/registry-entity-utils.ts var resolveId = (entityConfiguration, data) => { if (entityConfiguration.idClassIdentity) { const id = {}; entityConfiguration.idClassPropertyNameList.forEach((property) => { id[property.name] = data[property.name]; }); return id; } const idField = entityConfiguration.propertyConfigurationList.find((property) => property.id === true); return data[idField.name]; }; var resolveValue = (propertyConfiguration, data) => { const fieldPath = propertyConfiguration.name; if (fieldPath.includes(".")) { let current = data; fieldPath.split(".").forEach((fieldPathPart) => { current = current[fieldPathPart]; }); return current; } return data[fieldPath]; }; var restructureSubmitValue = (value) => { const result = {}; Object.keys(value).forEach((key) => { if (key.includes(".")) { let current = result; key.split(".").forEach((fieldPathPart, i, arr) => { var _a; if (i === arr.length - 1) { current[fieldPathPart] = value[key]; } else { current[fieldPathPart] = __spreadValues({}, (_a = current[fieldPathPart]) != null ? _a : {}); current = current[fieldPathPart]; } }); } else { result[key] = value[key]; } }); return result; }; var formatIdName = (classFullName, idFieldName, id) => `${classFullName.split(".").pop()}[${idFieldName}=${id}]`; var findIdField = (entityConfiguration) => entityConfiguration.propertyConfigurationList.find((property) => property.id); // src/hook/use-update-effect.ts var import_react4 = __toESM(require("react")); var useUpdateEffect = (effect, dependencies) => { const firstRender = import_react4.default.useRef(true); import_react4.default.useEffect(() => { firstRender.current = true; }, []); import_react4.default.useEffect(() => { if (!firstRender.current) { return effect(); } firstRender.current = false; return void 0; }, dependencies); }; var useDebouncedUpdateEffect = (effect, debounceTime, dependencies) => { const firstRender = import_react4.default.useRef(true); const timeoutRef = import_react4.default.useRef(null); const clearTimeout = () => window.clearTimeout(timeoutRef.current); import_react4.default.useEffect(() => { firstRender.current = true; clearTimeout(); }, []); import_react4.default.useEffect(() => { clearTimeout(); if (!firstRender.current) { timeoutRef.current = setTimeout(() => { effect(); }, debounceTime); } firstRender.current = false; }, dependencies); }; // src/hook/use-registry-entity-administration.ts var useRegistryEntityAdministration = (entityName) => { const [request, setRequest] = import_react5.default.useState(DEFAULT_INITIAL_REQUEST); const registryEntity = useRegistryEntity(entityName, request); const [formModalOpen, setFormModalOpen] = import_react5.default.useState(false); const [formType, setFormType] = import_react5.default.useState(void 0); const [formData, setFormData] = import_react5.default.useState(); const [loading, setLoading] = import_react5.default.useState(false); const { entityConfiguration, entityIdProperty, data, add, edit, remove } = registryEntity; const handlePagingUpdate = (newPagingRequest) => __async(void 0, null, function* () { setRequest((oldRequest) => __spreadValues(__spreadValues({}, oldRequest), newPagingRequest)); }); const handleFilterUpdate = (searchParameter) => __async(void 0, null, function* () { setRequest((oldRequest) => __spreadProps(__spreadValues({}, oldRequest), { pageNumber: 0, searchParameter })); }); useUpdateEffect(() => { const reload = () => __async(void 0, null, function* () { setLoading(true); yield registryEntity.load(request); setLoading(false); }); reload(); }, [request]); const handleAddClick = () => { setFormModalOpen(true); setFormType("create"); setFormData(void 0); }; const handleAddFromCopyClick = (row) => { setFormModalOpen(true); setFormType("create"); setFormData(row); }; const handleEditClick = (id, row) => { setFormModalOpen(true); setFormType("update"); setFormData(row); }; const handlePreviewClick = (row) => { setFormModalOpen(true); setFormType("preview"); setFormData(row); }; const handleSubmitClick = (values) => __async(void 0, null, function* () { const finalValue = restructureSubmitValue(values); let actionResponse; setFormModalOpen(false); setLoading(true); if (formType === "update") { actionResponse = yield edit(formData[entityIdProperty.name], finalValue); } else { actionResponse = yield add(finalValue); } setLoading(false); setFormType(void 0); setFormData(void 0); return actionResponse; }); const closeFormModal = () => { setFormModalOpen(false); setFormType(void 0); setFormData(void 0); }; return { entityConfiguration, entityIdProperty, data, request, handlePagingUpdate, handleFilterUpdate, handleAddClick, handleAddFromCopyClick, handleEditClick, handlePreviewClick, handleSubmitClick, formType, formData, formModalOpen, closeFormModal, loading, remove }; }; // src/hook/use-registry-entity-form-configuration.ts var import_nrich_form_configuration_core = require("@croz/nrich-form-configuration-core"); var useRegistryEntityYupFormConfiguration = (classFullName, type) => (0, import_nrich_form_configuration_core.useYupFormConfiguration)(`${classFullName}:::${type}`); // src/hook/use-registry-filter.ts var import_react6 = __toESM(require("react")); var INITIAL_FILTER_VALUE = { query: "", propertyNameList: [] }; var useRegistryFilter = (initialFilterValue = INITIAL_FILTER_VALUE) => { const { finalProperties } = import_react6.default.useContext(RegistryEntityContext); const [searchParameter, setSearchParameter] = import_react6.default.useState(initialFilterValue); const handleFieldsChange = (event) => { const { value } = event.target; const newValue = typeof value === "string" ? value.split(",") : value; setSearchParameter((oldSearchParameter) => __spreadProps(__spreadValues({}, oldSearchParameter), { propertyNameList: newValue })); }; const handleQueryChange = (event) => { const { value } = event.target; setSearchParameter((oldSearchParameter) => __spreadProps(__spreadValues({}, oldSearchParameter), { query: value })); }; const availableFields = import_react6.default.useMemo( () => finalProperties.filter((property) => property.searchable).map((property) => ({ value: property.name, label: property.columnHeader })), [finalProperties] ); return { availableFields, searchParameter, handleFieldsChange, handleQueryChange }; }; // src/hook/use-registry-form.ts var import_react7 = __toESM(require("react")); var useRegistryForm = (initialValues, type) => { const { entityConfiguration, finalProperties } = import_react7.default.useContext(RegistryEntityContext); const yupSchema = useRegistryEntityYupFormConfiguration(entityConfiguration.classFullName, type); const finalInitialValues = import_react7.default.useMemo(() => { if (initialValues === void 0) { const values2 = {}; finalProperties.forEach((property) => { values2[property.name] = null; }); return values2; } const values = {}; finalProperties.forEach((property) => { values[property.name] = resolveValue(property, initialValues); }); return values; }, [initialValues]); const properties = type === "update" ? finalProperties : finalProperties.filter((property) => property.editable); return { entityConfiguration, yupSchema, finalInitialValues, properties }; }; // src/hook/use-registry-sort.ts var import_react8 = __toESM(require("react")); var useRegistrySort = (propertyConfiguration, value, onChange, allowMultiple = true) => { const sortDirection = import_react8.default.useMemo(() => { const sortProperty = value.find((pagingRequestSortProperty) => pagingRequestSortProperty.property === propertyConfiguration.name); if (sortProperty === void 0) { return void 0; } return sortProperty.direction; }, [propertyConfiguration, value]); const sortChangeHandler = () => { const sortProperty = value.find((pagingRequestSortProperty) => pagingRequestSortProperty.property === propertyConfiguration.name); if (sortProperty === void 0) { onChange([ ...allowMultiple ? value : [], { property: propertyConfiguration.name, direction: "ASC" } ]); } else if (sortProperty.direction === "ASC") { onChange(value.map((pagingRequestSortProperty) => { if (pagingRequestSortProperty.property === propertyConfiguration.name) { return __spreadProps(__spreadValues({}, pagingRequestSortProperty), { direction: "DESC" }); } return pagingRequestSortProperty; })); } else { onChange(value.filter((pagingRequestSortProperty) => pagingRequestSortProperty.property !== propertyConfiguration.name)); } }; return { sortDirection, sortChangeHandler }; }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { DEFAULT_INITIAL_REQUEST, RegistryEntityContext, RegistryEntityContextProvider, RegistryProvider, bulkLoadEntities, createEntity, findIdField, formatIdName, loadEntities, loadRegistryConfiguration, removeEntity, resolveId, resolveValue, restructureSubmitValue, updateEntity, useDebouncedUpdateEffect, useRegistryConfigurationStore, useRegistryEntity, useRegistryEntityAdministration, useRegistryEntityContext, useRegistryEntityYupFormConfiguration, useRegistryFilter, useRegistryForm, useRegistrySort, useUpdateEffect }); //# sourceMappingURL=index.js.map