@beinformed/ui 1.56.2 → 1.56.5

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/esm/hooks/useModularUI.js +20 -18
  3. package/esm/hooks/useModularUI.js.map +1 -1
  4. package/esm/hooks/useModularUIBasic.js +18 -16
  5. package/esm/hooks/useModularUIBasic.js.map +1 -1
  6. package/esm/models/concepts/ConceptTypeDetailModel.js +2 -2
  7. package/esm/models/concepts/ConceptTypeDetailModel.js.map +1 -1
  8. package/esm/redux/_modularui/ModularUIActions.js +10 -8
  9. package/esm/redux/_modularui/ModularUIActions.js.map +1 -1
  10. package/esm/redux/_modularui/ModularUIMiddleware.js +4 -1
  11. package/esm/redux/_modularui/ModularUIMiddleware.js.map +1 -1
  12. package/esm/redux/_modularui/ModularUIReducer.js +2 -1
  13. package/esm/redux/_modularui/ModularUIReducer.js.map +1 -1
  14. package/esm/redux/_modularui/types.js.map +1 -1
  15. package/lib/hooks/__tests__/UseModularUIModel.spec.js.flow +11 -4
  16. package/lib/hooks/__tests__/useAuthentication.spec.js.flow +2 -8
  17. package/lib/hooks/__tests__/useForm.spec.js.flow +14 -12
  18. package/lib/hooks/__tests__/useModelCatalog.spec.js.flow +10 -4
  19. package/lib/hooks/__tests__/useModels.spec.js.flow +3 -12
  20. package/lib/hooks/__tests__/useModularUIBasic.spec.js.flow +9 -8
  21. package/lib/hooks/useModularUI.js +19 -17
  22. package/lib/hooks/useModularUI.js.flow +26 -16
  23. package/lib/hooks/useModularUI.js.map +1 -1
  24. package/lib/hooks/useModularUIBasic.js +18 -16
  25. package/lib/hooks/useModularUIBasic.js.flow +23 -16
  26. package/lib/hooks/useModularUIBasic.js.map +1 -1
  27. package/lib/models/concepts/ConceptTypeDetailModel.js +2 -2
  28. package/lib/models/concepts/ConceptTypeDetailModel.js.flow +2 -2
  29. package/lib/models/concepts/ConceptTypeDetailModel.js.map +1 -1
  30. package/lib/redux/_modularui/ModularUIActions.js +10 -8
  31. package/lib/redux/_modularui/ModularUIActions.js.flow +14 -9
  32. package/lib/redux/_modularui/ModularUIActions.js.map +1 -1
  33. package/lib/redux/_modularui/ModularUIMiddleware.js +3 -0
  34. package/lib/redux/_modularui/ModularUIMiddleware.js.flow +6 -3
  35. package/lib/redux/_modularui/ModularUIMiddleware.js.map +1 -1
  36. package/lib/redux/_modularui/ModularUIReducer.js +2 -1
  37. package/lib/redux/_modularui/ModularUIReducer.js.flow +1 -0
  38. package/lib/redux/_modularui/ModularUIReducer.js.map +1 -1
  39. package/lib/redux/_modularui/__tests__/actions.spec.js.flow +1 -4
  40. package/lib/redux/_modularui/types.js.flow +1 -0
  41. package/lib/redux/_modularui/types.js.map +1 -1
  42. package/lib/redux/actions/__tests__/Application.spec.js.flow +1 -8
  43. package/lib/redux/actions/__tests__/Authorization.spec.js.flow +0 -4
  44. package/package.json +9 -9
  45. package/src/hooks/__tests__/UseModularUIModel.spec.js +11 -4
  46. package/src/hooks/__tests__/useAuthentication.spec.js +2 -8
  47. package/src/hooks/__tests__/useForm.spec.js +14 -12
  48. package/src/hooks/__tests__/useModelCatalog.spec.js +10 -4
  49. package/src/hooks/__tests__/useModels.spec.js +3 -12
  50. package/src/hooks/__tests__/useModularUIBasic.spec.js +9 -8
  51. package/src/hooks/useModularUI.js +26 -16
  52. package/src/hooks/useModularUIBasic.js +23 -16
  53. package/src/models/concepts/ConceptTypeDetailModel.js +2 -2
  54. package/src/redux/_modularui/ModularUIActions.js +14 -9
  55. package/src/redux/_modularui/ModularUIMiddleware.js +6 -3
  56. package/src/redux/_modularui/ModularUIReducer.js +1 -0
  57. package/src/redux/_modularui/__tests__/actions.spec.js +1 -4
  58. package/src/redux/_modularui/types.js +1 -0
  59. package/src/redux/actions/__tests__/Application.spec.js +1 -8
  60. package/src/redux/actions/__tests__/Authorization.spec.js +0 -4
@@ -1,6 +1,7 @@
1
1
  // @flow
2
- import { useEffect, useRef } from "react";
2
+ import { useEffect, useRef, useMemo } from "react";
3
3
  import { useDispatch, useSelector } from "react-redux";
4
+ import { useLocation } from "react-router";
4
5
 
5
6
  import { HTTP_METHODS } from "../constants";
6
7
  import {
@@ -12,14 +13,17 @@ import useDeepCompareEffect from "./useDeepCompareEffect";
12
13
 
13
14
  import { useLocale } from "./useI18n";
14
15
 
15
- import type Href from "../models/href/Href";
16
+ import Href from "../models/href/Href";
16
17
  import type { RequestModularUIOptions } from "../utils";
17
18
 
18
19
  /**
19
20
  */
20
21
  const useKeyForHook = (modelKey: string, url: string) => {
21
22
  const locale = useLocale();
22
- return `${modelKey}(${url.split("?")[0]})(${locale})`;
23
+ return useMemo(
24
+ () => `${modelKey}(${url.split("?")[0]})(${locale})`,
25
+ [modelKey, url, locale],
26
+ );
23
27
  };
24
28
 
25
29
  /**
@@ -34,11 +38,17 @@ export const useModularUI = (
34
38
  },
35
39
  ): any => {
36
40
  const dispatch = useDispatch();
37
- const href = url?.toString() || "";
41
+ const href = useMemo(() => url?.toString() || "", [url]);
38
42
  const key = useKeyForHook(modelKey, href);
39
43
 
44
+ const location = useLocation();
45
+ const redirectLocation = location.state?.redirectLocation;
46
+ const forceReload =
47
+ redirectLocation instanceof Href ? redirectLocation?.equals(href) : false;
48
+
40
49
  const prevOptions = useRef(options);
41
50
  const prevHref = useRef(href);
51
+ const prevForceReload = useRef(forceReload);
42
52
 
43
53
  // dispatch loadModularUI
44
54
  useDeepCompareEffect(() => {
@@ -48,25 +58,25 @@ export const useModularUI = (
48
58
  prevOptions.current.isReload &&
49
59
  !options.isReload;
50
60
 
51
- if (href !== "" && !isOldReload) {
61
+ const doForceReload = forceReload && !prevForceReload.current;
62
+
63
+ if (href !== "" && (doForceReload || !isOldReload)) {
52
64
  dispatch(loadModularUI(key, href, options));
53
65
  }
54
66
 
55
67
  prevOptions.current = options;
56
68
  prevHref.current = href;
57
- }, [key, href, options]);
69
+ prevForceReload.current = forceReload;
70
+ }, [key, href, options, forceReload]);
58
71
 
59
- const { removeOnUnmount = false } = options;
60
72
  useEffect(() => {
61
- return () => {
62
- if (removeOnUnmount) {
73
+ if (options.removeOnUnmount) {
74
+ return () => {
63
75
  dispatch(removeModelByKey(key));
64
- }
65
- };
66
- }, [dispatch, key, removeOnUnmount]);
76
+ };
77
+ }
78
+ }, [dispatch, key, options.removeOnUnmount]);
67
79
 
68
- // retrieve current model from modularui reducer
69
- return useSelector((state) => {
70
- return state.modularui[key];
71
- });
80
+ const selector = useMemo(() => (state) => state.modularui[key], [key]);
81
+ return useSelector(selector);
72
82
  };
@@ -1,4 +1,6 @@
1
1
  // @flow
2
+ import { useMemo } from "react";
3
+
2
4
  import { useModularUI } from "./useModularUI";
3
5
 
4
6
  import { useLocation } from "./useRouter";
@@ -26,6 +28,7 @@ export const useModularUIBasic = <T: ModularUIModel>(
26
28
  },
27
29
  ): T | null => {
28
30
  const location = useLocation();
31
+ const memoizedHref = useMemo(() => href.toString(), [href]);
29
32
 
30
33
  const useModularUIOptions = {
31
34
  targetModel: undefined,
@@ -48,25 +51,29 @@ export const useModularUIBasic = <T: ModularUIModel>(
48
51
  }
49
52
 
50
53
  // $FlowFixMe[incompatible-call]
51
- const modularUI = useModularUI(key, href, useModularUIOptions);
54
+ const modularUI = useModularUI(key, memoizedHref, useModularUIOptions);
52
55
 
53
- if (modularUI?.model) {
54
- const { model } = modularUI;
56
+ const expectedModels = useMemo(
57
+ () => options.expectedModels ?? [],
58
+ [options.expectedModels],
59
+ );
55
60
 
56
- const expectedModels = options.expectedModels ?? [];
57
- if (expectedModels.length > 0) {
58
- const isCorrectModel = expectedModels.some((expectedModel) => {
59
- return model.type === expectedModel;
60
- });
61
+ return useMemo((): T | null => {
62
+ if (modularUI?.model) {
63
+ const { model } = modularUI;
61
64
 
62
- if (!isCorrectModel) {
63
- console.error(modularUI, "is not of instance", expectedModels);
64
- throw new IllegalStateException("Resolved model has incorrect type");
65
+ if (expectedModels.length > 0) {
66
+ const isCorrectModel = expectedModels.some(
67
+ (expectedModel) => model.type === expectedModel,
68
+ );
69
+ if (!isCorrectModel) {
70
+ console.error(modularUI, "is not of instance", expectedModels);
71
+ throw new IllegalStateException("Resolved model has incorrect type");
72
+ }
65
73
  }
66
- }
67
74
 
68
- return model;
69
- }
70
-
71
- return null;
75
+ return model;
76
+ }
77
+ return null;
78
+ }, [expectedModels, modularUI]);
72
79
  };
@@ -11,8 +11,8 @@ class ConceptTypeDetailModel extends ResourceModel {
11
11
  * The name of the concept type consists of the functional id of the kmt and the functional id of the concept type separated by a #.<br>
12
12
  * For example BEI_CaseManagement#Case
13
13
  */
14
- get name(): string {
15
- return this.getData("name", "");
14
+ get kmtId(): string {
15
+ return this.getData("kmtId", "");
16
16
  }
17
17
 
18
18
  /**
@@ -109,6 +109,7 @@ export const loadModel = (
109
109
  ): ModularUIAction => ({
110
110
  type: "MODULARUI/FETCH",
111
111
  payload: {
112
+ key,
112
113
  href: href instanceof Href ? href : new Href(href),
113
114
  method: options?.method ?? HTTP_METHODS.GET,
114
115
  data: options?.data,
@@ -146,20 +147,24 @@ export const loadModularUI =
146
147
  href: Href | string,
147
148
  options?: RequestModularUIOptions,
148
149
  ): ThunkAction =>
149
- (dispatch: Dispatch) => {
150
- dispatch(updateStatus(key, MODULARUI_STATUS.LOADING));
150
+ (dispatch: Dispatch, getState) => {
151
+ const modularuiStore = getState()?.modularui;
152
+ if (
153
+ modularuiStore &&
154
+ modularuiStore[key]?.status === MODULARUI_STATUS.LOADING
155
+ ) {
156
+ // don't create duplicate requests during loading
157
+ return dispatch({
158
+ type: "NO_ACTION",
159
+ });
160
+ }
161
+
151
162
  dispatch(startProgress());
152
163
 
153
164
  const loadModelPromise = dispatch(loadModel(key, href, options));
154
165
 
155
166
  return Promise.resolve(loadModelPromise)
156
- .then((response) => {
157
- if (response?.type === "FINISH_PROGRESS") {
158
- dispatch(updateStatus(key, MODULARUI_STATUS.FINISHED));
159
- }
160
-
161
- return dispatch(finishProgress());
162
- })
167
+ .then(() => dispatch(finishProgress()))
163
168
  .catch((error) => dispatch(handleError(error)));
164
169
  };
165
170
 
@@ -1,11 +1,12 @@
1
1
  // @flow
2
2
  import ModularUIRequest from "../../modularui/ModularUIRequest";
3
- import { HTTP_METHODS } from "../../constants/Constants";
3
+ import { HTTP_METHODS, MODULARUI_STATUS } from "../../constants/Constants";
4
4
 
5
5
  import { startProgress, finishProgress } from "../actions/ProgressIndicator";
6
-
7
6
  import { handleError } from "../actions/Error";
8
7
 
8
+ import { updateStatus } from "./ModularUIActions";
9
+
9
10
  import type { Middleware, MiddlewareAPI } from "redux";
10
11
  import type {
11
12
  ReduxAction,
@@ -117,11 +118,13 @@ const handleFetch = (
117
118
  ) => {
118
119
  dispatch(startProgress());
119
120
 
120
- const { successAction, errorAction, ...requestOptions } = action.payload;
121
+ const { key, successAction, errorAction, ...requestOptions } = action.payload;
121
122
  requestOptions.locale = locale;
122
123
 
123
124
  const modularuiRequest = createRequest(requestOptions);
124
125
 
126
+ dispatch(updateStatus(key, MODULARUI_STATUS.LOADING));
127
+
125
128
  return modularuiRequest
126
129
  .fetch()
127
130
  .then((model) => responseHandler(next, dispatch, successAction, model))
@@ -46,6 +46,7 @@ const setModel = (
46
46
  ...state[key],
47
47
  model,
48
48
  lastModification: Date.now(),
49
+ status: MODULARUI_STATUS.FINISHED,
49
50
  },
50
51
  };
51
52
  }
@@ -134,16 +134,13 @@ describe("modularui actions", () => {
134
134
  await store.dispatch(loadModularUI("application", "/", {}));
135
135
 
136
136
  expect(store.getActions()).toStrictEqual([
137
- {
138
- type: "MODULARUI/STATUS",
139
- payload: { key: "application", status: MODULARUI_STATUS.LOADING },
140
- },
141
137
  {
142
138
  type: "START_PROGRESS",
143
139
  },
144
140
  {
145
141
  type: "MODULARUI/FETCH",
146
142
  payload: expect.objectContaining({
143
+ key: "application",
147
144
  href: new Href("/"),
148
145
  method: HTTP_METHODS.GET,
149
146
  data: undefined,
@@ -65,6 +65,7 @@ export type ErrorAction = (
65
65
  export type ModularUIAction = {
66
66
  type: "MODULARUI/FETCH",
67
67
  payload: {
68
+ key: string,
68
69
  href: Href,
69
70
  method?: $Keys<HTTP_METHODS>,
70
71
  data?: any,
@@ -16,14 +16,11 @@ describe("application actions", () => {
16
16
  await store.dispatch(reloadApplication());
17
17
 
18
18
  expect(store.getActions()).toStrictEqual([
19
- {
20
- type: "MODULARUI/STATUS",
21
- payload: { key: "application(/)(en)", status: "LOADING" },
22
- },
23
19
  { type: "START_PROGRESS" },
24
20
  expect.objectContaining({
25
21
  type: "MODULARUI/FETCH",
26
22
  payload: expect.objectContaining({
23
+ key: "application(/)(en)",
27
24
  href: new Href("/", "Application"),
28
25
  }),
29
26
  }),
@@ -43,10 +40,6 @@ describe("application actions", () => {
43
40
  type: "MODULARUI/REMOVE_KEY",
44
41
  payload: "/",
45
42
  },
46
- {
47
- type: "MODULARUI/STATUS",
48
- payload: { key: "application(/)(en)", status: "LOADING" },
49
- },
50
43
  { type: "START_PROGRESS" },
51
44
  expect.objectContaining({
52
45
  type: "MODULARUI/FETCH",
@@ -43,10 +43,6 @@ describe("authorization actions", () => {
43
43
  type: "MODULARUI/REMOVE_KEY",
44
44
  payload: "/",
45
45
  },
46
- {
47
- type: "MODULARUI/STATUS",
48
- payload: { key: "application(/)(en)", status: "LOADING" },
49
- },
50
46
  {
51
47
  type: "START_PROGRESS",
52
48
  },