@headless-adminapp/app 1.3.0 → 1.4.0

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 (36) hide show
  1. package/app/LayoutProvider.js +1 -2
  2. package/dataform/DataFormProvider/InitialValueResolver.js +4 -2
  3. package/dataform/DataFormProvider/index.js +29 -3
  4. package/dataform/context.d.ts +10 -2
  5. package/dataform/hooks/useFormDataState.d.ts +4 -0
  6. package/dataform/hooks/useFormDataState.js +8 -0
  7. package/dataform/hooks/useIsDataFetching.d.ts +1 -0
  8. package/dataform/hooks/useIsDataFetching.js +8 -0
  9. package/dataform/utils/defaultParameters.d.ts +2 -2
  10. package/dataform/utils/defaultParameters.js +3 -18
  11. package/datagrid/DataGridProvider/index.js +33 -6
  12. package/datagrid/hooks/useOpenRecord.js +12 -13
  13. package/historystate/contex.d.ts +1 -0
  14. package/historystate/contex.js +5 -0
  15. package/historystate/index.d.ts +2 -0
  16. package/historystate/index.js +7 -0
  17. package/historystate/provider.d.ts +7 -0
  18. package/historystate/provider.js +17 -0
  19. package/historystate/useHistoryStateKey.d.ts +1 -0
  20. package/historystate/useHistoryStateKey.js +9 -0
  21. package/locale/LocaleProvider.d.ts +1 -0
  22. package/mutable/context.d.ts +1 -1
  23. package/mutable/type.d.ts +1 -1
  24. package/mutable/utils.d.ts +1 -1
  25. package/mutable/utils.js +5 -2
  26. package/navigation/hooks/useOpenForm.js +21 -4
  27. package/package.json +3 -2
  28. package/recordset/RecordSetProvider.js +22 -5
  29. package/recordset/hooks/useRecordSetSetter.d.ts +1 -0
  30. package/recordset/hooks/useRecordSetSetter.js +1 -0
  31. package/route/context.d.ts +5 -1
  32. package/store/HistoryState.d.ts +7 -0
  33. package/store/HistoryState.js +32 -0
  34. package/store/index.d.ts +1 -0
  35. package/store/index.js +1 -0
  36. package/transport/hooks/useRetriveRecords.js +1 -0
@@ -9,7 +9,6 @@ const dialog_1 = require("../dialog");
9
9
  const locale_1 = require("../locale");
10
10
  const metadata_1 = require("../metadata");
11
11
  const progress_indicator_1 = require("../progress-indicator");
12
- const recordset_1 = require("../recordset");
13
12
  const route_1 = require("../route");
14
13
  const toast_notification_1 = require("../toast-notification");
15
14
  const transport_1 = require("../transport");
@@ -40,6 +39,6 @@ const defaultDataService = {
40
39
  },
41
40
  };
42
41
  const LayoutProvider = ({ authPlaceholder, authProps, dataService = defaultDataService, fileService, localeProps, metadataProps, queryClient = defaults_1.queryClient, routeProps, children, containers: { DialogContainer, ProgressIndicatorContainer, ToastNotificationContainer, }, }) => {
43
- return ((0, jsx_runtime_1.jsx)(route_1.RouteProvider, { ...routeProps, children: (0, jsx_runtime_1.jsx)(react_query_1.QueryClientProvider, { client: queryClient, children: (0, jsx_runtime_1.jsx)(locale_1.LocaleProvider, { ...localeProps, children: (0, jsx_runtime_1.jsx)(metadata_1.MetadataProvider, { ...metadataProps, children: (0, jsx_runtime_1.jsx)(transport_1.DataServiceContext.Provider, { value: dataService, children: (0, jsx_runtime_1.jsx)(context_1.FileServiceContext.Provider, { value: fileService ?? null, children: (0, jsx_runtime_1.jsx)(dialog_1.DialogProvider, { children: (0, jsx_runtime_1.jsx)(progress_indicator_1.ProgressIndicatorProvider, { children: (0, jsx_runtime_1.jsxs)(toast_notification_1.ToastNotificationProvider, { children: [(0, jsx_runtime_1.jsx)(DialogContainer, {}), (0, jsx_runtime_1.jsx)(ProgressIndicatorContainer, {}), (0, jsx_runtime_1.jsx)(ToastNotificationContainer, {}), (0, jsx_runtime_1.jsx)(auth_1.AuthProvider, { ...authProps, children: (0, jsx_runtime_1.jsx)(AuthWrapper_1.AuthWrapper, { Placeholder: authPlaceholder, children: (0, jsx_runtime_1.jsx)(recordset_1.RecordSetProvider, { children: children }) }) })] }) }) }) }) }) }) }) }) }));
42
+ return ((0, jsx_runtime_1.jsx)(route_1.RouteProvider, { ...routeProps, children: (0, jsx_runtime_1.jsx)(react_query_1.QueryClientProvider, { client: queryClient, children: (0, jsx_runtime_1.jsx)(locale_1.LocaleProvider, { ...localeProps, children: (0, jsx_runtime_1.jsx)(metadata_1.MetadataProvider, { ...metadataProps, children: (0, jsx_runtime_1.jsx)(transport_1.DataServiceContext.Provider, { value: dataService, children: (0, jsx_runtime_1.jsx)(context_1.FileServiceContext.Provider, { value: fileService ?? null, children: (0, jsx_runtime_1.jsx)(dialog_1.DialogProvider, { children: (0, jsx_runtime_1.jsx)(progress_indicator_1.ProgressIndicatorProvider, { children: (0, jsx_runtime_1.jsxs)(toast_notification_1.ToastNotificationProvider, { children: [(0, jsx_runtime_1.jsx)(DialogContainer, {}), (0, jsx_runtime_1.jsx)(ProgressIndicatorContainer, {}), (0, jsx_runtime_1.jsx)(ToastNotificationContainer, {}), (0, jsx_runtime_1.jsx)(auth_1.AuthProvider, { ...authProps, children: (0, jsx_runtime_1.jsx)(AuthWrapper_1.AuthWrapper, { Placeholder: authPlaceholder, children: children }) })] }) }) }) }) }) }) }) }) }));
44
43
  };
45
44
  exports.LayoutProvider = LayoutProvider;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.InitialValueResolver = InitialValueResolver;
4
+ const route_1 = require("@headless-adminapp/app/route");
4
5
  const react_1 = require("react");
5
6
  const mutable_1 = require("../../mutable");
6
7
  const context_1 = require("../context");
@@ -13,8 +14,9 @@ function InitialValueResolver() {
13
14
  const recordId = (0, hooks_1.useRecordId)();
14
15
  const record = (0, mutable_1.useContextSelector)(context_1.DataFormContext, (state) => state.record);
15
16
  const formInstance = (0, hooks_1.useFormInstance)();
17
+ const router = (0, route_1.useRouter)();
16
18
  const initialValues = (0, react_1.useMemo)(() => {
17
- const defaultParameters = (0, defaultParameters_1.getFormDefaultParameters)(schema, formConfig.experience) ?? {};
19
+ const defaultParameters = (0, defaultParameters_1.getFormDefaultParameters)(schema, formConfig.experience, router) ?? {};
18
20
  return (0, utils_1.getInitialValues)({
19
21
  cloneRecord: undefined,
20
22
  form: formConfig,
@@ -23,7 +25,7 @@ function InitialValueResolver() {
23
25
  schema: schema,
24
26
  defaultParameters,
25
27
  });
26
- }, [formConfig, record, recordId, schema]);
28
+ }, [formConfig, record, recordId, schema, router]);
27
29
  const setValue = (0, mutable_1.useContextSetValue)(context_1.DataFormContext);
28
30
  (0, react_1.useEffect)(() => {
29
31
  setValue({
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DataFormProvider = DataFormProvider;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const historystate_1 = require("@headless-adminapp/app/historystate");
6
+ const route_1 = require("@headless-adminapp/app/route");
5
7
  const store_1 = require("@headless-adminapp/app/store");
6
8
  const react_1 = require("react");
7
9
  const react_hook_form_1 = require("react-hook-form");
@@ -18,12 +20,20 @@ const getRecord_1 = require("./getRecord");
18
20
  const InitialValueResolver_1 = require("./InitialValueResolver");
19
21
  const ReadonlyInfoResolver_1 = require("./ReadonlyInfoResolver");
20
22
  const utils_2 = require("./utils");
23
+ function mergeInitialWithHistory(initialValue, historyState) {
24
+ return {
25
+ ...initialValue,
26
+ ...historyState,
27
+ };
28
+ }
21
29
  function DataFormProvider(props) {
22
30
  const { schemaStore } = (0, useMetadata_1.useMetadata)();
23
31
  const { language, region } = (0, useLocale_1.useLocale)();
24
32
  const formValidationStrings = (0, FormValidationStringContext_1.useFormValidationStrings)();
25
33
  const eventManager = (0, react_1.useMemo)(() => new store_1.EventManager(), []);
26
34
  const contextKey = (0, react_1.useRef)(0);
35
+ const router = (0, route_1.useRouter)();
36
+ const historyKey = (0, historystate_1.useHistoryStateKey)();
27
37
  const [formReadOnly, setFormReadOnly] = (0, react_1.useState)(false); // A trick to provide readOnly info to formInstance
28
38
  const formInstance = (0, react_hook_form_1.useForm)({
29
39
  mode: 'all',
@@ -46,12 +56,12 @@ function DataFormProvider(props) {
46
56
  ? saveRecordFnRef.current(options)
47
57
  : (0, saveRecord_1.saveRecord)(options);
48
58
  }, []);
49
- const contextValue = (0, mutable_1.useCreateContextStore)({
59
+ const contextValue = (0, mutable_1.useCreateContextStore)(() => mergeInitialWithHistory({
50
60
  contextKey: contextKey.current,
51
61
  schema: props.schema,
52
62
  form: props.form,
53
63
  commands: props.commands,
54
- dataState: { isFetching: false },
64
+ dataState: { isFetching: true },
55
65
  recordId: props.recordId,
56
66
  refresh: async () => { }, // Initial value, will be overridden
57
67
  cloneId: undefined,
@@ -59,6 +69,8 @@ function DataFormProvider(props) {
59
69
  // formInstanceRenderCount: 0,
60
70
  initialValues: {},
61
71
  saveRecordFn: saveRecordFnInternal,
72
+ activeTab: props.form.experience.tabs[0]?.name,
73
+ selectedRelatedItem: null,
62
74
  eventManager,
63
75
  disabledControls: {},
64
76
  requiredFields: {},
@@ -66,7 +78,21 @@ function DataFormProvider(props) {
66
78
  hiddenSections: {},
67
79
  hiddenTabs: {},
68
80
  formInternal: (0, utils_2.transformFormInternal)(props.form),
69
- });
81
+ }, router.getState(historyKey)));
82
+ (0, react_1.useEffect)(() => {
83
+ function listener(state, prevState, changes) {
84
+ if (['activeTab', 'selectedRelatedItem'].some((key) => key in changes)) {
85
+ router.setState(historyKey, {
86
+ activeTab: state.activeTab,
87
+ selectedRelatedItem: state.selectedRelatedItem,
88
+ });
89
+ }
90
+ }
91
+ contextValue.addListener(listener);
92
+ return () => {
93
+ contextValue.removeListener(listener);
94
+ };
95
+ }, [contextValue, historyKey, router]);
70
96
  (0, react_1.useEffect)(() => {
71
97
  contextValue.setValue({
72
98
  contextKey: ++contextKey.current,
@@ -4,8 +4,15 @@ import { Tab } from '@headless-adminapp/core/experience/form/Tab';
4
4
  import { InferredSchemaType, Schema, SchemaAttributes } from '@headless-adminapp/core/schema';
5
5
  import { IEventManager } from '@headless-adminapp/core/store';
6
6
  import { Data } from '@headless-adminapp/core/transport';
7
- import { Nullable } from '@headless-adminapp/core/types';
7
+ import { Localized, Nullable } from '@headless-adminapp/core/types';
8
8
  import { SaveRecordFn } from './utils/saveRecord';
9
+ export interface RelatedItemInfo {
10
+ key: string;
11
+ logicalName: string;
12
+ pluralLabel: string;
13
+ localizedPluralLabels?: Localized<string>;
14
+ attributeName: string;
15
+ }
9
16
  export type DataFormContextState<SA extends SchemaAttributes = SchemaAttributes> = {
10
17
  contextKey: number;
11
18
  schema: Schema<SA>;
@@ -14,7 +21,8 @@ export type DataFormContextState<SA extends SchemaAttributes = SchemaAttributes>
14
21
  cloneId?: string | number;
15
22
  commands: EntityMainFormCommandItemExperience[][];
16
23
  saveRecordFn: SaveRecordFn;
17
- activeTab?: string;
24
+ activeTab: string;
25
+ selectedRelatedItem: RelatedItemInfo | null;
18
26
  disabledControls: Record<string, boolean>;
19
27
  requiredFields: Record<string, boolean>;
20
28
  hiddenControls: Record<string, boolean>;
@@ -0,0 +1,4 @@
1
+ export declare function useFormDataState(): {
2
+ isFetching: boolean;
3
+ isError?: boolean;
4
+ };
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useFormDataState = useFormDataState;
4
+ const mutable_1 = require("@headless-adminapp/app/mutable");
5
+ const context_1 = require("../context");
6
+ function useFormDataState() {
7
+ return (0, mutable_1.useContextSelector)(context_1.DataFormContext, (state) => state.dataState);
8
+ }
@@ -0,0 +1 @@
1
+ export declare function useIsFormDataFetching(): boolean;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useIsFormDataFetching = useIsFormDataFetching;
4
+ const mutable_1 = require("@headless-adminapp/app/mutable");
5
+ const context_1 = require("../context");
6
+ function useIsFormDataFetching() {
7
+ return (0, mutable_1.useContextSelector)(context_1.DataFormContext, (state) => state.dataState.isFetching);
8
+ }
@@ -1,6 +1,6 @@
1
+ import { RouterInstance } from '@headless-adminapp/app/route/context';
1
2
  import { FormExperience } from '@headless-adminapp/core/experience/form';
2
3
  import { Schema } from '@headless-adminapp/core/schema';
3
- export declare function getFormDefaultParameters(schema: Schema, formExperience: FormExperience): {
4
+ export declare function getFormDefaultParameters(schema: Schema, formExperience: FormExperience, router: RouterInstance): {
4
5
  [x: string]: any;
5
6
  };
6
- export declare function setFormDefaultParameters(logicalName: string, values: Record<string, any>): void;
@@ -1,11 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getFormDefaultParameters = getFormDefaultParameters;
4
- exports.setFormDefaultParameters = setFormDefaultParameters;
5
- let formDefaultParameters = null;
6
- function getFormDefaultParameters(schema, formExperience) {
7
- const _values = formDefaultParameters?.values;
8
- const _logicalName = formDefaultParameters?.logicalName;
4
+ function getFormDefaultParameters(schema, formExperience, router) {
5
+ const _values = router.getState('defaultParameters')?.values;
6
+ const _logicalName = router.getState('defaultParameters')?.logicalName;
9
7
  const schemaDefaultValues = Object.keys(schema.attributes).reduce((acc, key) => {
10
8
  const attribute = schema.attributes[key];
11
9
  let defaultValue = attribute.default;
@@ -39,16 +37,3 @@ function getFormDefaultParameters(schema, formExperience) {
39
37
  }
40
38
  return defaultValues;
41
39
  }
42
- let defaultParamsTimeout = null;
43
- function setFormDefaultParameters(logicalName, values) {
44
- formDefaultParameters = {
45
- logicalName,
46
- values,
47
- };
48
- if (defaultParamsTimeout) {
49
- clearTimeout(defaultParamsTimeout);
50
- }
51
- defaultParamsTimeout = setTimeout(() => {
52
- formDefaultParameters = null;
53
- }, 5000);
54
- }
@@ -2,22 +2,33 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DataGridProvider = DataGridProvider;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const route_1 = require("@headless-adminapp/app/route");
5
6
  const react_1 = require("react");
7
+ const react_use_1 = require("react-use");
8
+ const historystate_1 = require("../../historystate");
6
9
  const useLocale_1 = require("../../locale/useLocale");
7
10
  const useMetadata_1 = require("../../metadata/hooks/useMetadata");
8
11
  const context_1 = require("../../mutable/context");
9
12
  const context_2 = require("../context");
10
13
  const DataResolver_1 = require("./DataResolver");
11
14
  const transformViewColumns_1 = require("./transformViewColumns");
15
+ function mergeInitialStateWithHistory(initialValue, historyState) {
16
+ return {
17
+ ...initialValue,
18
+ ...historyState,
19
+ };
20
+ }
12
21
  function DataGridProvider(props) {
13
22
  const onChangeViewRef = (0, react_1.useRef)(props.onChangeView);
14
23
  onChangeViewRef.current = props.onChangeView;
15
24
  const { schemaStore } = (0, useMetadata_1.useMetadata)();
16
25
  const { language } = (0, useLocale_1.useLocale)();
26
+ const router = (0, route_1.useRouter)();
17
27
  const handleViewChange = (0, react_1.useCallback)((viewId) => {
18
28
  onChangeViewRef.current?.(viewId);
19
29
  }, []);
20
- const contextValue = (0, context_1.useCreateContextStore)({
30
+ const historyKey = (0, historystate_1.useHistoryStateKey)();
31
+ const contextValue = (0, context_1.useCreateContextStore)(() => mergeInitialStateWithHistory({
21
32
  schema: props.schema,
22
33
  columnFilters: {},
23
34
  data: {
@@ -46,8 +57,24 @@ function DataGridProvider(props) {
46
57
  maxRecords: props.maxRecords,
47
58
  associated: props.associated,
48
59
  disabled: props.disabled ?? false,
49
- });
60
+ }, router.getState(historyKey)));
50
61
  (0, react_1.useEffect)(() => {
62
+ function listener(state, prevState, changes) {
63
+ if (['searchText', 'columnFilters', 'sorting', 'columns'].some((key) => key in changes)) {
64
+ router.setState(historyKey, {
65
+ searchText: state.searchText,
66
+ columnFilters: state.columnFilters,
67
+ sorting: state.sorting,
68
+ columns: state.columns,
69
+ });
70
+ }
71
+ }
72
+ contextValue.addListener(listener);
73
+ return () => {
74
+ contextValue.removeListener(listener);
75
+ };
76
+ }, [contextValue, historyKey, router]);
77
+ (0, react_use_1.useUpdateEffect)(() => {
51
78
  contextValue.setValue({
52
79
  view: props.view,
53
80
  searchText: '',
@@ -58,24 +85,24 @@ function DataGridProvider(props) {
58
85
  maxRecords: props.maxRecords,
59
86
  });
60
87
  }, [props.view, props.maxRecords, contextValue, schemaStore, language]);
61
- (0, react_1.useEffect)(() => {
88
+ (0, react_use_1.useUpdateEffect)(() => {
62
89
  contextValue.setValue({
63
90
  schema: props.schema,
64
91
  searchText: '',
65
92
  selectedIds: [],
66
93
  });
67
94
  }, [props.schema, contextValue]);
68
- (0, react_1.useEffect)(() => {
95
+ (0, react_use_1.useUpdateEffect)(() => {
69
96
  contextValue.setValue({
70
97
  extraFilter: props.extraFilter,
71
98
  });
72
99
  }, [props.extraFilter, contextValue]);
73
- (0, react_1.useEffect)(() => {
100
+ (0, react_use_1.useUpdateEffect)(() => {
74
101
  contextValue.setValue({
75
102
  commands: props.commands,
76
103
  });
77
104
  }, [props.commands, contextValue]);
78
- (0, react_1.useEffect)(() => {
105
+ (0, react_use_1.useUpdateEffect)(() => {
79
106
  contextValue.setValue({
80
107
  isSubGrid: props.isSubGrid ?? false,
81
108
  associated: props.associated,
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useOpenRecord = useOpenRecord;
4
- const recordset_1 = require("@headless-adminapp/app/recordset");
5
4
  const route_1 = require("@headless-adminapp/app/route");
6
5
  const app_1 = require("@headless-adminapp/core/experience/app");
7
6
  const react_1 = require("react");
@@ -12,7 +11,6 @@ function useOpenRecord() {
12
11
  const schema = (0, useGridSchema_1.useDataGridSchema)();
13
12
  const routeResolver = (0, route_1.useRouteResolver)();
14
13
  const router = (0, route_1.useRouter)();
15
- const recordSetSetter = (0, recordset_1.useRecordSetSetter)();
16
14
  const dataRef = (0, react_1.useRef)(data);
17
15
  dataRef.current = data;
18
16
  return (0, react_1.useCallback)((id, logicalName) => {
@@ -21,15 +19,16 @@ function useOpenRecord() {
21
19
  type: app_1.PageType.EntityForm,
22
20
  id,
23
21
  });
24
- if (logicalName === schema.logicalName) {
25
- recordSetSetter(schema.logicalName, dataRef.current?.records.map((x) => x[schema.idAttribute]) ?? []);
26
- }
27
- router.push(path);
28
- }, [
29
- recordSetSetter,
30
- routeResolver,
31
- router,
32
- schema.idAttribute,
33
- schema.logicalName,
34
- ]);
22
+ router.push(path, {
23
+ state: {
24
+ navigator: logicalName === schema.logicalName
25
+ ? {
26
+ ids: dataRef.current?.records.map((x) => x[schema.idAttribute]) ?? [],
27
+ visible: false,
28
+ logicalName: schema.logicalName,
29
+ }
30
+ : null,
31
+ },
32
+ });
33
+ }, [routeResolver, router, schema.idAttribute, schema.logicalName]);
35
34
  }
@@ -0,0 +1 @@
1
+ export declare const HistoryStateKeyContext: import("react").Context<string>;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HistoryStateKeyContext = void 0;
4
+ const react_1 = require("react");
5
+ exports.HistoryStateKeyContext = (0, react_1.createContext)('');
@@ -0,0 +1,2 @@
1
+ export { HistoryStateKeyProvider } from './provider';
2
+ export { useHistoryStateKey } from './useHistoryStateKey';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useHistoryStateKey = exports.HistoryStateKeyProvider = void 0;
4
+ var provider_1 = require("./provider");
5
+ Object.defineProperty(exports, "HistoryStateKeyProvider", { enumerable: true, get: function () { return provider_1.HistoryStateKeyProvider; } });
6
+ var useHistoryStateKey_1 = require("./useHistoryStateKey");
7
+ Object.defineProperty(exports, "useHistoryStateKey", { enumerable: true, get: function () { return useHistoryStateKey_1.useHistoryStateKey; } });
@@ -0,0 +1,7 @@
1
+ import { FC, PropsWithChildren } from 'react';
2
+ type HistoryStateKeyProviderProps = {
3
+ historyKey: string;
4
+ nested?: boolean;
5
+ };
6
+ export declare const HistoryStateKeyProvider: FC<PropsWithChildren<HistoryStateKeyProviderProps>>;
7
+ export {};
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HistoryStateKeyProvider = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const contex_1 = require("./contex");
6
+ const useHistoryStateKey_1 = require("./useHistoryStateKey");
7
+ const HistoryStateKeyProvider = ({ historyKey, nested, children }) => {
8
+ const parentHistoryKey = (0, useHistoryStateKey_1.useHistoryStateKey)();
9
+ if (nested) {
10
+ if (!parentHistoryKey || parentHistoryKey.startsWith('~')) {
11
+ return children;
12
+ }
13
+ historyKey = `${parentHistoryKey}.${historyKey}`;
14
+ }
15
+ return ((0, jsx_runtime_1.jsx)(contex_1.HistoryStateKeyContext.Provider, { value: historyKey, children: children }));
16
+ };
17
+ exports.HistoryStateKeyProvider = HistoryStateKeyProvider;
@@ -0,0 +1 @@
1
+ export declare function useHistoryStateKey(): string;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useHistoryStateKey = useHistoryStateKey;
4
+ const react_1 = require("react");
5
+ const contex_1 = require("./contex");
6
+ function useHistoryStateKey() {
7
+ const historyKey = (0, react_1.useContext)(contex_1.HistoryStateKeyContext);
8
+ return historyKey;
9
+ }
@@ -6,6 +6,7 @@ export interface LocaleProviderProps {
6
6
  options?: {
7
7
  direction?: Locale['direction'];
8
8
  dateFormats?: Locale['dateFormats'];
9
+ dateRangeFormats?: Locale['dateRangeFormats'];
9
10
  timeFormats?: Locale['timeFormats'];
10
11
  currency?: Partial<Locale['currency']>;
11
12
  };
@@ -3,7 +3,7 @@ import { useMutableValueSelector } from './utils';
3
3
  export type ContextValue<T> = MutableValue<T>;
4
4
  export declare const useContextSelectorInternal: typeof useMutableValueSelector;
5
5
  export declare function createContext<T>(): import("react").Context<ContextValue<T>>;
6
- export declare function useCreateContextStore<T>(initialValue: T): MutableValue<T>;
6
+ export declare function useCreateContextStore<T>(initialValue: T | (() => T)): MutableValue<T>;
7
7
  export declare function useContextValue<T>(context: React.Context<ContextValue<T>>): {
8
8
  current: T;
9
9
  };
package/mutable/type.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- type Listener<T> = (state: T) => void;
1
+ type Listener<T> = (newState: T, prevState: T, changes: Partial<T>) => void;
2
2
  export interface MutableValue<T> {
3
3
  value: {
4
4
  current: T;
@@ -1,3 +1,3 @@
1
1
  import { MutableValue } from './type';
2
- export declare function createMutableValue<T>(initialValue: T, isArray?: boolean): MutableValue<T>;
2
+ export declare function createMutableValue<T>(initialValue: T | (() => T), isArray?: boolean): MutableValue<T>;
3
3
  export declare function useMutableValueSelector<T, R>(mutableValue: MutableValue<T>, selector: (state: T) => R): R;
package/mutable/utils.js CHANGED
@@ -5,7 +5,9 @@ exports.useMutableValueSelector = useMutableValueSelector;
5
5
  const react_1 = require("react");
6
6
  function createMutableValue(initialValue, isArray) {
7
7
  let storeValue = {
8
- current: initialValue,
8
+ current: typeof initialValue === 'function'
9
+ ? initialValue()
10
+ : initialValue,
9
11
  };
10
12
  const listeners = new Set();
11
13
  return {
@@ -14,13 +16,14 @@ function createMutableValue(initialValue, isArray) {
14
16
  if (typeof value === 'function') {
15
17
  value = value(storeValue.current);
16
18
  }
19
+ const prevState = storeValue.current;
17
20
  if (isArray) {
18
21
  storeValue.current = value;
19
22
  }
20
23
  else {
21
24
  storeValue.current = { ...storeValue.current, ...value };
22
25
  }
23
- listeners.forEach((listener) => listener(storeValue.current));
26
+ listeners.forEach((listener) => listener(storeValue.current, prevState, value));
24
27
  },
25
28
  listeners,
26
29
  addListener: (listener) => listeners.add(listener),
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useOpenForm = useOpenForm;
4
- const defaultParameters_1 = require("@headless-adminapp/app/dataform/utils/defaultParameters");
5
4
  const app_1 = require("@headless-adminapp/core/experience/app");
6
5
  const react_1 = require("react");
7
6
  const hooks_1 = require("../../route/hooks/");
@@ -15,14 +14,32 @@ function useOpenForm() {
15
14
  type: app_1.PageType.EntityForm,
16
15
  id: options.id,
17
16
  });
17
+ const state = {};
18
18
  if (options.parameters) {
19
- (0, defaultParameters_1.setFormDefaultParameters)(options.logicalName, options.parameters);
19
+ state.defaultParameters = {
20
+ logicalName: options.logicalName,
21
+ values: options.parameters,
22
+ };
23
+ }
24
+ if (options.recordSetIds) {
25
+ state.navigator = {
26
+ ids: options.recordSetIds,
27
+ visible: false,
28
+ logicalName: options.logicalName,
29
+ };
20
30
  }
21
31
  if (options.replace) {
22
- router.replace(path);
32
+ router.replace(path, {
33
+ state: {
34
+ ...router.getState(),
35
+ ...state,
36
+ },
37
+ });
23
38
  }
24
39
  else {
25
- router.push(path);
40
+ router.push(path, {
41
+ state,
42
+ });
26
43
  }
27
44
  }, [routeResolver, router]);
28
45
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@headless-adminapp/app",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -34,8 +34,9 @@
34
34
  "lodash": "^4.17.21",
35
35
  "react-custom-scrollbars-2": "^4.5.0",
36
36
  "react-hook-form": "7.52.2",
37
+ "react-use": "17.6.0",
37
38
  "uuid": "11.0.3",
38
39
  "yup": "^1.4.0"
39
40
  },
40
- "gitHead": "bd466c5f536131bd6e2ff2241c1b5a48883f68c2"
41
+ "gitHead": "a064c301b98e340b142e8daeac078b4cdf5ad99a"
41
42
  }
@@ -5,14 +5,31 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const useMetadata_1 = require("../metadata/hooks/useMetadata");
7
7
  const context_1 = require("../mutable/context");
8
+ const route_1 = require("../route");
8
9
  const context_2 = require("./context");
9
10
  const RecordSetProvider = ({ children }) => {
10
- const contextValue = (0, context_1.useCreateContextStore)({
11
- logicalName: '',
12
- ids: [],
11
+ const router = (0, route_1.useRouter)();
12
+ const contextValue = (0, context_1.useCreateContextStore)(() => ({
13
+ logicalName: router.getState('navigator')?.logicalName ?? '',
14
+ ids: router.getState('navigator')?.ids ?? [],
13
15
  cardView: null,
14
- visibleNavigator: false,
15
- });
16
+ visibleNavigator: router.getState('navigator')?.visible ?? false,
17
+ }));
18
+ (0, react_1.useEffect)(() => {
19
+ function listener(state, prevState, changes) {
20
+ if (['ids', 'logicalName', 'visibleNavigator'].some((key) => key in changes)) {
21
+ router.setState('navigator', {
22
+ logicalName: state.logicalName,
23
+ ids: state.ids,
24
+ visible: state.visibleNavigator,
25
+ });
26
+ }
27
+ }
28
+ contextValue.addListener(listener);
29
+ return () => {
30
+ contextValue.removeListener(listener);
31
+ };
32
+ }, [contextValue, router]);
16
33
  return ((0, jsx_runtime_1.jsxs)(context_2.RecordSetContext.Provider, { value: contextValue, children: [(0, jsx_runtime_1.jsx)(CardViewSetter, {}), children] }));
17
34
  };
18
35
  exports.RecordSetProvider = RecordSetProvider;
@@ -1 +1,2 @@
1
+ /*** @deprecated */
1
2
  export declare function useRecordSetSetter(): (logicalName: string, ids: (string | number)[]) => void;
@@ -4,6 +4,7 @@ exports.useRecordSetSetter = useRecordSetSetter;
4
4
  const react_1 = require("react");
5
5
  const context_1 = require("../../mutable/context");
6
6
  const context_2 = require("../context");
7
+ /*** @deprecated */
7
8
  function useRecordSetSetter() {
8
9
  const setValue = (0, context_1.useContextSetValue)(context_2.RecordSetContext);
9
10
  const setRecordSet = (0, react_1.useCallback)((logicalName, ids) => {
@@ -3,7 +3,7 @@ import { ReadonlyURLSearchParams } from './types';
3
3
  export type InternalRouteResolver = (item: NavPageItem) => string;
4
4
  export type InternalIsRouteActive = (path: string, item: NavPageItem) => boolean;
5
5
  interface NavigateOptions {
6
- scroll?: boolean;
6
+ state?: any;
7
7
  }
8
8
  export interface RouterInstance {
9
9
  back: () => void;
@@ -11,6 +11,10 @@ export interface RouterInstance {
11
11
  push(href: string, options?: NavigateOptions): void;
12
12
  replace(href: string, options?: NavigateOptions): void;
13
13
  prefetch(href: string): void;
14
+ setState(state: any): void;
15
+ setState(key: string, state: any): void;
16
+ getState<T = any>(): T;
17
+ getState<T = any>(key: string): T | undefined;
14
18
  }
15
19
  export declare const RouterContext: import("react").Context<RouterInstance>;
16
20
  export declare const RouterPathnameContext: import("react").Context<string>;
@@ -0,0 +1,7 @@
1
+ export interface HistoryStatePlugin {
2
+ getter: () => Record<string, Record<string, unknown>>;
3
+ setter: (value: Record<string, Record<string, unknown>>) => void;
4
+ }
5
+ export declare function registerHistoryStatePlugin(plugin: HistoryStatePlugin): void;
6
+ export declare function getHistoryState<T extends Record<string, unknown> = Record<string, unknown>>(key: string): Partial<T>;
7
+ export declare function setHistoryState(key: string, value: Record<string, unknown>): void;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerHistoryStatePlugin = registerHistoryStatePlugin;
4
+ exports.getHistoryState = getHistoryState;
5
+ exports.setHistoryState = setHistoryState;
6
+ let historyStatePlugin = null;
7
+ function registerHistoryStatePlugin(plugin) {
8
+ historyStatePlugin = plugin;
9
+ }
10
+ function getHistoryState(key) {
11
+ if (!historyStatePlugin) {
12
+ return {};
13
+ }
14
+ if (!key || typeof key !== 'string' || key.startsWith('~')) {
15
+ return {};
16
+ }
17
+ const state = historyStatePlugin.getter();
18
+ return (state[key] || {});
19
+ }
20
+ function setHistoryState(key, value) {
21
+ if (!historyStatePlugin) {
22
+ return;
23
+ }
24
+ const currentState = historyStatePlugin.getter();
25
+ historyStatePlugin.setter({
26
+ ...currentState,
27
+ [key]: {
28
+ ...currentState[key],
29
+ ...value,
30
+ },
31
+ });
32
+ }
package/store/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './ComponentStore';
2
2
  export * from './EventManager';
3
3
  export * from './SchemaExperienceStore';
4
+ export * from './HistoryState';
package/store/index.js CHANGED
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./ComponentStore"), exports);
18
18
  __exportStar(require("./EventManager"), exports);
19
19
  __exportStar(require("./SchemaExperienceStore"), exports);
20
+ __exportStar(require("./HistoryState"), exports);
@@ -97,6 +97,7 @@ function useRetriveRecordsInternal(queryKey, { columns, expand, filter, maxRecor
97
97
  pageIndex: 0,
98
98
  },
99
99
  enabled: !disabled,
100
+ staleTime: 1000 * 60 * 5, // 5 minutes
100
101
  });
101
102
  const finalData = (0, react_1.useMemo)(() => {
102
103
  if (!data?.pages.length) {