@headless-adminapp/fluent 1.3.3 → 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 (62) hide show
  1. package/DataGrid/GridListContainer.js +2 -5
  2. package/DataGrid/GridTableContainer.js +2 -5
  3. package/DataGrid/useTableColumns.js +6 -14
  4. package/PageEntityForm/CommandContainer.d.ts +5 -1
  5. package/PageEntityForm/CommandContainer.js +33 -4
  6. package/PageEntityForm/FormTabRelated.d.ts +1 -1
  7. package/PageEntityForm/FormTabRelated.js +7 -5
  8. package/PageEntityForm/PageEntityForm.js +9 -7
  9. package/PageEntityForm/PageEntityFormDesktopContainer.js +24 -41
  10. package/PageEntityForm/ProcessFlow.d.ts +2 -1
  11. package/PageEntityForm/ProcessFlow.js +27 -12
  12. package/PageEntityForm/RecordAvatar.js +14 -0
  13. package/PageEntityForm/RelatedViewSelector.d.ts +1 -8
  14. package/PageEntityForm/SectionContainer.d.ts +2 -1
  15. package/PageEntityForm/SectionContainer.js +11 -9
  16. package/PageEntityForm/StandardControl.js +17 -36
  17. package/PageEntityView/PageEntityView.js +2 -1
  18. package/Skeleton/TextSkeleton.d.ts +10 -0
  19. package/Skeleton/TextSkeleton.js +21 -0
  20. package/form/controls/AttachmentControl.js +10 -3
  21. package/form/controls/AttachmentsControl.js +5 -1
  22. package/form/controls/CurrencyControl.d.ts +1 -1
  23. package/form/controls/CurrencyControl.js +5 -1
  24. package/form/controls/DateControl.d.ts +1 -1
  25. package/form/controls/DateControl.js +5 -1
  26. package/form/controls/DateRangeControl/DateRangeControl.d.ts +1 -1
  27. package/form/controls/DateRangeControl/DateRangeControl.js +5 -1
  28. package/form/controls/DateTimeControl.d.ts +1 -1
  29. package/form/controls/DateTimeControl.js +9 -1
  30. package/form/controls/DecimalControl.d.ts +1 -1
  31. package/form/controls/DecimalControl.js +5 -1
  32. package/form/controls/DurationControl.js +5 -1
  33. package/form/controls/EmailControl.d.ts +1 -1
  34. package/form/controls/EmailControl.js +5 -1
  35. package/form/controls/IdControl.d.ts +1 -1
  36. package/form/controls/IdControl.js +5 -1
  37. package/form/controls/IntegerControl.d.ts +1 -1
  38. package/form/controls/IntegerControl.js +5 -1
  39. package/form/controls/LookupControl.js +5 -1
  40. package/form/controls/MultiSelectControl.d.ts +1 -1
  41. package/form/controls/MultiSelectControl.js +5 -1
  42. package/form/controls/MultiSelectLookupControl.js +5 -1
  43. package/form/controls/RegardingControl.js +5 -1
  44. package/form/controls/RichTextControl.js +5 -1
  45. package/form/controls/SelectControl.d.ts +1 -1
  46. package/form/controls/SelectControl.js +5 -1
  47. package/form/controls/SkeletonControl.d.ts +7 -0
  48. package/form/controls/SkeletonControl.js +18 -0
  49. package/form/controls/SwitchControl.d.ts +1 -1
  50. package/form/controls/SwitchControl.js +5 -1
  51. package/form/controls/TelephoneControl.d.ts +1 -1
  52. package/form/controls/TelephoneControl.js +5 -1
  53. package/form/controls/TextAreaControl.d.ts +1 -1
  54. package/form/controls/TextAreaControl.js +5 -1
  55. package/form/controls/TextControl.d.ts +1 -1
  56. package/form/controls/TextControl.js +5 -1
  57. package/form/controls/TimeControl/TimeControl.d.ts +1 -1
  58. package/form/controls/TimeControl/TimeControl.js +5 -1
  59. package/form/controls/UrlControl.d.ts +1 -1
  60. package/form/controls/UrlControl.js +5 -1
  61. package/form/controls/types.d.ts +1 -0
  62. package/package.json +2 -2
@@ -9,7 +9,6 @@ const hooks_1 = require("@headless-adminapp/app/datagrid/hooks");
9
9
  const locale_1 = require("@headless-adminapp/app/locale");
10
10
  const mutable_1 = require("@headless-adminapp/app/mutable");
11
11
  const navigation_1 = require("@headless-adminapp/app/navigation");
12
- const hooks_2 = require("@headless-adminapp/app/recordset/hooks");
13
12
  const react_virtual_1 = require("@tanstack/react-virtual");
14
13
  const react_1 = require("react");
15
14
  const uuid_1 = require("uuid");
@@ -50,16 +49,14 @@ const GridListContainer = () => {
50
49
  });
51
50
  const virtualItems = virtualizer.getVirtualItems();
52
51
  const virtualSize = virtualizer.getTotalSize();
53
- const recordSetSetter = (0, hooks_2.useRecordSetSetter)();
54
52
  const openFormInternal = (0, navigation_1.useOpenForm)();
55
53
  const openRecord = (0, react_1.useCallback)((id) => {
56
- recordSetSetter(schema.logicalName, dataRef.current?.records.map((x) => x[schema.idAttribute]) ??
57
- []);
58
54
  openFormInternal({
59
55
  logicalName: schema.logicalName,
60
56
  id,
57
+ recordSetIds: dataRef.current?.records.map((x) => x[schema.idAttribute]) ?? [],
61
58
  });
62
- }, [openFormInternal, recordSetSetter, schema.idAttribute, schema.logicalName]);
59
+ }, [openFormInternal, schema.idAttribute, schema.logicalName]);
63
60
  return ((0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flex: 1, flexDirection: 'column' }, children: (0, jsx_runtime_1.jsx)(ScrollbarWithMoreDataRequest_1.ScrollbarWithMoreDataRequest, { data: data?.records, hasMore: dataState?.hasNextPage, rtl: direction === 'rtl', onRequestMore: () => {
64
61
  fetchNextPage();
65
62
  }, children: (0, jsx_runtime_1.jsx)("div", { style: {
@@ -9,7 +9,6 @@ const hooks_1 = require("@headless-adminapp/app/datagrid/hooks");
9
9
  const locale_1 = require("@headless-adminapp/app/locale");
10
10
  const mutable_1 = require("@headless-adminapp/app/mutable");
11
11
  const navigation_1 = require("@headless-adminapp/app/navigation");
12
- const hooks_2 = require("@headless-adminapp/app/recordset/hooks");
13
12
  const icons_1 = require("@headless-adminapp/icons");
14
13
  const react_table_1 = require("@tanstack/react-table");
15
14
  const react_virtual_1 = require("@tanstack/react-virtual");
@@ -99,16 +98,14 @@ const GridTableContainer = ({ noPadding, disableColumnFilter, disableColumnSort,
99
98
  }));
100
99
  }, [sorting]);
101
100
  const tableWrapperRef = (0, react_1.useRef)(null);
102
- const recordSetSetter = (0, hooks_2.useRecordSetSetter)();
103
101
  const openFormInternal = (0, navigation_1.useOpenForm)();
104
102
  const openRecord = (0, react_1.useCallback)((id) => {
105
- recordSetSetter(schema.logicalName, dataRef.current?.records.map((x) => x[schema.idAttribute]) ??
106
- []);
107
103
  openFormInternal({
108
104
  logicalName: schema.logicalName,
109
105
  id,
106
+ recordSetIds: dataRef.current?.records.map((x) => x[schema.idAttribute]),
110
107
  });
111
- }, [openFormInternal, recordSetSetter, schema.idAttribute, schema.logicalName]);
108
+ }, [openFormInternal, schema.idAttribute, schema.logicalName]);
112
109
  const { direction } = (0, locale_1.useLocale)();
113
110
  const strings = (0, PageEntityViewStringContext_1.usePageEntityViewStrings)();
114
111
  const dataRef = (0, react_1.useRef)(data);
@@ -10,8 +10,7 @@ const hooks_2 = require("@headless-adminapp/app/hooks");
10
10
  const locale_1 = require("@headless-adminapp/app/locale");
11
11
  const hooks_3 = require("@headless-adminapp/app/metadata/hooks");
12
12
  const mutable_1 = require("@headless-adminapp/app/mutable");
13
- const hooks_4 = require("@headless-adminapp/app/recordset/hooks");
14
- const hooks_5 = require("@headless-adminapp/app/route/hooks");
13
+ const hooks_4 = require("@headless-adminapp/app/route/hooks");
15
14
  const utils_1 = require("@headless-adminapp/app/utils");
16
15
  const phone_1 = require("@headless-adminapp/app/utils/phone");
17
16
  const app_1 = require("@headless-adminapp/core/experience/app");
@@ -84,9 +83,8 @@ function useTableColumns({ disableSelection, disableContextMenu, disableColumnRe
84
83
  return calculatedColumns;
85
84
  }, [columns, tableWrapperSize.width, schema.attributes]);
86
85
  const gridColumns = (0, hooks_1.useGridColumns)();
87
- const routeResolver = (0, hooks_5.useRouteResolver)();
88
- const router = (0, hooks_5.useRouter)();
89
- const recordSetSetter = (0, hooks_4.useRecordSetSetter)();
86
+ const routeResolver = (0, hooks_4.useRouteResolver)();
87
+ const router = (0, hooks_4.useRouter)();
90
88
  const openRecord = (0, useOpenRecord_1.useOpenRecord)();
91
89
  const locale = (0, locale_1.useLocale)();
92
90
  const dataRef = (0, react_1.useRef)(data);
@@ -226,7 +224,6 @@ function useTableColumns({ disableSelection, disableContextMenu, disableColumnRe
226
224
  schemaStore,
227
225
  routeResolver,
228
226
  openRecord,
229
- recordSetSetter,
230
227
  router,
231
228
  }),
232
229
  enableResizing: true,
@@ -247,7 +244,6 @@ function useTableColumns({ disableSelection, disableContextMenu, disableColumnRe
247
244
  schemaStore,
248
245
  routeResolver,
249
246
  openRecord,
250
- recordSetSetter,
251
247
  router,
252
248
  ]);
253
249
  return (0, react_1.useMemo)(() => {
@@ -257,7 +253,7 @@ function useTableColumns({ disableSelection, disableContextMenu, disableColumnRe
257
253
  function renderCellHeaderContent({ column, props, disableColumnResize, disableColumnFilter, disableColumnSort, onChangeSortDirection, attribute, }) {
258
254
  return ((0, jsx_runtime_1.jsx)(GridColumnHeader_1.TableHeaderFilterCell, { columnName: column.name, sortDirection: props.column.getIsSorted() || undefined, minWidth: props.header.getSize(), column: column, resizable: !disableColumnResize, disableFilter: disableColumnFilter, disableSort: disableColumnSort, onChangeSortDirection: onChangeSortDirection, attribute: attribute, onResetSize: props.column.resetSize, resizeHandler: props.header.getResizeHandler(), children: column.label }, column.id));
259
255
  }
260
- function renderCellContent({ info, column, schema, schemaStore, locale, routeResolver, openRecord, recordSetSetter, router, }) {
256
+ function renderCellContent({ info, column, schema, schemaStore, locale, routeResolver, openRecord, router, }) {
261
257
  let attribute;
262
258
  let value;
263
259
  if (column.expandedKey) {
@@ -317,7 +313,6 @@ function renderCellContent({ info, column, schema, schemaStore, locale, routeRes
317
313
  column,
318
314
  schemaStore,
319
315
  routeResolver,
320
- recordSetSetter,
321
316
  router,
322
317
  value,
323
318
  attribute,
@@ -330,7 +325,6 @@ function renderCellContent({ info, column, schema, schemaStore, locale, routeRes
330
325
  column,
331
326
  schemaStore,
332
327
  routeResolver,
333
- recordSetSetter,
334
328
  router,
335
329
  value,
336
330
  attribute,
@@ -392,7 +386,7 @@ function renderPrimaryAttributeAvatar({ info, schema, value, }) {
392
386
  src: avatarValue?.url,
393
387
  } }));
394
388
  }
395
- function renderLookupAttribute({ value, info, column, schemaStore, routeResolver, recordSetSetter, router, attribute, formattedValue, }) {
389
+ function renderLookupAttribute({ value, info, column, schemaStore, routeResolver, router, attribute, formattedValue, }) {
396
390
  if (!value) {
397
391
  return ((0, jsx_runtime_1.jsx)(TableCell_1.TableCellText, { value: "", width: info.column.getSize() }, column.id));
398
392
  }
@@ -409,11 +403,10 @@ function renderLookupAttribute({ value, info, column, schemaStore, routeResolver
409
403
  }, name: formattedValue, color: (0, avatar_1.getAvatarColor)(formattedValue), image: {
410
404
  src: value.avatar,
411
405
  } })), formattedValue] }), width: info.column.getSize(), href: path, onClick: () => {
412
- recordSetSetter('', []);
413
406
  router.push(path);
414
407
  } }, column.id));
415
408
  }
416
- function renderRegardingAttribute({ value, info, column, schemaStore, routeResolver, recordSetSetter, router, formattedValue, }) {
409
+ function renderRegardingAttribute({ value, info, column, schemaStore, routeResolver, router, formattedValue, }) {
417
410
  if (!value) {
418
411
  return ((0, jsx_runtime_1.jsx)(TableCell_1.TableCellText, { value: "", width: info.column.getSize() }, column.id));
419
412
  }
@@ -435,7 +428,6 @@ function renderRegardingAttribute({ value, info, column, schemaStore, routeResol
435
428
  }, name: formattedValue, color: (0, avatar_1.getAvatarColor)(formattedValue), image: {
436
429
  src: value.avatar,
437
430
  } })), formattedValue] }), width: info.column.getSize(), href: path, onClick: () => {
438
- recordSetSetter('', []);
439
431
  router.push(path);
440
432
  } }, column.id));
441
433
  }
@@ -1,2 +1,6 @@
1
1
  import { FC } from 'react';
2
- export declare const CommandContainer: FC;
2
+ interface CommandContainerProps {
3
+ skeleton?: boolean;
4
+ }
5
+ export declare const CommandContainer: FC<CommandContainerProps>;
6
+ export {};
@@ -1,24 +1,31 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.CommandContainer = void 0;
4
7
  const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_components_1 = require("@fluentui/react-components");
5
9
  const hooks_1 = require("@headless-adminapp/app/dataform/hooks");
6
10
  const hooks_2 = require("@headless-adminapp/app/hooks");
11
+ const locale_1 = require("@headless-adminapp/app/locale");
7
12
  const mutable_1 = require("@headless-adminapp/app/mutable");
8
13
  const recordset_1 = require("@headless-adminapp/app/recordset");
9
14
  const hooks_3 = require("@headless-adminapp/app/recordset/hooks");
10
15
  const hooks_4 = require("@headless-adminapp/app/route/hooks");
11
16
  const icons_1 = require("@headless-adminapp/icons");
12
17
  const react_1 = require("react");
18
+ const CommandBar_1 = __importDefault(require("../CommandBar"));
13
19
  const OverflowCommandBar_1 = require("../OverflowCommandBar");
14
- const CommandContainer = () => {
20
+ const CommandContainer = ({ skeleton }) => {
21
+ const { language } = (0, locale_1.useLocale)();
15
22
  const gridCommands = (0, hooks_1.useMainFormCommands)();
16
23
  const router = (0, hooks_4.useRouter)();
17
24
  const isMobile = (0, hooks_2.useIsMobile)();
18
25
  const schema = (0, hooks_1.useDataFormSchema)();
19
26
  const [recordSetVisible, setRecordSetVisible] = (0, hooks_3.useRecordSetVisibility)();
20
27
  const recordSetContext = (0, mutable_1.useContextSelector)(recordset_1.RecordSetContext, (state) => state);
21
- const extendedCommands = (0, react_1.useMemo)(() => {
28
+ const navigationCommands = (0, react_1.useMemo)(() => {
22
29
  return [
23
30
  [
24
31
  {
@@ -44,10 +51,8 @@ const CommandContainer = () => {
44
51
  ],
45
52
  ]
46
53
  : []),
47
- ...gridCommands,
48
54
  ];
49
55
  }, [
50
- gridCommands,
51
56
  isMobile,
52
57
  recordSetContext.ids.length,
53
58
  recordSetContext.logicalName,
@@ -56,6 +61,30 @@ const CommandContainer = () => {
56
61
  schema.logicalName,
57
62
  setRecordSetVisible,
58
63
  ]);
64
+ const extendedCommands = (0, react_1.useMemo)(() => {
65
+ return [...navigationCommands, ...gridCommands];
66
+ }, [gridCommands, navigationCommands]);
67
+ if (skeleton) {
68
+ return ((0, jsx_runtime_1.jsxs)(CommandBar_1.default.Wrapper, { overflow: "hidden", children: [navigationCommands.map((group, groupIndex) => ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [groupIndex > 0 && (0, jsx_runtime_1.jsx)(CommandBar_1.default.Divider, {}), group.map((item, index) => {
69
+ const commandType = item.type;
70
+ switch (item.type) {
71
+ case 'menu':
72
+ case 'button':
73
+ case 'label':
74
+ case 'icon':
75
+ return ((0, jsx_runtime_1.jsx)(react_1.Fragment, { children: (0, OverflowCommandBar_1.renderCommandItem)(`${groupIndex}-${index}`, item, language) }, `${groupIndex}-${index}`));
76
+ default:
77
+ throw new Error(`Unknown command type: ${commandType}`);
78
+ }
79
+ })] }, groupIndex))), (0, jsx_runtime_1.jsx)(CommandBar_1.default.Divider, {}), (0, jsx_runtime_1.jsx)(SkeletonCommandButton, {}), (0, jsx_runtime_1.jsx)(SkeletonCommandButton, {}), (0, jsx_runtime_1.jsx)(SkeletonCommandButton, {})] }));
80
+ }
59
81
  return (0, jsx_runtime_1.jsx)(OverflowCommandBar_1.OverflowCommandBar, { commands: extendedCommands });
60
82
  };
61
83
  exports.CommandContainer = CommandContainer;
84
+ const SkeletonCommandButton = () => {
85
+ return ((0, jsx_runtime_1.jsxs)("div", { style: {
86
+ display: 'flex',
87
+ gap: react_components_1.tokens.spacingHorizontalS,
88
+ paddingInline: react_components_1.tokens.spacingHorizontalM,
89
+ }, children: [(0, jsx_runtime_1.jsx)(react_components_1.SkeletonItem, { style: { width: 20, height: 20 } }), (0, jsx_runtime_1.jsx)(react_components_1.SkeletonItem, { style: { width: 60, height: 20 } })] }));
90
+ };
@@ -1,4 +1,4 @@
1
- import { RelatedItemInfo } from './RelatedViewSelector';
1
+ import { RelatedItemInfo } from '@headless-adminapp/app/dataform/context';
2
2
  interface FormTabRelatedProps {
3
3
  selectedRelatedItem: RelatedItemInfo | null;
4
4
  }
@@ -4,11 +4,13 @@ exports.FormTabRelated = FormTabRelated;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_components_1 = require("@fluentui/react-components");
6
6
  const hooks_1 = require("@headless-adminapp/app/dataform/hooks");
7
+ const historystate_1 = require("@headless-adminapp/app/historystate");
7
8
  const FormTab_1 = require("../form/layout/FormTab");
8
9
  const SubgridControl_1 = require("./SubgridControl");
9
10
  function FormTabRelated({ selectedRelatedItem }) {
10
11
  const recordId = (0, hooks_1.useRecordId)();
11
12
  const schema = (0, hooks_1.useDataFormSchema)();
13
+ const historyKey = (0, historystate_1.useHistoryStateKey)();
12
14
  return ((0, jsx_runtime_1.jsx)(FormTab_1.FormTab, { value: "related", noWrapper: true, children: (0, jsx_runtime_1.jsx)("div", { style: {
13
15
  display: 'flex',
14
16
  flexDirection: 'column',
@@ -32,9 +34,9 @@ function FormTabRelated({ selectedRelatedItem }) {
32
34
  flex: 1,
33
35
  display: 'flex',
34
36
  flexDirection: 'column',
35
- }, children: !!selectedRelatedItem && ((0, jsx_runtime_1.jsx)(SubgridControl_1.SubgridControl, { logicalName: selectedRelatedItem.logicalName, allowViewSelection: true, associated: {
36
- logicalName: schema.logicalName,
37
- id: recordId,
38
- refAttributeName: selectedRelatedItem.attributeName,
39
- } })) }) }) }) }) }) }));
37
+ }, children: !!selectedRelatedItem && ((0, jsx_runtime_1.jsx)(historystate_1.HistoryStateKeyProvider, { historyKey: `related.${selectedRelatedItem.key}`, nested: true, children: (0, jsx_runtime_1.jsx)(SubgridControl_1.SubgridControl, { logicalName: selectedRelatedItem.logicalName, allowViewSelection: true, associated: {
38
+ logicalName: schema.logicalName,
39
+ id: recordId,
40
+ refAttributeName: selectedRelatedItem.attributeName,
41
+ } }) })) }) }) }) }) }) }));
40
42
  }
@@ -4,7 +4,9 @@ exports.PageEntityForm = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_components_1 = require("@fluentui/react-components");
6
6
  const hooks_1 = require("@headless-adminapp/app/dataform/hooks");
7
+ const historystate_1 = require("@headless-adminapp/app/historystate");
7
8
  const PageEntityFormProvider_1 = require("@headless-adminapp/app/providers/PageEntityFormProvider");
9
+ const recordset_1 = require("@headless-adminapp/app/recordset");
8
10
  const icons_1 = require("@headless-adminapp/icons");
9
11
  const PageBroken_1 = require("../components/PageBroken");
10
12
  const PageLoading_1 = require("../components/PageLoading");
@@ -27,12 +29,12 @@ const PageEntityForm = ({ logicalName, formId, recordId, }) => {
27
29
  return ((0, jsx_runtime_1.jsx)(PageBroken_1.PageBroken, { Icon: icons_1.Icons.Error, title: "Creating is disabled", message: "Creating records is disabled for this entity." }));
28
30
  }
29
31
  }
30
- return ((0, jsx_runtime_1.jsx)(PageEntityFormProvider_1.PageEntityFormProvider, { schema: schema, form: form, recordId: recordId, commands: commands, children: (0, jsx_runtime_1.jsxs)("div", { style: {
31
- display: 'flex',
32
- flex: 1,
33
- flexDirection: 'row',
34
- backgroundColor: react_components_1.tokens.colorNeutralBackground2,
35
- overflow: 'hidden',
36
- }, children: [(0, jsx_runtime_1.jsx)(RecordSetNavigatorContainer_1.RecordSetNavigatorContainer, {}), (0, jsx_runtime_1.jsx)(PageEntityFormDesktopContainer_1.PageEntityFormDesktopContainer, {})] }) }));
32
+ return ((0, jsx_runtime_1.jsx)(historystate_1.HistoryStateKeyProvider, { historyKey: 'page-entity-form.' + logicalName, children: (0, jsx_runtime_1.jsx)(recordset_1.RecordSetProvider, { children: (0, jsx_runtime_1.jsx)(PageEntityFormProvider_1.PageEntityFormProvider, { schema: schema, form: form, recordId: recordId, commands: commands, children: (0, jsx_runtime_1.jsxs)("div", { style: {
33
+ display: 'flex',
34
+ flex: 1,
35
+ flexDirection: 'row',
36
+ backgroundColor: react_components_1.tokens.colorNeutralBackground2,
37
+ overflow: 'hidden',
38
+ }, children: [(0, jsx_runtime_1.jsx)(RecordSetNavigatorContainer_1.RecordSetNavigatorContainer, {}), (0, jsx_runtime_1.jsx)(PageEntityFormDesktopContainer_1.PageEntityFormDesktopContainer, {})] }) }) }) }));
37
39
  };
38
40
  exports.PageEntityForm = PageEntityForm;
@@ -5,6 +5,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_components_1 = require("@fluentui/react-components");
6
6
  const dataform_1 = require("@headless-adminapp/app/dataform");
7
7
  const hooks_1 = require("@headless-adminapp/app/dataform/hooks");
8
+ const useFormDataState_1 = require("@headless-adminapp/app/dataform/hooks/useFormDataState");
8
9
  const locale_1 = require("@headless-adminapp/app/locale");
9
10
  const utils_1 = require("@headless-adminapp/app/locale/utils");
10
11
  const mutable_1 = require("@headless-adminapp/app/mutable");
@@ -12,9 +13,9 @@ const utils_2 = require("@headless-adminapp/app/utils");
12
13
  const react_1 = require("react");
13
14
  const react_hook_form_1 = require("react-hook-form");
14
15
  const PageBroken_1 = require("../components/PageBroken");
15
- const PageLoading_1 = require("../components/PageLoading");
16
16
  const FormBody_1 = require("../form/layout/FormBody");
17
17
  const FormTab_1 = require("../form/layout/FormTab");
18
+ const TextSkeleton_1 = require("../Skeleton/TextSkeleton");
18
19
  const CommandContainer_1 = require("./CommandContainer");
19
20
  const FormTabRelated_1 = require("./FormTabRelated");
20
21
  const PageEntityFormStringContext_1 = require("./PageEntityFormStringContext");
@@ -22,52 +23,37 @@ const ProcessFlow_1 = require("./ProcessFlow");
22
23
  const RecordAvatar_1 = require("./RecordAvatar");
23
24
  const RelatedViewSelector_1 = require("./RelatedViewSelector");
24
25
  const SectionContainer_1 = require("./SectionContainer");
25
- let previousCachedActiveTabInfo = null;
26
26
  const PageEntityFormDesktopContainer = () => {
27
- const dataState = (0, mutable_1.useContextSelector)(dataform_1.DataFormContext, (state) => state.dataState);
27
+ const dataState = (0, useFormDataState_1.useFormDataState)();
28
28
  const strings = (0, PageEntityFormStringContext_1.usePageEntityFormStrings)();
29
29
  const locale = (0, locale_1.useLocale)();
30
30
  const recordId = (0, hooks_1.useRecordId)();
31
31
  const record = (0, mutable_1.useContextSelector)(dataform_1.DataFormContext, (state) => state.record);
32
32
  const activeTab = (0, mutable_1.useContextSelector)(dataform_1.DataFormContext, (state) => state.activeTab);
33
+ const selectedRelatedItem = (0, mutable_1.useContextSelector)(dataform_1.DataFormContext, (state) => state.selectedRelatedItem);
33
34
  const { language } = (0, locale_1.useLocale)();
34
35
  const schema = (0, hooks_1.useDataFormSchema)();
35
36
  const formConfig = (0, hooks_1.useSelectedForm)();
36
37
  const processFlowSteps = (0, hooks_1.useProcessFlowSteps)();
37
38
  const setActiveTab = (0, mutable_1.useContextValueSetter)(dataform_1.DataFormContext, (setValue) => (value) => {
38
- setValue((state) => ({
39
- ...state,
39
+ setValue(() => ({
40
40
  activeTab: value,
41
41
  }));
42
42
  });
43
- (0, react_1.useEffect)(() => {
44
- if (previousCachedActiveTabInfo &&
45
- previousCachedActiveTabInfo.logicalName === schema.logicalName) {
46
- setActiveTab(previousCachedActiveTabInfo.name);
47
- setSelectedRelatedItem(previousCachedActiveTabInfo.relatedItem);
48
- }
49
- else {
50
- setActiveTab(formConfig.experience.tabs[0].name);
51
- previousCachedActiveTabInfo = {
52
- logicalName: schema.logicalName,
53
- name: formConfig.experience.tabs[0].name,
54
- relatedItem: null,
55
- };
56
- }
57
- }, [setActiveTab, formConfig, schema]);
43
+ const setSelectedRelatedItem = (0, mutable_1.useContextValueSetter)(dataform_1.DataFormContext, (setValue) => (item) => {
44
+ setValue(() => ({
45
+ selectedRelatedItem: item,
46
+ }));
47
+ });
58
48
  const [recordTitle] = (0, hooks_1.useRecordTitle)();
59
49
  // const readonly = useIsFormReadonly();
60
50
  const formInstance = (0, hooks_1.useFormInstance)();
61
51
  const isDirty = (0, hooks_1.useFormIsDirty)();
62
52
  const notifications = (0, hooks_1.useFormNotifications)();
63
- const [selectedRelatedItem, setSelectedRelatedItem] = (0, react_1.useState)(null);
64
- if (dataState.isFetching) {
65
- return (0, jsx_runtime_1.jsx)(PageLoading_1.PageLoading, {});
66
- }
67
- if (dataState.isError) {
53
+ if (!dataState.isFetching && dataState.isError) {
68
54
  return (0, jsx_runtime_1.jsx)(PageBroken_1.PageBroken, { title: "Error", message: "Unable to load page" });
69
55
  }
70
- if (recordId && !record) {
56
+ if (recordId && !record && !dataState.isFetching) {
71
57
  return ((0, jsx_runtime_1.jsx)(PageBroken_1.PageBroken, { title: "Record not found", message: "Requested record not found in system or you may not have enought permission." }));
72
58
  }
73
59
  return ((0, jsx_runtime_1.jsxs)("div", { style: {
@@ -89,7 +75,7 @@ const PageEntityFormDesktopContainer = () => {
89
75
  background: react_components_1.tokens.colorNeutralBackground1,
90
76
  display: 'flex',
91
77
  // overflow: 'hidden',
92
- }, children: (0, jsx_runtime_1.jsx)(CommandContainer_1.CommandContainer, {}) }), notifications.length > 0 && ((0, jsx_runtime_1.jsx)("div", { children: notifications.map((notification, index) => ((0, jsx_runtime_1.jsx)(react_components_1.MessageBar, { intent: notification.level, icon: null, children: (0, jsx_runtime_1.jsx)(react_components_1.MessageBarBody, { children: notification.message }) }, index))) })), (0, jsx_runtime_1.jsxs)("div", { style: {
78
+ }, children: (0, jsx_runtime_1.jsx)(CommandContainer_1.CommandContainer, { skeleton: dataState.isFetching }) }), notifications.length > 0 && ((0, jsx_runtime_1.jsx)("div", { children: notifications.map((notification, index) => ((0, jsx_runtime_1.jsx)(react_components_1.MessageBar, { intent: notification.level, icon: null, children: (0, jsx_runtime_1.jsx)(react_components_1.MessageBarBody, { children: notification.message }) }, index))) })), (0, jsx_runtime_1.jsxs)("div", { style: {
93
79
  display: 'flex',
94
80
  flexDirection: 'column',
95
81
  boxShadow: react_components_1.tokens.shadow4,
@@ -103,7 +89,11 @@ const PageEntityFormDesktopContainer = () => {
103
89
  paddingInline: react_components_1.tokens.spacingHorizontalM,
104
90
  paddingTop: react_components_1.tokens.spacingVerticalS,
105
91
  marginBottom: react_components_1.tokens.spacingVerticalS,
106
- }, children: [(0, jsx_runtime_1.jsx)(RecordAvatar_1.RecordAvatar, {}), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column', flex: 1 }, children: [(0, jsx_runtime_1.jsxs)("div", { style: {
92
+ }, children: [(0, jsx_runtime_1.jsx)(RecordAvatar_1.RecordAvatar, {}), dataState.isFetching ? ((0, jsx_runtime_1.jsxs)("div", { style: {
93
+ display: 'flex',
94
+ flexDirection: 'column',
95
+ flex: 1,
96
+ }, children: [(0, jsx_runtime_1.jsx)(TextSkeleton_1.Subtitle2Skeleton, { width: 200 }), (0, jsx_runtime_1.jsx)(TextSkeleton_1.Body1Skeleton, { width: 80 })] })) : ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column', flex: 1 }, children: [(0, jsx_runtime_1.jsxs)("div", { style: {
107
97
  display: 'flex',
108
98
  gap: react_components_1.tokens.spacingHorizontalXS,
109
99
  alignItems: 'center',
@@ -111,7 +101,7 @@ const PageEntityFormDesktopContainer = () => {
111
101
  ? `- ${strings.unsaved}`
112
102
  : !!record
113
103
  ? `- ${strings.saved}`
114
- : '' })] }), (0, jsx_runtime_1.jsx)(react_components_1.Body1, { style: { color: react_components_1.tokens.colorNeutralForeground3 }, children: (0, utils_1.localizedLabel)(language, schema) })] }), (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flexDirection: 'row' }, children: formConfig.experience.headerControls?.map((controlName, index) => {
104
+ : '' })] }), (0, jsx_runtime_1.jsx)(react_components_1.Body1, { style: { color: react_components_1.tokens.colorNeutralForeground3 }, children: (0, utils_1.localizedLabel)(language, schema) })] })), (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flexDirection: 'row' }, children: formConfig.experience.headerControls?.map((controlName, index) => {
115
105
  const attribute = schema.attributes[controlName];
116
106
  if (!attribute) {
117
107
  console.warn(`Attribute ${controlName} not found`);
@@ -121,24 +111,17 @@ const PageEntityFormDesktopContainer = () => {
121
111
  width: react_components_1.tokens.spacingHorizontalXXL,
122
112
  opacity: 0.5,
123
113
  } })), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column' }, children: [(0, jsx_runtime_1.jsx)(react_components_1.Body1, { style: { color: react_components_1.tokens.colorNeutralForeground4 }, children: attribute.label }), (0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: formInstance.control, name: controlName, render: ({ field }) => {
114
+ if (dataState.isFetching) {
115
+ return (0, jsx_runtime_1.jsx)(TextSkeleton_1.Body1Skeleton, { width: 100 });
116
+ }
124
117
  return ((0, jsx_runtime_1.jsx)(react_components_1.Body1, { children: (0, utils_2.getAttributeFormattedValue)(attribute, field.value, locale) }));
125
118
  } })] })] }, controlName));
126
- }) })] }), !!processFlowSteps?.length && ((0, jsx_runtime_1.jsx)(ProcessFlow_1.ProcessFlow, { height: 28, rounded: false, items: processFlowSteps })), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', paddingBottom: react_components_1.tokens.spacingVerticalS }, children: [(0, jsx_runtime_1.jsxs)(react_components_1.TabList, { selectedValue: activeTab, onTabSelect: (e, value) => {
119
+ }) })] }), !!processFlowSteps?.length && ((0, jsx_runtime_1.jsx)(ProcessFlow_1.ProcessFlow, { height: 28, rounded: false, items: processFlowSteps, skeleton: dataState.isFetching })), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', paddingBottom: react_components_1.tokens.spacingVerticalS }, children: [(0, jsx_runtime_1.jsxs)(react_components_1.TabList, { selectedValue: activeTab, onTabSelect: (e, value) => {
127
120
  setActiveTab(value.value);
128
- previousCachedActiveTabInfo = {
129
- logicalName: schema.logicalName,
130
- name: value.value,
131
- relatedItem: null,
132
- };
133
121
  }, children: [formConfig.experience.tabs.map((tab) => ((0, jsx_runtime_1.jsx)(react_components_1.Tab, { value: tab.name, children: (0, utils_1.localizedLabel)(language, tab) }, tab.name))), !!selectedRelatedItem && ((0, jsx_runtime_1.jsx)(react_components_1.Tab, { value: "related", children: selectedRelatedItem.localizedPluralLabels?.[language] ??
134
122
  selectedRelatedItem.pluralLabel }))] }), (0, jsx_runtime_1.jsx)(RelatedViewSelector_1.RelatedViewSelector, { onSelect: (item) => {
135
123
  setSelectedRelatedItem(item);
136
124
  setActiveTab('related');
137
- previousCachedActiveTabInfo = {
138
- logicalName: schema.logicalName,
139
- name: 'related',
140
- relatedItem: item,
141
- };
142
- } })] })] })] }), (0, jsx_runtime_1.jsxs)(FormBody_1.FormBody, { children: [formConfig.experience.tabs.map((tab) => ((0, jsx_runtime_1.jsx)(FormTab_1.FormTab, { value: tab.name, columnCount: tab.columnCount, columnWidths: tab.columnWidths, children: tab.tabColumns.map((tabColumn, index) => ((0, jsx_runtime_1.jsx)(FormTab_1.FormTab.Column, { children: tabColumn.sections.map((section) => ((0, jsx_runtime_1.jsx)(SectionContainer_1.SectionContainer, { section: section, readOnly: false }, section.name))) }, index))) }, tab.name))), (0, jsx_runtime_1.jsx)(FormTabRelated_1.FormTabRelated, { selectedRelatedItem: selectedRelatedItem })] })] }));
125
+ } })] })] })] }), (0, jsx_runtime_1.jsxs)(FormBody_1.FormBody, { children: [formConfig.experience.tabs.map((tab) => ((0, jsx_runtime_1.jsx)(FormTab_1.FormTab, { value: tab.name, columnCount: tab.columnCount, columnWidths: tab.columnWidths, children: tab.tabColumns.map((tabColumn, index) => ((0, jsx_runtime_1.jsx)(FormTab_1.FormTab.Column, { children: tabColumn.sections.map((section) => ((0, jsx_runtime_1.jsx)(SectionContainer_1.SectionContainer, { section: section, readOnly: false, skeleton: dataState.isFetching }, section.name))) }, index))) }, tab.name))), (0, jsx_runtime_1.jsx)(FormTabRelated_1.FormTabRelated, { selectedRelatedItem: selectedRelatedItem })] })] }));
143
126
  };
144
127
  exports.PageEntityFormDesktopContainer = PageEntityFormDesktopContainer;
@@ -5,6 +5,7 @@ interface ProcessFlowProps {
5
5
  label: string;
6
6
  isActivated?: boolean;
7
7
  }>;
8
+ skeleton?: boolean;
8
9
  }
9
- export declare function ProcessFlow({ height, rounded, items, }: ProcessFlowProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare function ProcessFlow({ height, rounded, items, skeleton, }: ProcessFlowProps): import("react/jsx-runtime").JSX.Element;
10
11
  export {};
@@ -3,17 +3,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ProcessFlow = ProcessFlow;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_components_1 = require("@fluentui/react-components");
6
- function ProcessFlow({ height = 32, rounded = true, items, }) {
7
- return ((0, jsx_runtime_1.jsx)("div", { style: { position: 'relative', height }, children: (0, jsx_runtime_1.jsx)("div", { style: {
8
- display: 'flex',
9
- overflow: 'hidden',
10
- borderRadius: rounded ? react_components_1.tokens.borderRadiusMedium : 0,
11
- }, children: items.map((item, index) => ((0, jsx_runtime_1.jsx)(ProcessFlowItem, { height: height, label: item.label, isActivated: item.isActivated, isFirst: index === 0, isLast: index === items.length - 1 }, index))) }) }));
6
+ const useStyles = (0, react_components_1.makeStyles)({
7
+ skeleton: {
8
+ backgroundColor: 'transparent',
9
+ '&:after': {
10
+ backgroundImage: 'linear-gradient(to right, transparent 0%, var(--colorNeutralStencil2) 50%, transparent 100%)',
11
+ },
12
+ },
13
+ });
14
+ function ProcessFlow({ height = 32, rounded = true, items, skeleton, }) {
15
+ const styles = useStyles();
16
+ return ((0, jsx_runtime_1.jsxs)("div", { style: { position: 'relative', height }, children: [(0, jsx_runtime_1.jsx)("div", { style: {
17
+ display: 'flex',
18
+ overflow: 'hidden',
19
+ borderRadius: rounded ? react_components_1.tokens.borderRadiusMedium : 0,
20
+ }, children: items.map((item, index) => ((0, jsx_runtime_1.jsx)(ProcessFlowItem, { height: height, label: item.label, isActivated: item.isActivated, isFirst: index === 0, isLast: index === items.length - 1, skeleton: skeleton }, index))) }), skeleton && ((0, jsx_runtime_1.jsx)("div", { style: { position: 'absolute', inset: 0, zIndex: 1 }, children: (0, jsx_runtime_1.jsx)(react_components_1.SkeletonItem, { style: {
21
+ height: '100%',
22
+ borderRadius: rounded ? react_components_1.tokens.borderRadiusMedium : 0,
23
+ }, className: styles.skeleton }) }))] }));
12
24
  }
13
- const ProcessFlowItem = ({ label, height, isActivated, isFirst, isLast, }) => {
14
- const backgroundColor = isActivated
15
- ? react_components_1.tokens.colorBrandBackground
16
- : react_components_1.tokens.colorNeutralStrokeDisabled;
25
+ const ProcessFlowItem = ({ label, height, isActivated, isFirst, isLast, skeleton, }) => {
26
+ let backgroundColor = react_components_1.tokens.colorNeutralStencil1;
27
+ if (!skeleton) {
28
+ backgroundColor = isActivated
29
+ ? react_components_1.tokens.colorBrandBackground
30
+ : react_components_1.tokens.colorNeutralStrokeDisabled;
31
+ }
17
32
  return ((0, jsx_runtime_1.jsxs)("div", { style: {
18
33
  flex: 1,
19
34
  position: 'relative',
@@ -72,7 +87,7 @@ const ProcessFlowItem = ({ label, height, isActivated, isFirst, isLast, }) => {
72
87
  borderRight: isLast
73
88
  ? 'none'
74
89
  : `1px solid ${react_components_1.tokens.colorNeutralBackground1}`,
75
- } })] }), (0, jsx_runtime_1.jsx)("div", { style: {
90
+ } })] }), !skeleton && ((0, jsx_runtime_1.jsx)("div", { style: {
76
91
  display: 'flex',
77
92
  flexDirection: 'column',
78
93
  flex: 1,
@@ -80,5 +95,5 @@ const ProcessFlowItem = ({ label, height, isActivated, isFirst, isLast, }) => {
80
95
  gap: react_components_1.tokens.spacingVerticalS,
81
96
  color: isActivated ? 'white' : undefined,
82
97
  zIndex: 2,
83
- }, children: (0, jsx_runtime_1.jsx)(react_components_1.Caption1, { children: label }) })] }));
98
+ }, children: (0, jsx_runtime_1.jsx)(react_components_1.Caption1, { children: label }) }))] }));
84
99
  };
@@ -6,6 +6,7 @@ const react_components_1 = require("@fluentui/react-components");
6
6
  const app_1 = require("@headless-adminapp/app/app");
7
7
  const dataform_1 = require("@headless-adminapp/app/dataform");
8
8
  const hooks_1 = require("@headless-adminapp/app/dataform/hooks");
9
+ const useIsDataFetching_1 = require("@headless-adminapp/app/dataform/hooks/useIsDataFetching");
9
10
  const dialog_1 = require("@headless-adminapp/app/dialog");
10
11
  const mutable_1 = require("@headless-adminapp/app/mutable");
11
12
  const progress_indicator_1 = require("@headless-adminapp/app/progress-indicator");
@@ -23,6 +24,7 @@ const RecordAvatar = () => {
23
24
  const dataService = (0, transport_1.useDataService)();
24
25
  const refresh = (0, mutable_1.useContextSelector)(dataform_1.DataFormContext, (state) => state.refresh);
25
26
  const [showAvatarChangeDialog, setShowAvatarChangeDialog] = (0, react_1.useState)(false);
27
+ const isDataFetching = (0, useIsDataFetching_1.useIsFormDataFetching)();
26
28
  const fileService = (0, transport_1.useFileService)();
27
29
  const { showProgressIndicator, hideProgressIndicator } = (0, progress_indicator_1.useProgressIndicator)();
28
30
  const openErrorDialog = (0, dialog_1.useOpenErrorDialog)();
@@ -59,6 +61,18 @@ const RecordAvatar = () => {
59
61
  if (!experienceSchema) {
60
62
  return null;
61
63
  }
64
+ if (isDataFetching) {
65
+ return ((0, jsx_runtime_1.jsx)("div", { style: {
66
+ display: 'flex',
67
+ alignItems: 'flex-start',
68
+ marginRight: react_components_1.tokens.spacingHorizontalM,
69
+ marginTop: 2,
70
+ }, children: (0, jsx_runtime_1.jsx)(react_components_1.SkeletonItem, { style: {
71
+ width: 36,
72
+ height: 36,
73
+ borderRadius: react_components_1.tokens.borderRadiusCircular,
74
+ } }) }));
75
+ }
62
76
  if (isPlaceholder && !value) {
63
77
  const Icon = experienceSchema.Icon ?? icons_1.Icons.Entity ?? icons_1.IconPlaceholder;
64
78
  return ((0, jsx_runtime_1.jsx)("div", { style: {
@@ -1,11 +1,4 @@
1
- import { Localized } from '@headless-adminapp/core/types';
2
- export interface RelatedItemInfo {
3
- key: string;
4
- logicalName: string;
5
- pluralLabel: string;
6
- localizedPluralLabels?: Localized<string>;
7
- attributeName: string;
8
- }
1
+ import { RelatedItemInfo } from '@headless-adminapp/app/dataform/context';
9
2
  interface RelatedViewSelectorProps {
10
3
  onSelect: (item: RelatedItemInfo) => void;
11
4
  }
@@ -1,6 +1,7 @@
1
1
  import { Section } from '@headless-adminapp/core/experience/form';
2
2
  import type { SchemaAttributes } from '@headless-adminapp/core/schema';
3
- export declare function SectionContainer<S extends SchemaAttributes = SchemaAttributes>({ section }: Readonly<{
3
+ export declare function SectionContainer<S extends SchemaAttributes = SchemaAttributes>({ section, skeleton, }: Readonly<{
4
4
  section: Section<S>;
5
5
  readOnly: boolean;
6
+ skeleton?: boolean;
6
7
  }>): import("react/jsx-runtime").JSX.Element | null;
@@ -7,6 +7,7 @@ const constants_1 = require("@headless-adminapp/app/dataform/constants");
7
7
  const utils_1 = require("@headless-adminapp/app/dataform/DataFormProvider/utils");
8
8
  const hooks_1 = require("@headless-adminapp/app/dataform/hooks");
9
9
  const useEventManager_1 = require("@headless-adminapp/app/dataform/hooks/useEventManager");
10
+ const historystate_1 = require("@headless-adminapp/app/historystate");
10
11
  const hooks_2 = require("@headless-adminapp/app/hooks");
11
12
  const locale_1 = require("@headless-adminapp/app/locale");
12
13
  const utils_2 = require("@headless-adminapp/app/locale/utils");
@@ -19,7 +20,7 @@ const layout_1 = require("../form/layout");
19
20
  const EditableGridControl_1 = require("./EditableGridControl/EditableGridControl");
20
21
  const StandardControl_1 = require("./StandardControl");
21
22
  const SubgridControl_1 = require("./SubgridControl");
22
- function SectionContainer({ section }) {
23
+ function SectionContainer({ section, skeleton, }) {
23
24
  const schema = (0, hooks_1.useDataFormSchema)();
24
25
  const formInstance = (0, hooks_1.useFormInstance)();
25
26
  const recordId = (0, hooks_1.useRecordId)();
@@ -95,7 +96,7 @@ function SectionContainer({ section }) {
95
96
  recordId,
96
97
  attributeName: control.attributeName,
97
98
  logicalName: schema.logicalName,
98
- }, autoHeight: control.autoHeight, maxHeight: control.maxHeight }) }));
99
+ }, autoHeight: control.autoHeight, maxHeight: control.maxHeight, skeleton: skeleton }) }));
99
100
  } }, control.attributeName) }, control.attributeName));
100
101
  }
101
102
  case 'editablegrid': {
@@ -119,13 +120,14 @@ function SectionContainer({ section }) {
119
120
  ContainerComponent = componentStore_1.componentStore.getComponent(control.component);
120
121
  }
121
122
  }
122
- return ((0, jsx_runtime_1.jsx)(SubgridControl_1.SubgridControl, { logicalName: control.logicalName, allowViewSelection: control.allowViewSelection, viewId: control.viewId, availableViewIds: control.availableViewIds, ContainerComponent: ContainerComponent, associated: !control.associatedAttribute
123
- ? false
124
- : {
125
- logicalName: schema.logicalName,
126
- id: recordId,
127
- refAttributeName: control.associatedAttribute,
128
- } }, index));
123
+ const key = control.key ?? `${control.logicalName}-${index}`;
124
+ return ((0, jsx_runtime_1.jsx)(historystate_1.HistoryStateKeyProvider, { historyKey: `subgrid.${key}`, nested: true, children: (0, jsx_runtime_1.jsx)(SubgridControl_1.SubgridControl, { logicalName: control.logicalName, allowViewSelection: control.allowViewSelection, viewId: control.viewId, availableViewIds: control.availableViewIds, ContainerComponent: ContainerComponent, associated: !control.associatedAttribute
125
+ ? false
126
+ : {
127
+ logicalName: schema.logicalName,
128
+ id: recordId,
129
+ refAttributeName: control.associatedAttribute,
130
+ } }, key) }));
129
131
  }
130
132
  case 'component': {
131
133
  const Component = control.component === 'string'