@beinformed/ui 1.65.27 → 1.65.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [1.65.28](https://git.beinformed.com/public/nl.beinformed.bi.layout.lib.ui/compare/v1.65.27...v1.65.28) (2026-02-02)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * **hooks:** ensure `removeOnUnmount` is respected in `useModularUIModel` ([3f28a63](https://git.beinformed.com/public/nl.beinformed.bi.layout.lib.ui/commit/3f28a63d5f0d8898a9a59a98d66869ed6cba2fa6))
11
+
5
12
  ## [1.65.27](https://git.beinformed.com/public/nl.beinformed.bi.layout.lib.ui/compare/v1.65.26...v1.65.27) (2026-01-31)
6
13
 
7
14
 
@@ -40,7 +40,7 @@ export const useModularUI = (modelKey, url, options = {}) => {
40
40
  const requestOptions = useMemo(() => {
41
41
  const merged = {
42
42
  method: HTTP_METHODS.GET,
43
- removeOnUnmount: false,
43
+ removeOnUnmount: true,
44
44
  ...options
45
45
  };
46
46
  if (url instanceof Href) {
@@ -55,7 +55,7 @@ export const useModularUI = (
55
55
  const requestOptions = useMemo(() => {
56
56
  const merged = {
57
57
  method: HTTP_METHODS.GET,
58
- removeOnUnmount: false,
58
+ removeOnUnmount: true,
59
59
  ...options,
60
60
  };
61
61
 
@@ -1 +1 @@
1
- {"version":3,"file":"useModularUI.js","names":["useEffect","useMemo","useRef","useDispatch","useSelector","useLocation","HTTP_METHODS","MODULARUI_STATUS","loadModularUI","removeModelByKey","useDeepCompareEffect","useModularUIKey","Href","useModularUI","modelKey","url","options","dispatch","hrefInstance","requestUrl","toString","currentQueryString","querystring","prevQueryRef","key","model","state","modularui","requestOptions","merged","method","GET","removeOnUnmount","origin","contextPath","location","redirectLocation","shouldLoad","status","ERROR","current","equals","isReload"],"sources":["../../src/hooks/useModularUI.js"],"sourcesContent":["// @flow\nimport { useEffect, useMemo, useRef } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { useLocation } from \"react-router\";\n\nimport { HTTP_METHODS, MODULARUI_STATUS } from \"../constants\";\nimport {\n loadModularUI,\n removeModelByKey,\n} from \"../redux/_modularui/ModularUIActions\";\n\nimport useDeepCompareEffect from \"./useDeepCompareEffect\";\nimport { useModularUIKey } from \"./useModularUIKey\";\n\nimport Href from \"../models/href/Href\";\n\nimport type { RequestModularUIOptions } from \"../utils\";\nimport type { ModelEntry } from \"../redux\";\n\n/**\n * A custom hook to fetch and manage Be Informed modular UI resources.\n * It handles automatic data fetching based on URL/query changes, manages Redux state\n * synchronization, and provides cleanup logic when components unmount.\n *\n * @param {string} modelKey - A unique identifier for the type of model being fetched.\n * @param {string | Href} url - The endpoint URL or Href instance to fetch data from.\n * @param {RequestModularUIOptions} options - Configuration for the request (method, headers, etc.).\n * @returns {ModelEntry} The model data retrieved from the Redux store.\n */\nexport const useModularUI = (\n modelKey: string,\n url: string | Href,\n options: RequestModularUIOptions = (({}: any): RequestModularUIOptions),\n): any => {\n const dispatch = useDispatch();\n\n // Normalize the URL input into a Href instance to safely access query params and paths\n const hrefInstance = useMemo(() => new Href(url), [url]);\n const requestUrl = useMemo(() => hrefInstance.toString(), [hrefInstance]);\n const currentQueryString = hrefInstance.querystring;\n\n // Persistence ref to detect if query parameters have changed between renders\n const prevQueryRef = useRef(currentQueryString);\n\n // Generate a unique key for the Redux store based on the model type and the full URL\n const key = useModularUIKey(modelKey, requestUrl);\n\n // Select the specific piece of state corresponding to this modular UI component\n const model = useSelector((state) => state.modularui[key]);\n\n /**\n * Memoize request options to prevent unnecessary re-renders.\n * Merges default settings (GET method, auto-cleanup) with user-provided options.\n */\n const requestOptions = useMemo(() => {\n const merged = {\n method: HTTP_METHODS.GET,\n removeOnUnmount: false,\n ...options,\n };\n\n if (url instanceof Href) {\n merged.origin = merged.origin ?? url.origin;\n merged.contextPath = merged.contextPath ?? url.contextPath;\n }\n return merged;\n }, [options, url]);\n\n const location = useLocation();\n const redirectLocation = location.state?.redirectLocation;\n\n /**\n * Determines if a network request should be initiated.\n * Logic includes:\n * - Model doesn't exist yet (Initial load)\n * - Previous request resulted in an error (Retry)\n * - The query parameters changed (Filtering/Paging)\n * - A redirect was triggered specifically for this URL\n * - Manual 'isReload' flag is passed in options\n */\n const shouldLoad =\n model == null ||\n model.status === MODULARUI_STATUS.ERROR ||\n prevQueryRef.current !== currentQueryString ||\n (redirectLocation instanceof Href\n ? redirectLocation.equals(requestUrl)\n : false) ||\n requestOptions.isReload === true;\n\n // Synchronize the ref after the render cycle determines if we should load\n useEffect(() => {\n prevQueryRef.current = currentQueryString;\n }, [currentQueryString]);\n\n // Execute the load action. Deep compare is used on options to prevent\n // infinite loops caused by passing inline object literals.\n useDeepCompareEffect(() => {\n if (requestUrl !== \"\" && shouldLoad) {\n dispatch(loadModularUI(key, requestUrl, requestOptions));\n }\n }, [key, requestUrl, requestOptions, shouldLoad]);\n\n // Cleanup Effect:\n // If 'removeOnUnmount' is true, this removes the model data from the Redux store\n // when the component using this hook is destroyed.\n useEffect(() => {\n if (requestOptions.removeOnUnmount) {\n return () => {\n dispatch(removeModelByKey(key));\n };\n }\n }, [dispatch, key, requestOptions.removeOnUnmount]);\n\n return model;\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"useModularUI.js","names":["useEffect","useMemo","useRef","useDispatch","useSelector","useLocation","HTTP_METHODS","MODULARUI_STATUS","loadModularUI","removeModelByKey","useDeepCompareEffect","useModularUIKey","Href","useModularUI","modelKey","url","options","dispatch","hrefInstance","requestUrl","toString","currentQueryString","querystring","prevQueryRef","key","model","state","modularui","requestOptions","merged","method","GET","removeOnUnmount","origin","contextPath","location","redirectLocation","shouldLoad","status","ERROR","current","equals","isReload"],"sources":["../../src/hooks/useModularUI.js"],"sourcesContent":["// @flow\nimport { useEffect, useMemo, useRef } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { useLocation } from \"react-router\";\n\nimport { HTTP_METHODS, MODULARUI_STATUS } from \"../constants\";\nimport {\n loadModularUI,\n removeModelByKey,\n} from \"../redux/_modularui/ModularUIActions\";\n\nimport useDeepCompareEffect from \"./useDeepCompareEffect\";\nimport { useModularUIKey } from \"./useModularUIKey\";\n\nimport Href from \"../models/href/Href\";\n\nimport type { RequestModularUIOptions } from \"../utils\";\nimport type { ModelEntry } from \"../redux\";\n\n/**\n * A custom hook to fetch and manage Be Informed modular UI resources.\n * It handles automatic data fetching based on URL/query changes, manages Redux state\n * synchronization, and provides cleanup logic when components unmount.\n *\n * @param {string} modelKey - A unique identifier for the type of model being fetched.\n * @param {string | Href} url - The endpoint URL or Href instance to fetch data from.\n * @param {RequestModularUIOptions} options - Configuration for the request (method, headers, etc.).\n * @returns {ModelEntry} The model data retrieved from the Redux store.\n */\nexport const useModularUI = (\n modelKey: string,\n url: string | Href,\n options: RequestModularUIOptions = (({}: any): RequestModularUIOptions),\n): any => {\n const dispatch = useDispatch();\n\n // Normalize the URL input into a Href instance to safely access query params and paths\n const hrefInstance = useMemo(() => new Href(url), [url]);\n const requestUrl = useMemo(() => hrefInstance.toString(), [hrefInstance]);\n const currentQueryString = hrefInstance.querystring;\n\n // Persistence ref to detect if query parameters have changed between renders\n const prevQueryRef = useRef(currentQueryString);\n\n // Generate a unique key for the Redux store based on the model type and the full URL\n const key = useModularUIKey(modelKey, requestUrl);\n\n // Select the specific piece of state corresponding to this modular UI component\n const model = useSelector((state) => state.modularui[key]);\n\n /**\n * Memoize request options to prevent unnecessary re-renders.\n * Merges default settings (GET method, auto-cleanup) with user-provided options.\n */\n const requestOptions = useMemo(() => {\n const merged = {\n method: HTTP_METHODS.GET,\n removeOnUnmount: true,\n ...options,\n };\n\n if (url instanceof Href) {\n merged.origin = merged.origin ?? url.origin;\n merged.contextPath = merged.contextPath ?? url.contextPath;\n }\n return merged;\n }, [options, url]);\n\n const location = useLocation();\n const redirectLocation = location.state?.redirectLocation;\n\n /**\n * Determines if a network request should be initiated.\n * Logic includes:\n * - Model doesn't exist yet (Initial load)\n * - Previous request resulted in an error (Retry)\n * - The query parameters changed (Filtering/Paging)\n * - A redirect was triggered specifically for this URL\n * - Manual 'isReload' flag is passed in options\n */\n const shouldLoad =\n model == null ||\n model.status === MODULARUI_STATUS.ERROR ||\n prevQueryRef.current !== currentQueryString ||\n (redirectLocation instanceof Href\n ? redirectLocation.equals(requestUrl)\n : false) ||\n requestOptions.isReload === true;\n\n // Synchronize the ref after the render cycle determines if we should load\n useEffect(() => {\n prevQueryRef.current = currentQueryString;\n }, [currentQueryString]);\n\n // Execute the load action. Deep compare is used on options to prevent\n // infinite loops caused by passing inline object literals.\n useDeepCompareEffect(() => {\n if (requestUrl !== \"\" && shouldLoad) {\n dispatch(loadModularUI(key, requestUrl, requestOptions));\n }\n }, [key, requestUrl, requestOptions, shouldLoad]);\n\n // Cleanup Effect:\n // If 'removeOnUnmount' is true, this removes the model data from the Redux store\n // when the component using this hook is destroyed.\n useEffect(() => {\n if (requestOptions.removeOnUnmount) {\n return () => {\n dispatch(removeModelByKey(key));\n };\n }\n }, [dispatch, key, requestOptions.removeOnUnmount]);\n\n return model;\n};\n"],"mappings":"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","ignoreList":[]}
@@ -11,6 +11,7 @@ import { useModularUIBasic } from "./useModularUIBasic";
11
11
  export const useApplication = options => useModularUIBasic("application", "/", {
12
12
  expectedModels: ["Application"],
13
13
  targetModel: ApplicationModel,
14
+ removeOnUnmount: options?.removeOnUnmount ?? false,
14
15
  ...options
15
16
  });
16
17
 
@@ -20,6 +20,7 @@ export const useApplication = (
20
20
  useModularUIBasic("application", "/", {
21
21
  expectedModels: ["Application"],
22
22
  targetModel: ApplicationModel,
23
+ removeOnUnmount: options?.removeOnUnmount ?? false,
23
24
  ...options,
24
25
  });
25
26
 
@@ -1 +1 @@
1
- {"version":3,"file":"useModularUIModel.js","names":["ApplicationModel","CaseViewModel","TabModel","GroupingPanelModel","DetailModel","UserProfileModel","useModularUIBasic","useApplication","options","expectedModels","targetModel","useTab","href","useCaseView","useGroupingPanel","useDetailPanel","useUserProfile"],"sources":["../../src/hooks/useModularUIModel.js"],"sourcesContent":["// @flow\nimport ApplicationModel from \"../models/application/ApplicationModel\";\nimport CaseViewModel from \"../models/caseview/CaseViewModel\";\nimport TabModel from \"../models/tab/TabModel\";\nimport GroupingPanelModel from \"../models/panels/GroupingPanelModel\";\nimport DetailModel from \"../models/detail/DetailModel\";\nimport UserProfileModel from \"../models/user/UserProfileModel\";\n\nimport { useModularUIBasic } from \"./useModularUIBasic\";\n\nimport type Href from \"../models/href/Href\";\nimport type { HookOptions } from \"./useModularUIBasic\";\n\n/**\n * Load application\n */\nexport const useApplication = (\n options?: HookOptions,\n): ApplicationModel | null =>\n useModularUIBasic(\"application\", \"/\", {\n expectedModels: [\"Application\"],\n targetModel: ApplicationModel,\n ...options,\n });\n\n/**\n * Load a tab by href\n */\nexport const useTab = (\n href: string | Href,\n options?: HookOptions,\n): TabModel | null =>\n useModularUIBasic(\"tab\", href, {\n expectedModels: [\"Tab\"],\n targetModel: TabModel,\n ...options,\n });\n\n/**\n * Load caseview by href\n */\nexport const useCaseView = (\n href: string | Href,\n options?: HookOptions,\n): CaseViewModel | null =>\n useModularUIBasic(\"caseview\", href, {\n expectedModels: [\"CaseView\"],\n targetModel: CaseViewModel,\n ...options,\n });\n\n/**\n */\nexport const useGroupingPanel = (\n href: string | Href,\n options?: HookOptions,\n): GroupingPanelModel | null =>\n useModularUIBasic(\"groupingpanel\", href, {\n expectedModels: [\"GroupingPanel\"],\n targetModel: GroupingPanelModel,\n ...options,\n });\n\n/**\n */\nexport const useDetailPanel = (\n href: string | Href,\n options?: HookOptions,\n): DetailModel | null =>\n useModularUIBasic(\"detailpanel\", href, {\n expectedModels: [\"Detail\"],\n targetModel: DetailModel,\n ...options,\n });\n\n/**\n */\nexport const useUserProfile = (\n href: string | Href,\n options?: HookOptions,\n): UserProfileModel | null =>\n useModularUIBasic(\"userprofile\", href, {\n expectedModels: [\"UserProfile\"],\n targetModel: UserProfileModel,\n ...options,\n });\n"],"mappings":"AACA,OAAOA,gBAAgB,MAAM,wCAAwC;AACrE,OAAOC,aAAa,MAAM,kCAAkC;AAC5D,OAAOC,QAAQ,MAAM,wBAAwB;AAC7C,OAAOC,kBAAkB,MAAM,qCAAqC;AACpE,OAAOC,WAAW,MAAM,8BAA8B;AACtD,OAAOC,gBAAgB,MAAM,iCAAiC;AAE9D,SAASC,iBAAiB,QAAQ,qBAAqB;AAKvD;AACA;AACA;AACA,OAAO,MAAMC,cAAc,GACzBC,OAAqB,IAErBF,iBAAiB,CAAC,aAAa,EAAE,GAAG,EAAE;EACpCG,cAAc,EAAE,CAAC,aAAa,CAAC;EAC/BC,WAAW,EAAEV,gBAAgB;EAC7B,GAAGQ;AACL,CAAC,CAAC;;AAEJ;AACA;AACA;AACA,OAAO,MAAMG,MAAM,GAAGA,CACpBC,IAAmB,EACnBJ,OAAqB,KAErBF,iBAAiB,CAAC,KAAK,EAAEM,IAAI,EAAE;EAC7BH,cAAc,EAAE,CAAC,KAAK,CAAC;EACvBC,WAAW,EAAER,QAAQ;EACrB,GAAGM;AACL,CAAC,CAAC;;AAEJ;AACA;AACA;AACA,OAAO,MAAMK,WAAW,GAAGA,CACzBD,IAAmB,EACnBJ,OAAqB,KAErBF,iBAAiB,CAAC,UAAU,EAAEM,IAAI,EAAE;EAClCH,cAAc,EAAE,CAAC,UAAU,CAAC;EAC5BC,WAAW,EAAET,aAAa;EAC1B,GAAGO;AACL,CAAC,CAAC;;AAEJ;AACA;AACA,OAAO,MAAMM,gBAAgB,GAAGA,CAC9BF,IAAmB,EACnBJ,OAAqB,KAErBF,iBAAiB,CAAC,eAAe,EAAEM,IAAI,EAAE;EACvCH,cAAc,EAAE,CAAC,eAAe,CAAC;EACjCC,WAAW,EAAEP,kBAAkB;EAC/B,GAAGK;AACL,CAAC,CAAC;;AAEJ;AACA;AACA,OAAO,MAAMO,cAAc,GAAGA,CAC5BH,IAAmB,EACnBJ,OAAqB,KAErBF,iBAAiB,CAAC,aAAa,EAAEM,IAAI,EAAE;EACrCH,cAAc,EAAE,CAAC,QAAQ,CAAC;EAC1BC,WAAW,EAAEN,WAAW;EACxB,GAAGI;AACL,CAAC,CAAC;;AAEJ;AACA;AACA,OAAO,MAAMQ,cAAc,GAAGA,CAC5BJ,IAAmB,EACnBJ,OAAqB,KAErBF,iBAAiB,CAAC,aAAa,EAAEM,IAAI,EAAE;EACrCH,cAAc,EAAE,CAAC,aAAa,CAAC;EAC/BC,WAAW,EAAEL,gBAAgB;EAC7B,GAAGG;AACL,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"useModularUIModel.js","names":["ApplicationModel","CaseViewModel","TabModel","GroupingPanelModel","DetailModel","UserProfileModel","useModularUIBasic","useApplication","options","expectedModels","targetModel","removeOnUnmount","useTab","href","useCaseView","useGroupingPanel","useDetailPanel","useUserProfile"],"sources":["../../src/hooks/useModularUIModel.js"],"sourcesContent":["// @flow\nimport ApplicationModel from \"../models/application/ApplicationModel\";\nimport CaseViewModel from \"../models/caseview/CaseViewModel\";\nimport TabModel from \"../models/tab/TabModel\";\nimport GroupingPanelModel from \"../models/panels/GroupingPanelModel\";\nimport DetailModel from \"../models/detail/DetailModel\";\nimport UserProfileModel from \"../models/user/UserProfileModel\";\n\nimport { useModularUIBasic } from \"./useModularUIBasic\";\n\nimport type Href from \"../models/href/Href\";\nimport type { HookOptions } from \"./useModularUIBasic\";\n\n/**\n * Load application\n */\nexport const useApplication = (\n options?: HookOptions,\n): ApplicationModel | null =>\n useModularUIBasic(\"application\", \"/\", {\n expectedModels: [\"Application\"],\n targetModel: ApplicationModel,\n removeOnUnmount: options?.removeOnUnmount ?? false,\n ...options,\n });\n\n/**\n * Load a tab by href\n */\nexport const useTab = (\n href: string | Href,\n options?: HookOptions,\n): TabModel | null =>\n useModularUIBasic(\"tab\", href, {\n expectedModels: [\"Tab\"],\n targetModel: TabModel,\n ...options,\n });\n\n/**\n * Load caseview by href\n */\nexport const useCaseView = (\n href: string | Href,\n options?: HookOptions,\n): CaseViewModel | null =>\n useModularUIBasic(\"caseview\", href, {\n expectedModels: [\"CaseView\"],\n targetModel: CaseViewModel,\n ...options,\n });\n\n/**\n */\nexport const useGroupingPanel = (\n href: string | Href,\n options?: HookOptions,\n): GroupingPanelModel | null =>\n useModularUIBasic(\"groupingpanel\", href, {\n expectedModels: [\"GroupingPanel\"],\n targetModel: GroupingPanelModel,\n ...options,\n });\n\n/**\n */\nexport const useDetailPanel = (\n href: string | Href,\n options?: HookOptions,\n): DetailModel | null =>\n useModularUIBasic(\"detailpanel\", href, {\n expectedModels: [\"Detail\"],\n targetModel: DetailModel,\n ...options,\n });\n\n/**\n */\nexport const useUserProfile = (\n href: string | Href,\n options?: HookOptions,\n): UserProfileModel | null =>\n useModularUIBasic(\"userprofile\", href, {\n expectedModels: [\"UserProfile\"],\n targetModel: UserProfileModel,\n ...options,\n });\n"],"mappings":"AACA,OAAOA,gBAAgB,MAAM,wCAAwC;AACrE,OAAOC,aAAa,MAAM,kCAAkC;AAC5D,OAAOC,QAAQ,MAAM,wBAAwB;AAC7C,OAAOC,kBAAkB,MAAM,qCAAqC;AACpE,OAAOC,WAAW,MAAM,8BAA8B;AACtD,OAAOC,gBAAgB,MAAM,iCAAiC;AAE9D,SAASC,iBAAiB,QAAQ,qBAAqB;AAKvD;AACA;AACA;AACA,OAAO,MAAMC,cAAc,GACzBC,OAAqB,IAErBF,iBAAiB,CAAC,aAAa,EAAE,GAAG,EAAE;EACpCG,cAAc,EAAE,CAAC,aAAa,CAAC;EAC/BC,WAAW,EAAEV,gBAAgB;EAC7BW,eAAe,EAAEH,OAAO,EAAEG,eAAe,IAAI,KAAK;EAClD,GAAGH;AACL,CAAC,CAAC;;AAEJ;AACA;AACA;AACA,OAAO,MAAMI,MAAM,GAAGA,CACpBC,IAAmB,EACnBL,OAAqB,KAErBF,iBAAiB,CAAC,KAAK,EAAEO,IAAI,EAAE;EAC7BJ,cAAc,EAAE,CAAC,KAAK,CAAC;EACvBC,WAAW,EAAER,QAAQ;EACrB,GAAGM;AACL,CAAC,CAAC;;AAEJ;AACA;AACA;AACA,OAAO,MAAMM,WAAW,GAAGA,CACzBD,IAAmB,EACnBL,OAAqB,KAErBF,iBAAiB,CAAC,UAAU,EAAEO,IAAI,EAAE;EAClCJ,cAAc,EAAE,CAAC,UAAU,CAAC;EAC5BC,WAAW,EAAET,aAAa;EAC1B,GAAGO;AACL,CAAC,CAAC;;AAEJ;AACA;AACA,OAAO,MAAMO,gBAAgB,GAAGA,CAC9BF,IAAmB,EACnBL,OAAqB,KAErBF,iBAAiB,CAAC,eAAe,EAAEO,IAAI,EAAE;EACvCJ,cAAc,EAAE,CAAC,eAAe,CAAC;EACjCC,WAAW,EAAEP,kBAAkB;EAC/B,GAAGK;AACL,CAAC,CAAC;;AAEJ;AACA;AACA,OAAO,MAAMQ,cAAc,GAAGA,CAC5BH,IAAmB,EACnBL,OAAqB,KAErBF,iBAAiB,CAAC,aAAa,EAAEO,IAAI,EAAE;EACrCJ,cAAc,EAAE,CAAC,QAAQ,CAAC;EAC1BC,WAAW,EAAEN,WAAW;EACxB,GAAGI;AACL,CAAC,CAAC;;AAEJ;AACA;AACA,OAAO,MAAMS,cAAc,GAAGA,CAC5BJ,IAAmB,EACnBL,OAAqB,KAErBF,iBAAiB,CAAC,aAAa,EAAEO,IAAI,EAAE;EACrCJ,cAAc,EAAE,CAAC,aAAa,CAAC;EAC/BC,WAAW,EAAEL,gBAAgB;EAC7B,GAAGG;AACL,CAAC,CAAC","ignoreList":[]}
@@ -47,7 +47,7 @@ const useModularUI = (modelKey, url, options = {}) => {
47
47
  const requestOptions = (0, _react.useMemo)(() => {
48
48
  const merged = {
49
49
  method: _constants.HTTP_METHODS.GET,
50
- removeOnUnmount: false,
50
+ removeOnUnmount: true,
51
51
  ...options
52
52
  };
53
53
  if (url instanceof _Href.default) {
@@ -1 +1 @@
1
- {"version":3,"file":"useModularUI.js","names":["_react","require","_reactRedux","_reactRouter","_constants","_ModularUIActions","_useDeepCompareEffect","_interopRequireDefault","_useModularUIKey","_Href","useModularUI","modelKey","url","options","dispatch","useDispatch","hrefInstance","useMemo","Href","requestUrl","toString","currentQueryString","querystring","prevQueryRef","useRef","key","useModularUIKey","model","useSelector","state","modularui","requestOptions","merged","method","HTTP_METHODS","GET","removeOnUnmount","origin","contextPath","location","useLocation","redirectLocation","shouldLoad","status","MODULARUI_STATUS","ERROR","current","equals","isReload","useEffect","useDeepCompareEffect","loadModularUI","removeModelByKey","exports"],"sources":["../../src/hooks/useModularUI.js"],"sourcesContent":["// @flow\nimport { useEffect, useMemo, useRef } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { useLocation } from \"react-router\";\n\nimport { HTTP_METHODS, MODULARUI_STATUS } from \"../constants\";\nimport {\n loadModularUI,\n removeModelByKey,\n} from \"../redux/_modularui/ModularUIActions\";\n\nimport useDeepCompareEffect from \"./useDeepCompareEffect\";\nimport { useModularUIKey } from \"./useModularUIKey\";\n\nimport Href from \"../models/href/Href\";\n\nimport type { RequestModularUIOptions } from \"../utils\";\nimport type { ModelEntry } from \"../redux\";\n\n/**\n * A custom hook to fetch and manage Be Informed modular UI resources.\n * It handles automatic data fetching based on URL/query changes, manages Redux state\n * synchronization, and provides cleanup logic when components unmount.\n *\n * @param {string} modelKey - A unique identifier for the type of model being fetched.\n * @param {string | Href} url - The endpoint URL or Href instance to fetch data from.\n * @param {RequestModularUIOptions} options - Configuration for the request (method, headers, etc.).\n * @returns {ModelEntry} The model data retrieved from the Redux store.\n */\nexport const useModularUI = (\n modelKey: string,\n url: string | Href,\n options: RequestModularUIOptions = (({}: any): RequestModularUIOptions),\n): any => {\n const dispatch = useDispatch();\n\n // Normalize the URL input into a Href instance to safely access query params and paths\n const hrefInstance = useMemo(() => new Href(url), [url]);\n const requestUrl = useMemo(() => hrefInstance.toString(), [hrefInstance]);\n const currentQueryString = hrefInstance.querystring;\n\n // Persistence ref to detect if query parameters have changed between renders\n const prevQueryRef = useRef(currentQueryString);\n\n // Generate a unique key for the Redux store based on the model type and the full URL\n const key = useModularUIKey(modelKey, requestUrl);\n\n // Select the specific piece of state corresponding to this modular UI component\n const model = useSelector((state) => state.modularui[key]);\n\n /**\n * Memoize request options to prevent unnecessary re-renders.\n * Merges default settings (GET method, auto-cleanup) with user-provided options.\n */\n const requestOptions = useMemo(() => {\n const merged = {\n method: HTTP_METHODS.GET,\n removeOnUnmount: false,\n ...options,\n };\n\n if (url instanceof Href) {\n merged.origin = merged.origin ?? url.origin;\n merged.contextPath = merged.contextPath ?? url.contextPath;\n }\n return merged;\n }, [options, url]);\n\n const location = useLocation();\n const redirectLocation = location.state?.redirectLocation;\n\n /**\n * Determines if a network request should be initiated.\n * Logic includes:\n * - Model doesn't exist yet (Initial load)\n * - Previous request resulted in an error (Retry)\n * - The query parameters changed (Filtering/Paging)\n * - A redirect was triggered specifically for this URL\n * - Manual 'isReload' flag is passed in options\n */\n const shouldLoad =\n model == null ||\n model.status === MODULARUI_STATUS.ERROR ||\n prevQueryRef.current !== currentQueryString ||\n (redirectLocation instanceof Href\n ? redirectLocation.equals(requestUrl)\n : false) ||\n requestOptions.isReload === true;\n\n // Synchronize the ref after the render cycle determines if we should load\n useEffect(() => {\n prevQueryRef.current = currentQueryString;\n }, [currentQueryString]);\n\n // Execute the load action. Deep compare is used on options to prevent\n // infinite loops caused by passing inline object literals.\n useDeepCompareEffect(() => {\n if (requestUrl !== \"\" && shouldLoad) {\n dispatch(loadModularUI(key, requestUrl, requestOptions));\n }\n }, [key, requestUrl, requestOptions, shouldLoad]);\n\n // Cleanup Effect:\n // If 'removeOnUnmount' is true, this removes the model data from the Redux store\n // when the component using this hook is destroyed.\n useEffect(() => {\n if (requestOptions.removeOnUnmount) {\n return () => {\n dispatch(removeModelByKey(key));\n };\n }\n }, [dispatch, key, requestOptions.removeOnUnmount]);\n\n return model;\n};\n"],"mappings":";;;;;;;AACA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AACA,IAAAE,YAAA,GAAAF,OAAA;AAEA,IAAAG,UAAA,GAAAH,OAAA;AACA,IAAAI,iBAAA,GAAAJ,OAAA;AAKA,IAAAK,qBAAA,GAAAC,sBAAA,CAAAN,OAAA;AACA,IAAAO,gBAAA,GAAAP,OAAA;AAEA,IAAAQ,KAAA,GAAAF,sBAAA,CAAAN,OAAA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMS,YAAY,GAAGA,CAC1BC,QAAgB,EAChBC,GAAkB,EAClBC,OAAgC,GAAK,CAAC,CAAiC,KAC/D;EACR,MAAMC,QAAQ,GAAG,IAAAC,uBAAW,EAAC,CAAC;;EAE9B;EACA,MAAMC,YAAY,GAAG,IAAAC,cAAO,EAAC,MAAM,IAAIC,aAAI,CAACN,GAAG,CAAC,EAAE,CAACA,GAAG,CAAC,CAAC;EACxD,MAAMO,UAAU,GAAG,IAAAF,cAAO,EAAC,MAAMD,YAAY,CAACI,QAAQ,CAAC,CAAC,EAAE,CAACJ,YAAY,CAAC,CAAC;EACzE,MAAMK,kBAAkB,GAAGL,YAAY,CAACM,WAAW;;EAEnD;EACA,MAAMC,YAAY,GAAG,IAAAC,aAAM,EAACH,kBAAkB,CAAC;;EAE/C;EACA,MAAMI,GAAG,GAAG,IAAAC,gCAAe,EAACf,QAAQ,EAAEQ,UAAU,CAAC;;EAEjD;EACA,MAAMQ,KAAK,GAAG,IAAAC,uBAAW,EAAEC,KAAK,IAAKA,KAAK,CAACC,SAAS,CAACL,GAAG,CAAC,CAAC;;EAE1D;AACF;AACA;AACA;EACE,MAAMM,cAAc,GAAG,IAAAd,cAAO,EAAC,MAAM;IACnC,MAAMe,MAAM,GAAG;MACbC,MAAM,EAAEC,uBAAY,CAACC,GAAG;MACxBC,eAAe,EAAE,KAAK;MACtB,GAAGvB;IACL,CAAC;IAED,IAAID,GAAG,YAAYM,aAAI,EAAE;MACvBc,MAAM,CAACK,MAAM,GAAGL,MAAM,CAACK,MAAM,IAAIzB,GAAG,CAACyB,MAAM;MAC3CL,MAAM,CAACM,WAAW,GAAGN,MAAM,CAACM,WAAW,IAAI1B,GAAG,CAAC0B,WAAW;IAC5D;IACA,OAAON,MAAM;EACf,CAAC,EAAE,CAACnB,OAAO,EAAED,GAAG,CAAC,CAAC;EAElB,MAAM2B,QAAQ,GAAG,IAAAC,wBAAW,EAAC,CAAC;EAC9B,MAAMC,gBAAgB,GAAGF,QAAQ,CAACV,KAAK,EAAEY,gBAAgB;;EAEzD;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACE,MAAMC,UAAU,GACdf,KAAK,IAAI,IAAI,IACbA,KAAK,CAACgB,MAAM,KAAKC,2BAAgB,CAACC,KAAK,IACvCtB,YAAY,CAACuB,OAAO,KAAKzB,kBAAkB,KAC1CoB,gBAAgB,YAAYvB,aAAI,GAC7BuB,gBAAgB,CAACM,MAAM,CAAC5B,UAAU,CAAC,GACnC,KAAK,CAAC,IACVY,cAAc,CAACiB,QAAQ,KAAK,IAAI;;EAElC;EACA,IAAAC,gBAAS,EAAC,MAAM;IACd1B,YAAY,CAACuB,OAAO,GAAGzB,kBAAkB;EAC3C,CAAC,EAAE,CAACA,kBAAkB,CAAC,CAAC;;EAExB;EACA;EACA,IAAA6B,6BAAoB,EAAC,MAAM;IACzB,IAAI/B,UAAU,KAAK,EAAE,IAAIuB,UAAU,EAAE;MACnC5B,QAAQ,CAAC,IAAAqC,+BAAa,EAAC1B,GAAG,EAAEN,UAAU,EAAEY,cAAc,CAAC,CAAC;IAC1D;EACF,CAAC,EAAE,CAACN,GAAG,EAAEN,UAAU,EAAEY,cAAc,EAAEW,UAAU,CAAC,CAAC;;EAEjD;EACA;EACA;EACA,IAAAO,gBAAS,EAAC,MAAM;IACd,IAAIlB,cAAc,CAACK,eAAe,EAAE;MAClC,OAAO,MAAM;QACXtB,QAAQ,CAAC,IAAAsC,kCAAgB,EAAC3B,GAAG,CAAC,CAAC;MACjC,CAAC;IACH;EACF,CAAC,EAAE,CAACX,QAAQ,EAAEW,GAAG,EAAEM,cAAc,CAACK,eAAe,CAAC,CAAC;EAEnD,OAAOT,KAAK;AACd,CAAC;AAAC0B,OAAA,CAAA3C,YAAA,GAAAA,YAAA","ignoreList":[]}
1
+ {"version":3,"file":"useModularUI.js","names":["_react","require","_reactRedux","_reactRouter","_constants","_ModularUIActions","_useDeepCompareEffect","_interopRequireDefault","_useModularUIKey","_Href","useModularUI","modelKey","url","options","dispatch","useDispatch","hrefInstance","useMemo","Href","requestUrl","toString","currentQueryString","querystring","prevQueryRef","useRef","key","useModularUIKey","model","useSelector","state","modularui","requestOptions","merged","method","HTTP_METHODS","GET","removeOnUnmount","origin","contextPath","location","useLocation","redirectLocation","shouldLoad","status","MODULARUI_STATUS","ERROR","current","equals","isReload","useEffect","useDeepCompareEffect","loadModularUI","removeModelByKey","exports"],"sources":["../../src/hooks/useModularUI.js"],"sourcesContent":["// @flow\nimport { useEffect, useMemo, useRef } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { useLocation } from \"react-router\";\n\nimport { HTTP_METHODS, MODULARUI_STATUS } from \"../constants\";\nimport {\n loadModularUI,\n removeModelByKey,\n} from \"../redux/_modularui/ModularUIActions\";\n\nimport useDeepCompareEffect from \"./useDeepCompareEffect\";\nimport { useModularUIKey } from \"./useModularUIKey\";\n\nimport Href from \"../models/href/Href\";\n\nimport type { RequestModularUIOptions } from \"../utils\";\nimport type { ModelEntry } from \"../redux\";\n\n/**\n * A custom hook to fetch and manage Be Informed modular UI resources.\n * It handles automatic data fetching based on URL/query changes, manages Redux state\n * synchronization, and provides cleanup logic when components unmount.\n *\n * @param {string} modelKey - A unique identifier for the type of model being fetched.\n * @param {string | Href} url - The endpoint URL or Href instance to fetch data from.\n * @param {RequestModularUIOptions} options - Configuration for the request (method, headers, etc.).\n * @returns {ModelEntry} The model data retrieved from the Redux store.\n */\nexport const useModularUI = (\n modelKey: string,\n url: string | Href,\n options: RequestModularUIOptions = (({}: any): RequestModularUIOptions),\n): any => {\n const dispatch = useDispatch();\n\n // Normalize the URL input into a Href instance to safely access query params and paths\n const hrefInstance = useMemo(() => new Href(url), [url]);\n const requestUrl = useMemo(() => hrefInstance.toString(), [hrefInstance]);\n const currentQueryString = hrefInstance.querystring;\n\n // Persistence ref to detect if query parameters have changed between renders\n const prevQueryRef = useRef(currentQueryString);\n\n // Generate a unique key for the Redux store based on the model type and the full URL\n const key = useModularUIKey(modelKey, requestUrl);\n\n // Select the specific piece of state corresponding to this modular UI component\n const model = useSelector((state) => state.modularui[key]);\n\n /**\n * Memoize request options to prevent unnecessary re-renders.\n * Merges default settings (GET method, auto-cleanup) with user-provided options.\n */\n const requestOptions = useMemo(() => {\n const merged = {\n method: HTTP_METHODS.GET,\n removeOnUnmount: true,\n ...options,\n };\n\n if (url instanceof Href) {\n merged.origin = merged.origin ?? url.origin;\n merged.contextPath = merged.contextPath ?? url.contextPath;\n }\n return merged;\n }, [options, url]);\n\n const location = useLocation();\n const redirectLocation = location.state?.redirectLocation;\n\n /**\n * Determines if a network request should be initiated.\n * Logic includes:\n * - Model doesn't exist yet (Initial load)\n * - Previous request resulted in an error (Retry)\n * - The query parameters changed (Filtering/Paging)\n * - A redirect was triggered specifically for this URL\n * - Manual 'isReload' flag is passed in options\n */\n const shouldLoad =\n model == null ||\n model.status === MODULARUI_STATUS.ERROR ||\n prevQueryRef.current !== currentQueryString ||\n (redirectLocation instanceof Href\n ? redirectLocation.equals(requestUrl)\n : false) ||\n requestOptions.isReload === true;\n\n // Synchronize the ref after the render cycle determines if we should load\n useEffect(() => {\n prevQueryRef.current = currentQueryString;\n }, [currentQueryString]);\n\n // Execute the load action. Deep compare is used on options to prevent\n // infinite loops caused by passing inline object literals.\n useDeepCompareEffect(() => {\n if (requestUrl !== \"\" && shouldLoad) {\n dispatch(loadModularUI(key, requestUrl, requestOptions));\n }\n }, [key, requestUrl, requestOptions, shouldLoad]);\n\n // Cleanup Effect:\n // If 'removeOnUnmount' is true, this removes the model data from the Redux store\n // when the component using this hook is destroyed.\n useEffect(() => {\n if (requestOptions.removeOnUnmount) {\n return () => {\n dispatch(removeModelByKey(key));\n };\n }\n }, [dispatch, key, requestOptions.removeOnUnmount]);\n\n return model;\n};\n"],"mappings":";;;;;;;AACA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AACA,IAAAE,YAAA,GAAAF,OAAA;AAEA,IAAAG,UAAA,GAAAH,OAAA;AACA,IAAAI,iBAAA,GAAAJ,OAAA;AAKA,IAAAK,qBAAA,GAAAC,sBAAA,CAAAN,OAAA;AACA,IAAAO,gBAAA,GAAAP,OAAA;AAEA,IAAAQ,KAAA,GAAAF,sBAAA,CAAAN,OAAA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMS,YAAY,GAAGA,CAC1BC,QAAgB,EAChBC,GAAkB,EAClBC,OAAgC,GAAK,CAAC,CAAiC,KAC/D;EACR,MAAMC,QAAQ,GAAG,IAAAC,uBAAW,EAAC,CAAC;;EAE9B;EACA,MAAMC,YAAY,GAAG,IAAAC,cAAO,EAAC,MAAM,IAAIC,aAAI,CAACN,GAAG,CAAC,EAAE,CAACA,GAAG,CAAC,CAAC;EACxD,MAAMO,UAAU,GAAG,IAAAF,cAAO,EAAC,MAAMD,YAAY,CAACI,QAAQ,CAAC,CAAC,EAAE,CAACJ,YAAY,CAAC,CAAC;EACzE,MAAMK,kBAAkB,GAAGL,YAAY,CAACM,WAAW;;EAEnD;EACA,MAAMC,YAAY,GAAG,IAAAC,aAAM,EAACH,kBAAkB,CAAC;;EAE/C;EACA,MAAMI,GAAG,GAAG,IAAAC,gCAAe,EAACf,QAAQ,EAAEQ,UAAU,CAAC;;EAEjD;EACA,MAAMQ,KAAK,GAAG,IAAAC,uBAAW,EAAEC,KAAK,IAAKA,KAAK,CAACC,SAAS,CAACL,GAAG,CAAC,CAAC;;EAE1D;AACF;AACA;AACA;EACE,MAAMM,cAAc,GAAG,IAAAd,cAAO,EAAC,MAAM;IACnC,MAAMe,MAAM,GAAG;MACbC,MAAM,EAAEC,uBAAY,CAACC,GAAG;MACxBC,eAAe,EAAE,IAAI;MACrB,GAAGvB;IACL,CAAC;IAED,IAAID,GAAG,YAAYM,aAAI,EAAE;MACvBc,MAAM,CAACK,MAAM,GAAGL,MAAM,CAACK,MAAM,IAAIzB,GAAG,CAACyB,MAAM;MAC3CL,MAAM,CAACM,WAAW,GAAGN,MAAM,CAACM,WAAW,IAAI1B,GAAG,CAAC0B,WAAW;IAC5D;IACA,OAAON,MAAM;EACf,CAAC,EAAE,CAACnB,OAAO,EAAED,GAAG,CAAC,CAAC;EAElB,MAAM2B,QAAQ,GAAG,IAAAC,wBAAW,EAAC,CAAC;EAC9B,MAAMC,gBAAgB,GAAGF,QAAQ,CAACV,KAAK,EAAEY,gBAAgB;;EAEzD;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACE,MAAMC,UAAU,GACdf,KAAK,IAAI,IAAI,IACbA,KAAK,CAACgB,MAAM,KAAKC,2BAAgB,CAACC,KAAK,IACvCtB,YAAY,CAACuB,OAAO,KAAKzB,kBAAkB,KAC1CoB,gBAAgB,YAAYvB,aAAI,GAC7BuB,gBAAgB,CAACM,MAAM,CAAC5B,UAAU,CAAC,GACnC,KAAK,CAAC,IACVY,cAAc,CAACiB,QAAQ,KAAK,IAAI;;EAElC;EACA,IAAAC,gBAAS,EAAC,MAAM;IACd1B,YAAY,CAACuB,OAAO,GAAGzB,kBAAkB;EAC3C,CAAC,EAAE,CAACA,kBAAkB,CAAC,CAAC;;EAExB;EACA;EACA,IAAA6B,6BAAoB,EAAC,MAAM;IACzB,IAAI/B,UAAU,KAAK,EAAE,IAAIuB,UAAU,EAAE;MACnC5B,QAAQ,CAAC,IAAAqC,+BAAa,EAAC1B,GAAG,EAAEN,UAAU,EAAEY,cAAc,CAAC,CAAC;IAC1D;EACF,CAAC,EAAE,CAACN,GAAG,EAAEN,UAAU,EAAEY,cAAc,EAAEW,UAAU,CAAC,CAAC;;EAEjD;EACA;EACA;EACA,IAAAO,gBAAS,EAAC,MAAM;IACd,IAAIlB,cAAc,CAACK,eAAe,EAAE;MAClC,OAAO,MAAM;QACXtB,QAAQ,CAAC,IAAAsC,kCAAgB,EAAC3B,GAAG,CAAC,CAAC;MACjC,CAAC;IACH;EACF,CAAC,EAAE,CAACX,QAAQ,EAAEW,GAAG,EAAEM,cAAc,CAACK,eAAe,CAAC,CAAC;EAEnD,OAAOT,KAAK;AACd,CAAC;AAAC0B,OAAA,CAAA3C,YAAA,GAAAA,YAAA","ignoreList":[]}
@@ -18,6 +18,7 @@ var _useModularUIBasic = require("./useModularUIBasic");
18
18
  const useApplication = options => (0, _useModularUIBasic.useModularUIBasic)("application", "/", {
19
19
  expectedModels: ["Application"],
20
20
  targetModel: _ApplicationModel.default,
21
+ removeOnUnmount: options?.removeOnUnmount ?? false,
21
22
  ...options
22
23
  });
23
24
 
@@ -1 +1 @@
1
- {"version":3,"file":"useModularUIModel.js","names":["_ApplicationModel","_interopRequireDefault","require","_CaseViewModel","_TabModel","_GroupingPanelModel","_DetailModel","_UserProfileModel","_useModularUIBasic","useApplication","options","useModularUIBasic","expectedModels","targetModel","ApplicationModel","exports","useTab","href","TabModel","useCaseView","CaseViewModel","useGroupingPanel","GroupingPanelModel","useDetailPanel","DetailModel","useUserProfile","UserProfileModel"],"sources":["../../src/hooks/useModularUIModel.js"],"sourcesContent":["// @flow\nimport ApplicationModel from \"../models/application/ApplicationModel\";\nimport CaseViewModel from \"../models/caseview/CaseViewModel\";\nimport TabModel from \"../models/tab/TabModel\";\nimport GroupingPanelModel from \"../models/panels/GroupingPanelModel\";\nimport DetailModel from \"../models/detail/DetailModel\";\nimport UserProfileModel from \"../models/user/UserProfileModel\";\n\nimport { useModularUIBasic } from \"./useModularUIBasic\";\n\nimport type Href from \"../models/href/Href\";\nimport type { HookOptions } from \"./useModularUIBasic\";\n\n/**\n * Load application\n */\nexport const useApplication = (\n options?: HookOptions,\n): ApplicationModel | null =>\n useModularUIBasic(\"application\", \"/\", {\n expectedModels: [\"Application\"],\n targetModel: ApplicationModel,\n ...options,\n });\n\n/**\n * Load a tab by href\n */\nexport const useTab = (\n href: string | Href,\n options?: HookOptions,\n): TabModel | null =>\n useModularUIBasic(\"tab\", href, {\n expectedModels: [\"Tab\"],\n targetModel: TabModel,\n ...options,\n });\n\n/**\n * Load caseview by href\n */\nexport const useCaseView = (\n href: string | Href,\n options?: HookOptions,\n): CaseViewModel | null =>\n useModularUIBasic(\"caseview\", href, {\n expectedModels: [\"CaseView\"],\n targetModel: CaseViewModel,\n ...options,\n });\n\n/**\n */\nexport const useGroupingPanel = (\n href: string | Href,\n options?: HookOptions,\n): GroupingPanelModel | null =>\n useModularUIBasic(\"groupingpanel\", href, {\n expectedModels: [\"GroupingPanel\"],\n targetModel: GroupingPanelModel,\n ...options,\n });\n\n/**\n */\nexport const useDetailPanel = (\n href: string | Href,\n options?: HookOptions,\n): DetailModel | null =>\n useModularUIBasic(\"detailpanel\", href, {\n expectedModels: [\"Detail\"],\n targetModel: DetailModel,\n ...options,\n });\n\n/**\n */\nexport const useUserProfile = (\n href: string | Href,\n options?: HookOptions,\n): UserProfileModel | null =>\n useModularUIBasic(\"userprofile\", href, {\n expectedModels: [\"UserProfile\"],\n targetModel: UserProfileModel,\n ...options,\n });\n"],"mappings":";;;;;;;AACA,IAAAA,iBAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,cAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,SAAA,GAAAH,sBAAA,CAAAC,OAAA;AACA,IAAAG,mBAAA,GAAAJ,sBAAA,CAAAC,OAAA;AACA,IAAAI,YAAA,GAAAL,sBAAA,CAAAC,OAAA;AACA,IAAAK,iBAAA,GAAAN,sBAAA,CAAAC,OAAA;AAEA,IAAAM,kBAAA,GAAAN,OAAA;AAKA;AACA;AACA;AACO,MAAMO,cAAc,GACzBC,OAAqB,IAErB,IAAAC,oCAAiB,EAAC,aAAa,EAAE,GAAG,EAAE;EACpCC,cAAc,EAAE,CAAC,aAAa,CAAC;EAC/BC,WAAW,EAAEC,yBAAgB;EAC7B,GAAGJ;AACL,CAAC,CAAC;;AAEJ;AACA;AACA;AAFAK,OAAA,CAAAN,cAAA,GAAAA,cAAA;AAGO,MAAMO,MAAM,GAAGA,CACpBC,IAAmB,EACnBP,OAAqB,KAErB,IAAAC,oCAAiB,EAAC,KAAK,EAAEM,IAAI,EAAE;EAC7BL,cAAc,EAAE,CAAC,KAAK,CAAC;EACvBC,WAAW,EAAEK,iBAAQ;EACrB,GAAGR;AACL,CAAC,CAAC;;AAEJ;AACA;AACA;AAFAK,OAAA,CAAAC,MAAA,GAAAA,MAAA;AAGO,MAAMG,WAAW,GAAGA,CACzBF,IAAmB,EACnBP,OAAqB,KAErB,IAAAC,oCAAiB,EAAC,UAAU,EAAEM,IAAI,EAAE;EAClCL,cAAc,EAAE,CAAC,UAAU,CAAC;EAC5BC,WAAW,EAAEO,sBAAa;EAC1B,GAAGV;AACL,CAAC,CAAC;;AAEJ;AACA;AADAK,OAAA,CAAAI,WAAA,GAAAA,WAAA;AAEO,MAAME,gBAAgB,GAAGA,CAC9BJ,IAAmB,EACnBP,OAAqB,KAErB,IAAAC,oCAAiB,EAAC,eAAe,EAAEM,IAAI,EAAE;EACvCL,cAAc,EAAE,CAAC,eAAe,CAAC;EACjCC,WAAW,EAAES,2BAAkB;EAC/B,GAAGZ;AACL,CAAC,CAAC;;AAEJ;AACA;AADAK,OAAA,CAAAM,gBAAA,GAAAA,gBAAA;AAEO,MAAME,cAAc,GAAGA,CAC5BN,IAAmB,EACnBP,OAAqB,KAErB,IAAAC,oCAAiB,EAAC,aAAa,EAAEM,IAAI,EAAE;EACrCL,cAAc,EAAE,CAAC,QAAQ,CAAC;EAC1BC,WAAW,EAAEW,oBAAW;EACxB,GAAGd;AACL,CAAC,CAAC;;AAEJ;AACA;AADAK,OAAA,CAAAQ,cAAA,GAAAA,cAAA;AAEO,MAAME,cAAc,GAAGA,CAC5BR,IAAmB,EACnBP,OAAqB,KAErB,IAAAC,oCAAiB,EAAC,aAAa,EAAEM,IAAI,EAAE;EACrCL,cAAc,EAAE,CAAC,aAAa,CAAC;EAC/BC,WAAW,EAAEa,yBAAgB;EAC7B,GAAGhB;AACL,CAAC,CAAC;AAACK,OAAA,CAAAU,cAAA,GAAAA,cAAA","ignoreList":[]}
1
+ {"version":3,"file":"useModularUIModel.js","names":["_ApplicationModel","_interopRequireDefault","require","_CaseViewModel","_TabModel","_GroupingPanelModel","_DetailModel","_UserProfileModel","_useModularUIBasic","useApplication","options","useModularUIBasic","expectedModels","targetModel","ApplicationModel","removeOnUnmount","exports","useTab","href","TabModel","useCaseView","CaseViewModel","useGroupingPanel","GroupingPanelModel","useDetailPanel","DetailModel","useUserProfile","UserProfileModel"],"sources":["../../src/hooks/useModularUIModel.js"],"sourcesContent":["// @flow\nimport ApplicationModel from \"../models/application/ApplicationModel\";\nimport CaseViewModel from \"../models/caseview/CaseViewModel\";\nimport TabModel from \"../models/tab/TabModel\";\nimport GroupingPanelModel from \"../models/panels/GroupingPanelModel\";\nimport DetailModel from \"../models/detail/DetailModel\";\nimport UserProfileModel from \"../models/user/UserProfileModel\";\n\nimport { useModularUIBasic } from \"./useModularUIBasic\";\n\nimport type Href from \"../models/href/Href\";\nimport type { HookOptions } from \"./useModularUIBasic\";\n\n/**\n * Load application\n */\nexport const useApplication = (\n options?: HookOptions,\n): ApplicationModel | null =>\n useModularUIBasic(\"application\", \"/\", {\n expectedModels: [\"Application\"],\n targetModel: ApplicationModel,\n removeOnUnmount: options?.removeOnUnmount ?? false,\n ...options,\n });\n\n/**\n * Load a tab by href\n */\nexport const useTab = (\n href: string | Href,\n options?: HookOptions,\n): TabModel | null =>\n useModularUIBasic(\"tab\", href, {\n expectedModels: [\"Tab\"],\n targetModel: TabModel,\n ...options,\n });\n\n/**\n * Load caseview by href\n */\nexport const useCaseView = (\n href: string | Href,\n options?: HookOptions,\n): CaseViewModel | null =>\n useModularUIBasic(\"caseview\", href, {\n expectedModels: [\"CaseView\"],\n targetModel: CaseViewModel,\n ...options,\n });\n\n/**\n */\nexport const useGroupingPanel = (\n href: string | Href,\n options?: HookOptions,\n): GroupingPanelModel | null =>\n useModularUIBasic(\"groupingpanel\", href, {\n expectedModels: [\"GroupingPanel\"],\n targetModel: GroupingPanelModel,\n ...options,\n });\n\n/**\n */\nexport const useDetailPanel = (\n href: string | Href,\n options?: HookOptions,\n): DetailModel | null =>\n useModularUIBasic(\"detailpanel\", href, {\n expectedModels: [\"Detail\"],\n targetModel: DetailModel,\n ...options,\n });\n\n/**\n */\nexport const useUserProfile = (\n href: string | Href,\n options?: HookOptions,\n): UserProfileModel | null =>\n useModularUIBasic(\"userprofile\", href, {\n expectedModels: [\"UserProfile\"],\n targetModel: UserProfileModel,\n ...options,\n });\n"],"mappings":";;;;;;;AACA,IAAAA,iBAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,cAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,SAAA,GAAAH,sBAAA,CAAAC,OAAA;AACA,IAAAG,mBAAA,GAAAJ,sBAAA,CAAAC,OAAA;AACA,IAAAI,YAAA,GAAAL,sBAAA,CAAAC,OAAA;AACA,IAAAK,iBAAA,GAAAN,sBAAA,CAAAC,OAAA;AAEA,IAAAM,kBAAA,GAAAN,OAAA;AAKA;AACA;AACA;AACO,MAAMO,cAAc,GACzBC,OAAqB,IAErB,IAAAC,oCAAiB,EAAC,aAAa,EAAE,GAAG,EAAE;EACpCC,cAAc,EAAE,CAAC,aAAa,CAAC;EAC/BC,WAAW,EAAEC,yBAAgB;EAC7BC,eAAe,EAAEL,OAAO,EAAEK,eAAe,IAAI,KAAK;EAClD,GAAGL;AACL,CAAC,CAAC;;AAEJ;AACA;AACA;AAFAM,OAAA,CAAAP,cAAA,GAAAA,cAAA;AAGO,MAAMQ,MAAM,GAAGA,CACpBC,IAAmB,EACnBR,OAAqB,KAErB,IAAAC,oCAAiB,EAAC,KAAK,EAAEO,IAAI,EAAE;EAC7BN,cAAc,EAAE,CAAC,KAAK,CAAC;EACvBC,WAAW,EAAEM,iBAAQ;EACrB,GAAGT;AACL,CAAC,CAAC;;AAEJ;AACA;AACA;AAFAM,OAAA,CAAAC,MAAA,GAAAA,MAAA;AAGO,MAAMG,WAAW,GAAGA,CACzBF,IAAmB,EACnBR,OAAqB,KAErB,IAAAC,oCAAiB,EAAC,UAAU,EAAEO,IAAI,EAAE;EAClCN,cAAc,EAAE,CAAC,UAAU,CAAC;EAC5BC,WAAW,EAAEQ,sBAAa;EAC1B,GAAGX;AACL,CAAC,CAAC;;AAEJ;AACA;AADAM,OAAA,CAAAI,WAAA,GAAAA,WAAA;AAEO,MAAME,gBAAgB,GAAGA,CAC9BJ,IAAmB,EACnBR,OAAqB,KAErB,IAAAC,oCAAiB,EAAC,eAAe,EAAEO,IAAI,EAAE;EACvCN,cAAc,EAAE,CAAC,eAAe,CAAC;EACjCC,WAAW,EAAEU,2BAAkB;EAC/B,GAAGb;AACL,CAAC,CAAC;;AAEJ;AACA;AADAM,OAAA,CAAAM,gBAAA,GAAAA,gBAAA;AAEO,MAAME,cAAc,GAAGA,CAC5BN,IAAmB,EACnBR,OAAqB,KAErB,IAAAC,oCAAiB,EAAC,aAAa,EAAEO,IAAI,EAAE;EACrCN,cAAc,EAAE,CAAC,QAAQ,CAAC;EAC1BC,WAAW,EAAEY,oBAAW;EACxB,GAAGf;AACL,CAAC,CAAC;;AAEJ;AACA;AADAM,OAAA,CAAAQ,cAAA,GAAAA,cAAA;AAEO,MAAME,cAAc,GAAGA,CAC5BR,IAAmB,EACnBR,OAAqB,KAErB,IAAAC,oCAAiB,EAAC,aAAa,EAAEO,IAAI,EAAE;EACrCN,cAAc,EAAE,CAAC,aAAa,CAAC;EAC/BC,WAAW,EAAEc,yBAAgB;EAC7B,GAAGjB;AACL,CAAC,CAAC;AAACM,OAAA,CAAAU,cAAA,GAAAA,cAAA","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beinformed/ui",
3
- "version": "1.65.27",
3
+ "version": "1.65.28",
4
4
  "description": "Toolbox for be informed javascript layouts",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "bugs": "https://support.beinformed.com",
@@ -68,7 +68,7 @@
68
68
  "styled-components": "^5.0.0"
69
69
  },
70
70
  "dependencies": {
71
- "@babel/runtime-corejs3": "^7.28.6",
71
+ "@babel/runtime-corejs3": "^7.29.0",
72
72
  "@date-fns/tz": "^1.4.1",
73
73
  "baseline-browser-mapping": "^2.9.19",
74
74
  "big.js": "^7.0.1",
@@ -89,13 +89,13 @@
89
89
  },
90
90
  "devDependencies": {
91
91
  "@babel/cli": "^7.28.6",
92
- "@babel/core": "^7.28.6",
92
+ "@babel/core": "^7.29.0",
93
93
  "@babel/eslint-parser": "^7.28.6",
94
94
  "@babel/eslint-plugin": "^7.27.1",
95
95
  "@babel/plugin-proposal-class-properties": "^7.18.6",
96
96
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
97
- "@babel/plugin-transform-runtime": "^7.28.5",
98
- "@babel/preset-env": "^7.28.6",
97
+ "@babel/plugin-transform-runtime": "^7.29.0",
98
+ "@babel/preset-env": "^7.29.0",
99
99
  "@babel/preset-flow": "^7.27.1",
100
100
  "@babel/preset-react": "^7.28.5",
101
101
  "@commitlint/cli": "^20.4.0",