@itwin/appui-react 3.4.0-dev.8 → 3.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 (113) hide show
  1. package/CHANGELOG.md +75 -1
  2. package/lib/cjs/appui-react/childwindow/ChildWindowManager.d.ts.map +1 -1
  3. package/lib/cjs/appui-react/childwindow/ChildWindowManager.js +4 -5
  4. package/lib/cjs/appui-react/childwindow/ChildWindowManager.js.map +1 -1
  5. package/lib/cjs/appui-react/content/FloatingViewportContent.d.ts.map +1 -1
  6. package/lib/cjs/appui-react/content/FloatingViewportContent.js +5 -5
  7. package/lib/cjs/appui-react/content/FloatingViewportContent.js.map +1 -1
  8. package/lib/cjs/appui-react/dialog/DialogManagerBase.d.ts +7 -0
  9. package/lib/cjs/appui-react/dialog/DialogManagerBase.d.ts.map +1 -1
  10. package/lib/cjs/appui-react/dialog/DialogManagerBase.js +23 -0
  11. package/lib/cjs/appui-react/dialog/DialogManagerBase.js.map +1 -1
  12. package/lib/cjs/appui-react/dialog/ModelessDialogManager.d.ts +0 -2
  13. package/lib/cjs/appui-react/dialog/ModelessDialogManager.d.ts.map +1 -1
  14. package/lib/cjs/appui-react/dialog/ModelessDialogManager.js +6 -18
  15. package/lib/cjs/appui-react/dialog/ModelessDialogManager.js.map +1 -1
  16. package/lib/cjs/appui-react/dialog/StandardMessageBox.d.ts.map +1 -1
  17. package/lib/cjs/appui-react/dialog/StandardMessageBox.js +2 -1
  18. package/lib/cjs/appui-react/dialog/StandardMessageBox.js.map +1 -1
  19. package/lib/cjs/appui-react/frontstage/FrontstageDef.d.ts +13 -1
  20. package/lib/cjs/appui-react/frontstage/FrontstageDef.d.ts.map +1 -1
  21. package/lib/cjs/appui-react/frontstage/FrontstageDef.js +140 -96
  22. package/lib/cjs/appui-react/frontstage/FrontstageDef.js.map +1 -1
  23. package/lib/cjs/appui-react/imodel-components/category-tree/Categories.json +2 -2
  24. package/lib/cjs/appui-react/imodel-components/models-tree/Hierarchy.GroupedByClass.json +1 -0
  25. package/lib/cjs/appui-react/imodel-components/models-tree/Hierarchy.json +1 -0
  26. package/lib/cjs/appui-react/imodel-components/models-tree/ModelsTree.d.ts +1 -1
  27. package/lib/cjs/appui-react/imodel-components/models-tree/ModelsTree.d.ts.map +1 -1
  28. package/lib/cjs/appui-react/imodel-components/models-tree/ModelsTree.js +11 -8
  29. package/lib/cjs/appui-react/imodel-components/models-tree/ModelsTree.js.map +1 -1
  30. package/lib/cjs/appui-react/imodel-components/models-tree/ModelsVisibilityHandler.d.ts +15 -1
  31. package/lib/cjs/appui-react/imodel-components/models-tree/ModelsVisibilityHandler.d.ts.map +1 -1
  32. package/lib/cjs/appui-react/imodel-components/models-tree/ModelsVisibilityHandler.js +5 -2
  33. package/lib/cjs/appui-react/imodel-components/models-tree/ModelsVisibilityHandler.js.map +1 -1
  34. package/lib/cjs/appui-react/stagepanels/StagePanelDef.d.ts +0 -6
  35. package/lib/cjs/appui-react/stagepanels/StagePanelDef.d.ts.map +1 -1
  36. package/lib/cjs/appui-react/tools/CoreToolDefinitions.d.ts +1 -0
  37. package/lib/cjs/appui-react/tools/CoreToolDefinitions.d.ts.map +1 -1
  38. package/lib/cjs/appui-react/tools/CoreToolDefinitions.js +23 -4
  39. package/lib/cjs/appui-react/tools/CoreToolDefinitions.js.map +1 -1
  40. package/lib/cjs/appui-react/ui-items-provider/StandardNavigationToolsProvider.d.ts.map +1 -1
  41. package/lib/cjs/appui-react/ui-items-provider/StandardNavigationToolsProvider.js +2 -0
  42. package/lib/cjs/appui-react/ui-items-provider/StandardNavigationToolsProvider.js.map +1 -1
  43. package/lib/cjs/appui-react/ui-items-provider/StandardNavigationToolsUiItemsProvider.d.ts +1 -0
  44. package/lib/cjs/appui-react/ui-items-provider/StandardNavigationToolsUiItemsProvider.d.ts.map +1 -1
  45. package/lib/cjs/appui-react/ui-items-provider/StandardNavigationToolsUiItemsProvider.js +2 -0
  46. package/lib/cjs/appui-react/ui-items-provider/StandardNavigationToolsUiItemsProvider.js.map +1 -1
  47. package/lib/cjs/appui-react/widget-panels/Frontstage.d.ts +20 -697
  48. package/lib/cjs/appui-react/widget-panels/Frontstage.d.ts.map +1 -1
  49. package/lib/cjs/appui-react/widget-panels/Frontstage.js +294 -270
  50. package/lib/cjs/appui-react/widget-panels/Frontstage.js.map +1 -1
  51. package/lib/cjs/appui-react/widget-panels/useWidgetDirection.js +1 -1
  52. package/lib/cjs/appui-react/widget-panels/useWidgetDirection.js.map +1 -1
  53. package/lib/cjs/appui-react/widgets/WidgetDef.d.ts +13 -6
  54. package/lib/cjs/appui-react/widgets/WidgetDef.d.ts.map +1 -1
  55. package/lib/cjs/appui-react/widgets/WidgetDef.js +6 -1
  56. package/lib/cjs/appui-react/widgets/WidgetDef.js.map +1 -1
  57. package/lib/esm/appui-react/childwindow/ChildWindowManager.d.ts.map +1 -1
  58. package/lib/esm/appui-react/childwindow/ChildWindowManager.js +4 -5
  59. package/lib/esm/appui-react/childwindow/ChildWindowManager.js.map +1 -1
  60. package/lib/esm/appui-react/content/FloatingViewportContent.d.ts.map +1 -1
  61. package/lib/esm/appui-react/content/FloatingViewportContent.js +5 -5
  62. package/lib/esm/appui-react/content/FloatingViewportContent.js.map +1 -1
  63. package/lib/esm/appui-react/dialog/DialogManagerBase.d.ts +7 -0
  64. package/lib/esm/appui-react/dialog/DialogManagerBase.d.ts.map +1 -1
  65. package/lib/esm/appui-react/dialog/DialogManagerBase.js +23 -0
  66. package/lib/esm/appui-react/dialog/DialogManagerBase.js.map +1 -1
  67. package/lib/esm/appui-react/dialog/ModelessDialogManager.d.ts +0 -2
  68. package/lib/esm/appui-react/dialog/ModelessDialogManager.d.ts.map +1 -1
  69. package/lib/esm/appui-react/dialog/ModelessDialogManager.js +6 -18
  70. package/lib/esm/appui-react/dialog/ModelessDialogManager.js.map +1 -1
  71. package/lib/esm/appui-react/dialog/StandardMessageBox.d.ts.map +1 -1
  72. package/lib/esm/appui-react/dialog/StandardMessageBox.js +2 -1
  73. package/lib/esm/appui-react/dialog/StandardMessageBox.js.map +1 -1
  74. package/lib/esm/appui-react/frontstage/FrontstageDef.d.ts +13 -1
  75. package/lib/esm/appui-react/frontstage/FrontstageDef.d.ts.map +1 -1
  76. package/lib/esm/appui-react/frontstage/FrontstageDef.js +142 -98
  77. package/lib/esm/appui-react/frontstage/FrontstageDef.js.map +1 -1
  78. package/lib/esm/appui-react/imodel-components/category-tree/Categories.json +2 -2
  79. package/lib/esm/appui-react/imodel-components/models-tree/Hierarchy.GroupedByClass.json +1 -0
  80. package/lib/esm/appui-react/imodel-components/models-tree/Hierarchy.json +1 -0
  81. package/lib/esm/appui-react/imodel-components/models-tree/ModelsTree.d.ts +1 -1
  82. package/lib/esm/appui-react/imodel-components/models-tree/ModelsTree.d.ts.map +1 -1
  83. package/lib/esm/appui-react/imodel-components/models-tree/ModelsTree.js +12 -9
  84. package/lib/esm/appui-react/imodel-components/models-tree/ModelsTree.js.map +1 -1
  85. package/lib/esm/appui-react/imodel-components/models-tree/ModelsVisibilityHandler.d.ts +15 -1
  86. package/lib/esm/appui-react/imodel-components/models-tree/ModelsVisibilityHandler.d.ts.map +1 -1
  87. package/lib/esm/appui-react/imodel-components/models-tree/ModelsVisibilityHandler.js +4 -2
  88. package/lib/esm/appui-react/imodel-components/models-tree/ModelsVisibilityHandler.js.map +1 -1
  89. package/lib/esm/appui-react/stagepanels/StagePanelDef.d.ts +0 -6
  90. package/lib/esm/appui-react/stagepanels/StagePanelDef.d.ts.map +1 -1
  91. package/lib/esm/appui-react/tools/CoreToolDefinitions.d.ts +1 -0
  92. package/lib/esm/appui-react/tools/CoreToolDefinitions.d.ts.map +1 -1
  93. package/lib/esm/appui-react/tools/CoreToolDefinitions.js +25 -6
  94. package/lib/esm/appui-react/tools/CoreToolDefinitions.js.map +1 -1
  95. package/lib/esm/appui-react/ui-items-provider/StandardNavigationToolsProvider.d.ts.map +1 -1
  96. package/lib/esm/appui-react/ui-items-provider/StandardNavigationToolsProvider.js +2 -0
  97. package/lib/esm/appui-react/ui-items-provider/StandardNavigationToolsProvider.js.map +1 -1
  98. package/lib/esm/appui-react/ui-items-provider/StandardNavigationToolsUiItemsProvider.d.ts +1 -0
  99. package/lib/esm/appui-react/ui-items-provider/StandardNavigationToolsUiItemsProvider.d.ts.map +1 -1
  100. package/lib/esm/appui-react/ui-items-provider/StandardNavigationToolsUiItemsProvider.js +2 -0
  101. package/lib/esm/appui-react/ui-items-provider/StandardNavigationToolsUiItemsProvider.js.map +1 -1
  102. package/lib/esm/appui-react/widget-panels/Frontstage.d.ts +20 -697
  103. package/lib/esm/appui-react/widget-panels/Frontstage.d.ts.map +1 -1
  104. package/lib/esm/appui-react/widget-panels/Frontstage.js +285 -264
  105. package/lib/esm/appui-react/widget-panels/Frontstage.js.map +1 -1
  106. package/lib/esm/appui-react/widget-panels/useWidgetDirection.js +2 -2
  107. package/lib/esm/appui-react/widget-panels/useWidgetDirection.js.map +1 -1
  108. package/lib/esm/appui-react/widgets/WidgetDef.d.ts +13 -6
  109. package/lib/esm/appui-react/widgets/WidgetDef.d.ts.map +1 -1
  110. package/lib/esm/appui-react/widgets/WidgetDef.js +6 -1
  111. package/lib/esm/appui-react/widgets/WidgetDef.js.map +1 -1
  112. package/lib/public/locales/en/UiFramework.json +3 -1
  113. package/package.json +36 -35
@@ -5,7 +5,7 @@
5
5
  *--------------------------------------------------------------------------------------------*/
6
6
  /* eslint-disable deprecation/deprecation */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.saveFrontstagePopoutWidgetSizeAndPosition = exports.useItemsManager = exports.useFrontstageManager = exports.getFrontstageStateSettingName = exports.FRONTSTAGE_SETTINGS_NAMESPACE = exports.useSaveFrontstageSettings = exports.useSavedFrontstageState = exports.setWidgetLabel = exports.expandWidget = exports.showWidget = exports.setWidgetState = exports.isPanelCollapsed = exports.packNineZoneState = exports.restoreNineZoneState = exports.initializeNineZoneState = exports.initializePanel = exports.isFrontstageStateSettingResult = exports.addPanelWidgets = exports.getPanelZoneWidgets = exports.getWidgetId = exports.removeMissingWidgets = exports.addMissingWidgets = exports.appendWidgets = exports.addWidgets = exports.useLabels = exports.ActiveFrontstageDefProvider = exports.WidgetPanelsFrontstage = exports.useNineZoneDispatch = exports.useUpdateNineZoneSize = exports.useNineZoneState = void 0;
8
+ exports.useItemsManager = exports.useFrontstageManager = exports.getFrontstageStateSettingName = exports.FRONTSTAGE_SETTINGS_NAMESPACE = exports.useSaveFrontstageSettings = exports.useSavedFrontstageState = exports.setWidgetLabel = exports.expandWidget = exports.showWidget = exports.setWidgetState = exports.isPanelCollapsed = exports.packNineZoneState = exports.restoreNineZoneState = exports.initializeNineZoneState = exports.initializePanel = exports.isFrontstageStateSettingResult = exports.addPanelWidgets = exports.getPanelZoneWidgets = exports.getWidgetId = exports.removeMissingWidgets = exports.addMissingWidgets = exports.appendWidgets = exports.addWidgets = exports.useLabels = exports.ActiveFrontstageDefProvider = exports.WidgetPanelsFrontstage = exports.useNineZoneDispatch = exports.useUpdateNineZoneSize = exports.useNineZoneState = void 0;
9
9
  /** @packageDocumentation
10
10
  * @module Frontstage
11
11
  */
@@ -268,7 +268,6 @@ function appendWidgets(state, widgetDefs, side, preferredWidgetIndex) {
268
268
  const saveTab = state.tabs[widgetDef.id];
269
269
  const preferredPanelWidgetSize = saveTab ? saveTab.preferredPanelWidgetSize : widgetDef.preferredPanelSize;
270
270
  const preferredFloatingWidgetSize = saveTab ? saveTab.preferredFloatingWidgetSize : widgetDef.defaultFloatingSize;
271
- const preferredPopoutWidgetSize = saveTab ? saveTab.preferredPopoutWidgetSize : undefined;
272
271
  // if a defaultFloatingSize is specified then this mean the widget can't determine its intrinsic size and must be explicitly sized
273
272
  const userSized = saveTab ? (saveTab.userSized || !!widgetDef.defaultFloatingSize && !!saveTab.preferredFloatingWidgetSize)
274
273
  : !!widgetDef.defaultFloatingSize;
@@ -278,7 +277,6 @@ function appendWidgets(state, widgetDefs, side, preferredWidgetIndex) {
278
277
  canPopout: widgetDef.canPopout,
279
278
  preferredPanelWidgetSize,
280
279
  preferredFloatingWidgetSize,
281
- preferredPopoutWidgetSize,
282
280
  userSized,
283
281
  isFloatingStateWindowResizable: widgetDef.isFloatingStateWindowResizable,
284
282
  hideWithUiWhenFloating: !!widgetDef.hideWithUiWhenFloating,
@@ -286,13 +284,43 @@ function appendWidgets(state, widgetDefs, side, preferredWidgetIndex) {
286
284
  if (widgetDef.isFloatingStateSupported && widgetDef.defaultState === appui_abstract_1.WidgetState.Floating) {
287
285
  const floatingContainerId = (_a = widgetDef.floatingContainerId) !== null && _a !== void 0 ? _a : (0, appui_layout_react_1.getUniqueId)();
288
286
  const widgetContainerId = getWidgetId(side, panelZoneKeys[preferredWidgetIndex]);
289
- const homePanelInfo = { side, widgetId: widgetContainerId, widgetIndex: 0 };
287
+ const home = { side, widgetId: widgetContainerId, widgetIndex: 0 };
290
288
  const preferredPosition = widgetDef.defaultFloatingPosition;
291
- state = (0, appui_layout_react_1.addWidgetTabToFloatingPanel)(state, floatingContainerId, widgetDef.id, homePanelInfo, preferredFloatingWidgetSize, preferredPosition, userSized, widgetDef.isFloatingStateWindowResizable);
289
+ if (floatingContainerId in state.widgets) {
290
+ state = (0, appui_layout_react_1.addTabToWidget)(state, widgetDef.id, floatingContainerId);
291
+ }
292
+ else {
293
+ const tab = state.tabs[widgetDef.id];
294
+ const size = { height: 200, width: 300, ...tab.preferredFloatingWidgetSize };
295
+ const preferredPoint = preferredPosition !== null && preferredPosition !== void 0 ? preferredPosition : { x: (state.size.width - size.width) / 2, y: (state.size.height - size.height) / 2 };
296
+ const nzBounds = core_react_1.Rectangle.createFromSize(state.size);
297
+ const bounds = core_react_1.Rectangle.createFromSize(size).offset(preferredPoint);
298
+ const containedBounds = bounds.containIn(nzBounds);
299
+ state = (0, appui_layout_react_1.addFloatingWidget)(state, floatingContainerId, [widgetDef.id], {
300
+ bounds: containedBounds.toProps(),
301
+ home,
302
+ userSized,
303
+ }, {
304
+ isFloatingStateWindowResizable: widgetDef.isFloatingStateWindowResizable,
305
+ });
306
+ }
292
307
  }
293
308
  else {
294
309
  const widgetPanelSectionId = (0, appui_layout_react_1.getWidgetPanelSectionId)(side, preferredWidgetIndex);
295
- state = (0, appui_layout_react_1.addWidgetTabToPanelSection)(state, side, widgetPanelSectionId, widgetDef.id);
310
+ if (widgetPanelSectionId in state.widgets) {
311
+ state = (0, appui_layout_react_1.addTabToWidget)(state, widgetDef.id, widgetPanelSectionId);
312
+ }
313
+ else {
314
+ const panel = state.panels[side];
315
+ if (panel.widgets.length < panel.maxWidgetCount) {
316
+ state = (0, appui_layout_react_1.addPanelWidget)(state, side, widgetPanelSectionId, [widgetDef.id]);
317
+ }
318
+ else {
319
+ const widgetIndex = Math.min(preferredWidgetIndex, panel.widgets.length - 1);
320
+ const widgetId = panel.widgets[widgetIndex];
321
+ state = (0, appui_layout_react_1.addTabToWidget)(state, widgetDef.id, widgetId);
322
+ }
323
+ }
296
324
  }
297
325
  }
298
326
  return state;
@@ -340,17 +368,15 @@ function addMissingWidgets(frontstageDef, initialState) {
340
368
  return state;
341
369
  }
342
370
  exports.addMissingWidgets = addMissingWidgets;
343
- /** Removes widgets with Hidden defaultState. */
344
- function removeHiddenWidgets(state, frontstageDef) {
371
+ /** Hide widgets with Hidden defaultState. */
372
+ function hideWidgets(state, frontstageDef) {
345
373
  const tabs = Object.values(state.tabs);
346
374
  for (const tab of tabs) {
347
375
  const widgetDef = frontstageDef.findWidgetDef(tab.id);
348
376
  if (!widgetDef)
349
377
  continue;
350
378
  if (widgetDef.defaultState === appui_abstract_1.WidgetState.Hidden) {
351
- state = (0, immer_1.default)(state, (draft) => {
352
- hideWidget(draft, widgetDef);
353
- });
379
+ state = hideWidget(state, widgetDef);
354
380
  }
355
381
  }
356
382
  return state;
@@ -359,16 +385,15 @@ function removeHiddenWidgets(state, frontstageDef) {
359
385
  * @internal
360
386
  */
361
387
  function removeMissingWidgets(frontstageDef, initialState) {
362
- const state = (0, immer_1.default)(initialState, (draft) => {
363
- for (const [, tab] of Object.entries(draft.tabs)) {
364
- if (tab.id === appui_layout_react_1.toolSettingsTabId)
365
- continue;
366
- const widgetDef = frontstageDef.findWidgetDef(tab.id);
367
- if (widgetDef)
368
- continue;
369
- (0, appui_layout_react_1.removeTab)(draft, tab.id);
370
- }
371
- });
388
+ let state = initialState;
389
+ for (const [, tab] of Object.entries(state.tabs)) {
390
+ if (tab.id === appui_layout_react_1.toolSettingsTabId)
391
+ continue;
392
+ const widgetDef = frontstageDef.findWidgetDef(tab.id);
393
+ if (widgetDef)
394
+ continue;
395
+ state = (0, appui_layout_react_1.removeTab)(state, tab.id);
396
+ }
372
397
  return state;
373
398
  }
374
399
  exports.removeMissingWidgets = removeMissingWidgets;
@@ -524,23 +549,23 @@ function isFrontstageStateSettingResult(settingsResult) {
524
549
  }
525
550
  exports.isFrontstageStateSettingResult = isFrontstageStateSettingResult;
526
551
  /** @internal */
527
- function initializePanel(nineZone, frontstageDef, panelSide) {
528
- nineZone = addPanelWidgets(nineZone, frontstageDef, panelSide);
552
+ function initializePanel(state, frontstageDef, panelSide) {
553
+ state = addPanelWidgets(state, frontstageDef, panelSide);
529
554
  const location = toStagePanelLocation(panelSide);
530
555
  const panelDef = frontstageDef.getStagePanelDef(location);
531
- nineZone = (0, immer_1.default)(nineZone, (draft) => {
556
+ state = (0, immer_1.default)(state, (draft) => {
532
557
  var _a, _b, _c;
533
558
  const panel = draft.panels[panelSide];
534
559
  panel.minSize = (_a = panelDef === null || panelDef === void 0 ? void 0 : panelDef.minSize) !== null && _a !== void 0 ? _a : panel.minSize;
535
560
  panel.pinned = (_b = panelDef === null || panelDef === void 0 ? void 0 : panelDef.pinned) !== null && _b !== void 0 ? _b : panel.pinned;
536
561
  panel.resizable = (_c = panelDef === null || panelDef === void 0 ? void 0 : panelDef.resizable) !== null && _c !== void 0 ? _c : panel.resizable;
537
562
  if (panelDef === null || panelDef === void 0 ? void 0 : panelDef.maxSizeSpec) {
538
- panel.maxSize = getPanelMaxSize(panelDef.maxSizeSpec, panelSide, nineZone.size);
563
+ panel.maxSize = getPanelMaxSize(panelDef.maxSizeSpec, panelSide, state.size);
539
564
  }
540
565
  const size = panelDef === null || panelDef === void 0 ? void 0 : panelDef.size;
541
566
  panel.size = size === undefined ? size : Math.min(Math.max(size, panel.minSize), panel.maxSize);
542
567
  });
543
- return nineZone;
568
+ return state;
544
569
  }
545
570
  exports.initializePanel = initializePanel;
546
571
  function getPanelMaxSize(maxSizeSpec, panel, nineZoneSize) {
@@ -550,7 +575,7 @@ function getPanelMaxSize(maxSizeSpec, panel, nineZoneSize) {
550
575
  const size = (0, appui_layout_react_1.isHorizontalPanelSide)(panel) ? nineZoneSize.height : nineZoneSize.width;
551
576
  return maxSizeSpec.percentage / 100 * size;
552
577
  }
553
- const stateVersion = 12; // this needs to be bumped when NineZoneState is changed (to recreate layout).
578
+ const stateVersion = 13; // this needs to be bumped when NineZoneState is changed (to recreate the layout).
554
579
  /** @internal */
555
580
  function initializeNineZoneState(frontstageDef) {
556
581
  let nineZone = defaultNineZone;
@@ -572,6 +597,7 @@ function initializeNineZoneState(frontstageDef) {
572
597
  for (const [, panel] of Object.entries(stateDraft.panels)) {
573
598
  const expanded = panel.widgets.find((widgetId) => stateDraft.widgets[widgetId].minimized === false);
574
599
  const firstWidget = panel.widgets.length > 0 ? stateDraft.widgets[panel.widgets[0]] : undefined;
600
+ // istanbul ignore next
575
601
  if (!expanded && firstWidget) {
576
602
  firstWidget.minimized = false;
577
603
  }
@@ -600,7 +626,7 @@ function initializeNineZoneState(frontstageDef) {
600
626
  }
601
627
  });
602
628
  nineZone = addMissingWidgets(frontstageDef, nineZone);
603
- nineZone = removeHiddenWidgets(nineZone, frontstageDef);
629
+ nineZone = hideWidgets(nineZone, frontstageDef);
604
630
  nineZone = processPopoutWidgets(nineZone, frontstageDef);
605
631
  return nineZone;
606
632
  }
@@ -613,29 +639,32 @@ exports.initializeNineZoneState = initializeNineZoneState;
613
639
  function restoreNineZoneState(frontstageDef, saved) {
614
640
  let restored = {
615
641
  ...saved,
616
- tabs: (0, appui_layout_react_1.createTabsState)(),
642
+ tabs: defaultNineZone.tabs,
617
643
  };
618
- restored = (0, immer_1.default)(restored, (draft) => {
619
- var _a;
620
- for (const [, tab] of Object.entries(saved.tabs)) {
621
- const widgetDef = frontstageDef.findWidgetDef(tab.id);
622
- if (!widgetDef) {
623
- core_bentley_1.Logger.logInfo(UiFramework_1.UiFramework.loggerCategory(restoreNineZoneState), "WidgetDef is not found for saved tab.", () => ({
624
- frontstageId: frontstageDef.id,
625
- tabId: tab.id,
626
- }));
627
- (0, appui_layout_react_1.removeTab)(draft, tab.id);
628
- // let fall through so we preserve preferred sizes of widgets load via UiItemsProvider
629
- }
644
+ for (const [, tab] of Object.entries(saved.tabs)) {
645
+ // Re-add the placeholder tab in order to correctly remove it from the state if WidgetDef is not found.
646
+ restored = (0, appui_layout_react_1.addTab)(restored, tab.id);
647
+ const widgetDef = frontstageDef.findWidgetDef(tab.id);
648
+ if (!widgetDef) {
649
+ core_bentley_1.Logger.logInfo(UiFramework_1.UiFramework.loggerCategory(restoreNineZoneState), "WidgetDef is not found for saved tab.", () => ({
650
+ frontstageId: frontstageDef.id,
651
+ tabId: tab.id,
652
+ }));
653
+ restored = (0, appui_layout_react_1.removeTab)(restored, tab.id);
654
+ continue;
655
+ }
656
+ restored = (0, immer_1.default)(restored, (draft) => {
630
657
  draft.tabs[tab.id] = {
631
658
  ...tab,
632
- label: getWidgetLabel((_a = widgetDef === null || widgetDef === void 0 ? void 0 : widgetDef.label) !== null && _a !== void 0 ? _a : "undefined"),
633
- hideWithUiWhenFloating: widgetDef === null || widgetDef === void 0 ? void 0 : widgetDef.hideWithUiWhenFloating,
634
- iconSpec: widgetDef === null || widgetDef === void 0 ? void 0 : widgetDef.iconSpec,
635
- canPopout: widgetDef === null || widgetDef === void 0 ? void 0 : widgetDef.canPopout,
636
- isFloatingStateWindowResizable: widgetDef === null || widgetDef === void 0 ? void 0 : widgetDef.isFloatingStateWindowResizable,
659
+ label: getWidgetLabel(widgetDef.label),
660
+ hideWithUiWhenFloating: widgetDef.hideWithUiWhenFloating,
661
+ iconSpec: widgetDef.iconSpec,
662
+ canPopout: widgetDef.canPopout,
663
+ isFloatingStateWindowResizable: widgetDef.isFloatingStateWindowResizable,
637
664
  };
638
- }
665
+ });
666
+ }
667
+ restored = (0, immer_1.default)(restored, (draft) => {
639
668
  // remove center panel section if one is found in left or right panels
640
669
  const oldLeftMiddleIndex = saved.panels.left.widgets.findIndex((value) => value === "leftMiddle");
641
670
  // istanbul ignore next
@@ -675,20 +704,6 @@ function restoreNineZoneState(frontstageDef, saved) {
675
704
  return restored;
676
705
  }
677
706
  exports.restoreNineZoneState = restoreNineZoneState;
678
- /**
679
- * Checks to see whether a widget id is one of our generated uuids
680
- * @param uuid the string value to test
681
- * @returns boolean
682
- */
683
- function isUUID(uuid) {
684
- const s = `${uuid}`;
685
- const result = s.match("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$");
686
- // istanbul ignore else
687
- if (result === null) {
688
- return false;
689
- }
690
- return true;
691
- }
692
707
  /** Prepares NineZoneState to be saved.
693
708
  * @note Removes toolSettings tab.
694
709
  * @note Removes tab labels and iconSpec.
@@ -703,33 +718,62 @@ function packNineZoneState(state) {
703
718
  for (const [, tab] of Object.entries(state.tabs)) {
704
719
  if (tab.id === appui_layout_react_1.toolSettingsTabId)
705
720
  continue;
706
- // istanbul ignore else
707
- if (isUUID(tab.id))
708
- continue;
709
721
  draft.tabs[tab.id] = {
710
722
  id: tab.id,
711
723
  preferredFloatingWidgetSize: tab.preferredFloatingWidgetSize,
712
- preferredPopoutWidgetSize: tab.preferredPopoutWidgetSize,
713
724
  allowedPanelTargets: tab.allowedPanelTargets,
714
725
  userSized: tab.userSized,
715
726
  };
716
727
  }
717
728
  });
718
- packed = (0, immer_1.default)(packed, (draft) => {
719
- for (const [, floatingWidget] of Object.entries(state.floatingWidgets.byId)) {
720
- const widgetId = floatingWidget.id;
721
- // istanbul ignore else
722
- if (isUUID(widgetId)) {
723
- const idIndex = draft.floatingWidgets.allIds.indexOf(widgetId);
724
- draft.floatingWidgets.allIds.splice(idIndex, 1);
725
- delete draft.floatingWidgets.byId[widgetId];
726
- delete draft.widgets[widgetId];
727
- }
728
- }
729
- });
730
729
  return packed;
731
730
  }
732
731
  exports.packNineZoneState = packNineZoneState;
732
+ // TODO: clean-up of saved widgets.
733
+ // istanbul ignore next
734
+ function packSavedWidgets(savedWidgets, frontstageDef) {
735
+ for (const widgetDef of frontstageDef.widgetDefs) {
736
+ const id = widgetDef.id;
737
+ const initialWidget = {
738
+ id,
739
+ };
740
+ const widget = (0, immer_1.default)(initialWidget, (draft) => {
741
+ if (widgetDef.tabLocation) {
742
+ draft.tabLocation = { ...widgetDef.tabLocation };
743
+ }
744
+ if (widgetDef.popoutBounds) {
745
+ draft.popoutBounds = widgetDef.popoutBounds.toProps();
746
+ }
747
+ });
748
+ if (widget === initialWidget)
749
+ continue;
750
+ savedWidgets = (0, immer_1.default)(savedWidgets, (draft) => {
751
+ draft.push(widget);
752
+ });
753
+ }
754
+ return savedWidgets;
755
+ }
756
+ // istanbul ignore next
757
+ function restoreSavedWidgets(savedWidgets, frontstage) {
758
+ let i = savedWidgets.length;
759
+ while (i--) {
760
+ const savedWidget = savedWidgets[i];
761
+ const widgetId = savedWidget.id;
762
+ const widgetDef = frontstage.findWidgetDef(widgetId);
763
+ if (!widgetDef)
764
+ continue;
765
+ if (savedWidget.tabLocation) {
766
+ widgetDef.tabLocation = { ...savedWidget.tabLocation };
767
+ }
768
+ if (savedWidget.popoutBounds) {
769
+ widgetDef.popoutBounds = core_react_1.Rectangle.create(savedWidget.popoutBounds);
770
+ }
771
+ savedWidgets = (0, immer_1.default)(savedWidgets, (draft) => {
772
+ draft.splice(i, 1);
773
+ });
774
+ }
775
+ return savedWidgets;
776
+ }
733
777
  /** @internal */
734
778
  function isPanelCollapsed(zoneStates, panelStates) {
735
779
  const openZone = zoneStates.find((zoneState) => zoneState === ZoneDef_1.ZoneState.Open);
@@ -737,121 +781,128 @@ function isPanelCollapsed(zoneStates, panelStates) {
737
781
  return !openZone && !openPanel;
738
782
  }
739
783
  exports.isPanelCollapsed = isPanelCollapsed;
740
- function addRemovedTab(nineZone, widgetDef) {
741
- var _a, _b;
742
- const newTab = (0, appui_layout_react_1.createTabState)(widgetDef.id, {
743
- label: getWidgetLabel(widgetDef.label),
744
- canPopout: widgetDef.canPopout,
745
- iconSpec: widgetDef.iconSpec,
746
- preferredPanelWidgetSize: widgetDef.preferredPanelSize,
747
- isFloatingStateWindowResizable: widgetDef.isFloatingStateWindowResizable,
748
- hideWithUiWhenFloating: !!widgetDef.hideWithUiWhenFloating,
749
- });
750
- nineZone.tabs[newTab.id] = newTab;
751
- if (widgetDef.tabLocation.widgetId in nineZone.widgets) {
752
- // Add to existing widget (by widget id).
753
- const widgetId = widgetDef.tabLocation.widgetId;
754
- const newTabWidget = nineZone.widgets[widgetId];
755
- newTabWidget.tabs.splice(widgetDef.tabLocation.tabIndex, 0, newTab.id);
784
+ function addHiddenWidget(state, widgetDef) {
785
+ const tabLocation = widgetDef.tabLocation || widgetDef.defaultTabLocation;
786
+ const tabId = widgetDef.id;
787
+ const { widgetId, tabIndex } = tabLocation;
788
+ if (widgetId in state.widgets) {
789
+ // Add to an existing widget (by widget id).
790
+ return (0, appui_layout_react_1.insertTabToWidget)(state, tabId, widgetId, tabIndex);
756
791
  }
757
- else if (widgetDef.tabLocation.floating) {
758
- const id = widgetDef.tabLocation.widgetId;
759
- if (id in nineZone.floatingWidgets.byId) {
760
- nineZone.floatingWidgets.allIds.push(id);
761
- nineZone.floatingWidgets.byId[id].hidden = false;
762
- (0, appui_layout_react_1.addWidgetTabToDraftFloatingPanel)(nineZone, (_a = widgetDef.floatingContainerId) !== null && _a !== void 0 ? _a : widgetDef.id, widgetDef.id, nineZone.floatingWidgets.byId[id].home, newTab);
763
- }
764
- else {
765
- const home = { side: widgetDef.tabLocation.side, widgetId: widgetDef.floatingContainerId, widgetIndex: 0 };
766
- (0, appui_layout_react_1.addWidgetTabToDraftFloatingPanel)(nineZone, (_b = widgetDef.floatingContainerId) !== null && _b !== void 0 ? _b : widgetDef.id, widgetDef.id, home, newTab);
767
- }
792
+ else if (tabLocation.floatingWidget) {
793
+ const floatingWidget = tabLocation.floatingWidget;
794
+ (0, core_bentley_1.assert)(widgetId === floatingWidget.id);
795
+ // Add to a new floating widget.
796
+ const nzBounds = core_react_1.Rectangle.createFromSize(state.size);
797
+ const bounds = core_react_1.Rectangle.create(floatingWidget.bounds).containIn(nzBounds);
798
+ return (0, appui_layout_react_1.addFloatingWidget)(state, floatingWidget.id, [tabId], {
799
+ ...floatingWidget,
800
+ bounds: bounds.toProps(),
801
+ });
768
802
  }
769
- else {
770
- const newTabPanel = nineZone.panels[widgetDef.tabLocation.side];
771
- if (newTabPanel.maxWidgetCount === newTabPanel.widgets.length) {
772
- // Add to existing panel widget.
773
- const widgetIndex = Math.min(newTabPanel.maxWidgetCount - 1, widgetDef.tabLocation.widgetIndex);
774
- const newTabWidgetId = newTabPanel.widgets[widgetIndex];
775
- const newTabWidget = nineZone.widgets[newTabWidgetId];
776
- newTabWidget.tabs.splice(widgetDef.tabLocation.tabIndex, 0, newTab.id);
777
- }
778
- else {
779
- // Create a new panel widget.
780
- const newWidget = (0, appui_layout_react_1.createWidgetState)((0, appui_layout_react_1.getUniqueId)(), [newTab.id]);
781
- nineZone.widgets[newWidget.id] = (0, immer_1.castDraft)(newWidget);
782
- newTabPanel.widgets.splice(widgetDef.tabLocation.widgetIndex, 0, newWidget.id);
783
- }
803
+ // Add to a panel section.
804
+ const panel = state.panels[tabLocation.side];
805
+ // Add to existing panel section.
806
+ if (panel.widgets.length >= panel.maxWidgetCount) {
807
+ const sectionIndex = Math.min(panel.maxWidgetCount - 1, tabLocation.widgetIndex);
808
+ const sectionId = panel.widgets[sectionIndex];
809
+ return (0, appui_layout_react_1.insertTabToWidget)(state, tabId, sectionId, tabLocation.tabIndex);
784
810
  }
811
+ // Create a new panel section.
812
+ const newSectionId = (0, appui_layout_react_1.getUniqueId)();
813
+ return (0, appui_layout_react_1.insertPanelWidget)(state, panel.side, newSectionId, [tabId], tabLocation.widgetIndex);
785
814
  }
786
815
  /** @internal */
787
- exports.setWidgetState = (0, immer_1.default)((nineZone, widgetDef, state) => {
816
+ function setWidgetState(state, widgetDef, widgetState) {
788
817
  var _a, _b;
789
- if (state === appui_abstract_1.WidgetState.Open) {
818
+ if (widgetState === appui_abstract_1.WidgetState.Hidden) {
819
+ return hideWidget(state, widgetDef);
820
+ }
821
+ else if (widgetState === appui_abstract_1.WidgetState.Open) {
790
822
  const id = widgetDef.id;
791
- let location = (0, appui_layout_react_1.findTab)(nineZone, id);
823
+ let location = (0, appui_layout_react_1.getTabLocation)(state, id);
792
824
  if (!location) {
793
- addRemovedTab(nineZone, widgetDef);
794
- location = (0, appui_layout_react_1.findTab)(nineZone, id);
795
- (0, core_bentley_1.assert)(!!location);
825
+ state = addHiddenWidget(state, widgetDef);
826
+ location = (0, appui_layout_react_1.getTabLocation)(state, id);
796
827
  }
797
- if (!!widgetDef.tabLocation.floating) {
798
- nineZone.floatingWidgets.byId[(_a = widgetDef.floatingContainerId) !== null && _a !== void 0 ? _a : widgetDef.id].hidden = false;
799
- }
800
- const widget = nineZone.widgets[location.widgetId];
801
- widget.minimized = false;
802
- widget.activeTabId = id;
803
- // ensure panel containing widget is not collapsed
804
- // istanbul ignore else
805
- if ("side" in location) {
806
- const panel = nineZone.panels[location.side];
807
- panel.collapsed && (panel.collapsed = false);
808
- // istanbul ignore next
809
- if (undefined === panel.size || 0 === panel.size) {
810
- panel.size = (_b = panel.minSize) !== null && _b !== void 0 ? _b : 200;
828
+ return (0, immer_1.default)(state, (draft) => {
829
+ var _a;
830
+ (0, core_bentley_1.assert)(!!location);
831
+ const widget = draft.widgets[location.widgetId];
832
+ widget.minimized = false;
833
+ widget.activeTabId = id;
834
+ if ((0, appui_layout_react_1.isFloatingTabLocation)(location)) {
835
+ const floatingWidget = draft.floatingWidgets.byId[location.floatingWidgetId];
836
+ floatingWidget.hidden = false;
837
+ // istanbul ignore else
811
838
  }
812
- }
839
+ else if ((0, appui_layout_react_1.isPanelTabLocation)(location)) {
840
+ const panel = draft.panels[location.side];
841
+ panel.collapsed = false;
842
+ if (undefined === panel.size || 0 === panel.size) {
843
+ // istanbul ignore next
844
+ panel.size = (_a = panel.minSize) !== null && _a !== void 0 ? _a : 200;
845
+ }
846
+ }
847
+ });
813
848
  }
814
- else if (state === appui_abstract_1.WidgetState.Closed) {
849
+ else if (widgetState === appui_abstract_1.WidgetState.Closed) {
815
850
  const id = widgetDef.id;
816
- let location = (0, appui_layout_react_1.findTab)(nineZone, id);
851
+ let location = (0, appui_layout_react_1.getTabLocation)(state, id);
817
852
  if (!location) {
818
- addRemovedTab(nineZone, widgetDef);
819
- location = (0, appui_layout_react_1.findTab)(nineZone, id);
820
- (0, core_bentley_1.assert)(!!location);
821
- }
822
- if ((0, appui_layout_react_1.isFloatingLocation)(location)) {
823
- const widget = nineZone.widgets[location.widgetId];
824
- if (id !== widget.activeTabId)
825
- return;
826
- widget.minimized = true;
853
+ state = addHiddenWidget(state, widgetDef);
854
+ location = (0, appui_layout_react_1.getTabLocation)(state, id);
827
855
  }
856
+ // TODO: should change activeTabId of a widget with multiple tabs.
857
+ return (0, immer_1.default)(state, (draft) => {
858
+ (0, core_bentley_1.assert)(!!location);
859
+ const widget = draft.widgets[location.widgetId];
860
+ if ((0, appui_layout_react_1.isFloatingTabLocation)(location)) {
861
+ if (id === widget.activeTabId) {
862
+ widget.minimized = true;
863
+ }
864
+ }
865
+ });
828
866
  }
829
- else if (state === appui_abstract_1.WidgetState.Hidden) {
830
- hideWidget(nineZone, widgetDef);
867
+ else if (widgetState === appui_abstract_1.WidgetState.Floating) {
868
+ const id = widgetDef.id;
869
+ let location = (0, appui_layout_react_1.getTabLocation)(state, id);
870
+ if (!location) {
871
+ state = addHiddenWidget(state, widgetDef);
872
+ location = (0, appui_layout_react_1.getTabLocation)(state, id);
873
+ }
874
+ (0, core_bentley_1.assert)(!!location);
875
+ if ((0, appui_layout_react_1.isFloatingTabLocation)(location))
876
+ return state;
877
+ // Widget is not floating.
878
+ state = (0, appui_layout_react_1.removeTabFromWidget)(state, id);
879
+ const bounds = (_b = (_a = widgetDef.tabLocation) === null || _a === void 0 ? void 0 : _a.floatingWidget) === null || _b === void 0 ? void 0 : _b.bounds;
880
+ state = (0, appui_layout_react_1.addFloatingWidget)(state, (0, appui_layout_react_1.getUniqueId)(), [id], { bounds });
831
881
  }
832
- });
882
+ return state;
883
+ }
884
+ exports.setWidgetState = setWidgetState;
833
885
  /** Stores widget location and hides it in the UI. */
834
886
  function hideWidget(state, widgetDef) {
835
- const location = (0, appui_layout_react_1.findTab)(state, widgetDef.id);
887
+ const location = (0, appui_layout_react_1.getTabLocation)(state, widgetDef.id);
836
888
  if (!location)
837
- return;
838
- if ((0, appui_layout_react_1.isFloatingLocation)(location)) {
839
- const widget = state.floatingWidgets.byId[location.widgetId];
889
+ return state;
890
+ // istanbul ignore else
891
+ if ((0, appui_layout_react_1.isFloatingTabLocation)(location)) {
892
+ const floatingWidget = state.floatingWidgets.byId[location.widgetId];
840
893
  widgetDef.setFloatingContainerId(location.floatingWidgetId);
841
894
  widgetDef.tabLocation = {
842
- side: widget.home.side,
843
- tabIndex: widget.home.widgetIndex,
844
- widgetId: widgetDef.id,
845
- widgetIndex: widget.home.widgetIndex,
846
- floating: true,
895
+ side: floatingWidget.home.side,
896
+ tabIndex: floatingWidget.home.widgetIndex,
897
+ widgetId: floatingWidget.id,
898
+ widgetIndex: floatingWidget.home.widgetIndex,
899
+ floatingWidget,
847
900
  };
848
901
  }
849
- else
850
- // istanbul ignore else
851
- if (!(0, appui_layout_react_1.isPopoutLocation)(location)) {
902
+ else if (!(0, appui_layout_react_1.isPopoutTabLocation)(location)) {
852
903
  const widgetId = location.widgetId;
853
- const side = "side" in location ? location.side : "left";
854
- const widgetIndex = "side" in location ? state.panels[side].widgets.indexOf(widgetId) : 0;
904
+ const side = (0, appui_layout_react_1.isPanelTabLocation)(location) ? location.side : "left";
905
+ const widgetIndex = (0, appui_layout_react_1.isPanelTabLocation)(location) ? state.panels[side].widgets.indexOf(widgetId) : 0;
855
906
  const tabIndex = state.widgets[location.widgetId].tabs.indexOf(widgetDef.id);
856
907
  widgetDef.tabLocation = {
857
908
  side,
@@ -860,50 +911,56 @@ function hideWidget(state, widgetDef) {
860
911
  widgetIndex,
861
912
  };
862
913
  }
863
- (0, appui_layout_react_1.removeTab)(state, widgetDef.id);
914
+ return (0, appui_layout_react_1.removeTabFromWidget)(state, widgetDef.id);
864
915
  }
865
916
  /** @internal */
866
- exports.showWidget = (0, immer_1.default)((nineZone, id) => {
867
- const location = (0, appui_layout_react_1.findTab)(nineZone, id);
917
+ function showWidget(state, id) {
918
+ const location = (0, appui_layout_react_1.getTabLocation)(state, id);
868
919
  if (!location)
869
- return;
870
- const widget = nineZone.widgets[location.widgetId];
871
- if ("side" in location) {
872
- const panel = nineZone.panels[location.side];
873
- panel.collapsed = false;
874
- widget.minimized = false;
920
+ return state;
921
+ state = (0, immer_1.default)(state, (draft) => {
922
+ const widget = draft.widgets[location.widgetId];
875
923
  widget.activeTabId = id;
876
- return;
924
+ widget.minimized = false;
925
+ if ((0, appui_layout_react_1.isPanelTabLocation)(location)) {
926
+ const panel = draft.panels[location.side];
927
+ panel.collapsed = false;
928
+ }
929
+ });
930
+ if ((0, appui_layout_react_1.isFloatingTabLocation)(location)) {
931
+ state = (0, appui_layout_react_1.floatingWidgetBringToFront)(state, location.floatingWidgetId);
877
932
  }
878
- widget.activeTabId = id;
879
- widget.minimized = false;
880
- (0, appui_layout_react_1.isFloatingLocation)(location) && (0, appui_layout_react_1.floatingWidgetBringToFront)(nineZone, location.floatingWidgetId);
881
- });
933
+ return state;
934
+ }
935
+ exports.showWidget = showWidget;
882
936
  /** @internal */
883
- exports.expandWidget = (0, immer_1.default)((nineZone, id) => {
884
- const location = (0, appui_layout_react_1.findTab)(nineZone, id);
937
+ function expandWidget(state, id) {
938
+ const location = (0, appui_layout_react_1.getTabLocation)(state, id);
885
939
  if (!location)
886
- return;
887
- const widget = nineZone.widgets[location.widgetId];
888
- if ("side" in location) {
889
- const panel = nineZone.panels[location.side];
890
- panel.widgets.forEach((wId) => {
891
- const w = nineZone.widgets[wId];
892
- w.minimized = true;
893
- });
940
+ return state;
941
+ return (0, immer_1.default)(state, (draft) => {
942
+ const widget = draft.widgets[location.widgetId];
943
+ if ((0, appui_layout_react_1.isPanelTabLocation)(location)) {
944
+ const panel = draft.panels[location.side];
945
+ panel.widgets.forEach((wId) => {
946
+ const w = draft.widgets[wId];
947
+ w.minimized = true;
948
+ });
949
+ }
894
950
  widget.minimized = false;
895
- return;
896
- }
897
- widget.minimized = false;
898
- return;
899
- });
951
+ });
952
+ }
953
+ exports.expandWidget = expandWidget;
900
954
  /** @internal */
901
- exports.setWidgetLabel = (0, immer_1.default)((nineZone, id, label) => {
902
- if (!(id in nineZone.tabs))
903
- return;
904
- const tab = nineZone.tabs[id];
905
- tab.label = label;
906
- });
955
+ function setWidgetLabel(state, id, label) {
956
+ if (!(id in state.tabs))
957
+ return state;
958
+ return (0, immer_1.default)(state, (draft) => {
959
+ const tab = draft.tabs[id];
960
+ tab.label = label;
961
+ });
962
+ }
963
+ exports.setWidgetLabel = setWidgetLabel;
907
964
  /** @internal */
908
965
  function useSavedFrontstageState(frontstageDef) {
909
966
  const uiStateStorage = (0, useUiStateStorage_1.useUiStateStorageHandler)();
@@ -924,20 +981,23 @@ function useSavedFrontstageState(frontstageDef) {
924
981
  }
925
982
  const id = frontstageDef.id;
926
983
  const version = frontstageDef.version;
927
- const settingsResult = await uiStateStorageRef.current.getSetting(exports.FRONTSTAGE_SETTINGS_NAMESPACE, getFrontstageStateSettingName(id));
928
- if (isMountedRef.current) {
929
- if (isFrontstageStateSettingResult(settingsResult) &&
930
- settingsResult.setting.version >= version &&
931
- settingsResult.setting.stateVersion >= stateVersion) {
932
- const restored = restoreNineZoneState(frontstageDef, settingsResult.setting.nineZone);
984
+ const settingResult = await uiStateStorageRef.current.getSetting(exports.FRONTSTAGE_SETTINGS_NAMESPACE, getFrontstageStateSettingName(id));
985
+ if (!isMountedRef.current)
986
+ return;
987
+ if (isFrontstageStateSettingResult(settingResult)) {
988
+ const setting = settingResult.setting;
989
+ if (setting.version >= version && setting.stateVersion >= stateVersion) {
990
+ const restored = restoreNineZoneState(frontstageDef, setting.nineZone);
991
+ const savedWidgets = restoreSavedWidgets(setting.widgets, frontstageDef);
933
992
  let state = addMissingWidgets(frontstageDef, restored);
934
- state = removeHiddenWidgets(state, frontstageDef);
993
+ state = hideWidgets(state, frontstageDef);
935
994
  state = processPopoutWidgets(state, frontstageDef);
936
995
  frontstageDef.nineZoneState = state;
996
+ frontstageDef.savedWidgetDefs = savedWidgets;
937
997
  return;
938
998
  }
939
- frontstageDef.nineZoneState = initializeNineZoneState(frontstageDef);
940
999
  }
1000
+ frontstageDef.nineZoneState = initializeNineZoneState(frontstageDef);
941
1001
  }
942
1002
  fetchFrontstageState(); // eslint-disable-line @typescript-eslint/no-floating-promises
943
1003
  }, [frontstageDef]);
@@ -947,16 +1007,19 @@ exports.useSavedFrontstageState = useSavedFrontstageState;
947
1007
  function useSaveFrontstageSettings(frontstageDef) {
948
1008
  const nineZone = useNineZoneState(frontstageDef);
949
1009
  const uiSettingsStorage = (0, useUiStateStorage_1.useUiStateStorageHandler)();
950
- // eslint-disable-next-line react-hooks/exhaustive-deps
951
- const saveSetting = React.useCallback(debounce(async (id, version, state) => {
952
- const setting = {
953
- id,
954
- nineZone: packNineZoneState(state),
955
- stateVersion,
956
- version,
957
- };
958
- await uiSettingsStorage.saveSetting(exports.FRONTSTAGE_SETTINGS_NAMESPACE, getFrontstageStateSettingName(id), setting);
959
- }, 1000), [uiSettingsStorage]);
1010
+ const saveSetting = React.useMemo(() => {
1011
+ return debounce(async (frontstage, state, savedWidgets) => {
1012
+ const id = frontstage.id;
1013
+ const setting = {
1014
+ id,
1015
+ version: frontstage.version,
1016
+ stateVersion,
1017
+ nineZone: packNineZoneState(state),
1018
+ widgets: packSavedWidgets(savedWidgets, frontstage),
1019
+ };
1020
+ await uiSettingsStorage.saveSetting(exports.FRONTSTAGE_SETTINGS_NAMESPACE, getFrontstageStateSettingName(id), setting);
1021
+ }, 1000);
1022
+ }, [uiSettingsStorage]);
960
1023
  React.useEffect(() => {
961
1024
  return () => {
962
1025
  saveSetting.cancel();
@@ -965,7 +1028,8 @@ function useSaveFrontstageSettings(frontstageDef) {
965
1028
  React.useEffect(() => {
966
1029
  if (!nineZone || nineZone.draggedTab)
967
1030
  return;
968
- saveSetting(frontstageDef.id, frontstageDef.version, nineZone);
1031
+ const savedWidgets = frontstageDef.savedWidgetDefs || [];
1032
+ saveSetting(frontstageDef, nineZone, savedWidgets);
969
1033
  }, [frontstageDef, nineZone, saveSetting]);
970
1034
  }
971
1035
  exports.useSaveFrontstageSettings = useSaveFrontstageSettings;
@@ -1004,7 +1068,7 @@ function useFrontstageManager(frontstageDef, useToolAsToolSettingsLabel) {
1004
1068
  React.useEffect(() => {
1005
1069
  const listener = createListener(frontstageDef, ({ widgetDef, widgetState }) => {
1006
1070
  (0, core_bentley_1.assert)(!!frontstageDef.nineZoneState);
1007
- frontstageDef.nineZoneState = (0, exports.setWidgetState)(frontstageDef.nineZoneState, widgetDef, widgetState);
1071
+ frontstageDef.nineZoneState = setWidgetState(frontstageDef.nineZoneState, widgetDef, widgetState);
1008
1072
  });
1009
1073
  FrontstageManager_1.FrontstageManager.onWidgetStateChangedEvent.addListener(listener);
1010
1074
  return () => {
@@ -1014,7 +1078,7 @@ function useFrontstageManager(frontstageDef, useToolAsToolSettingsLabel) {
1014
1078
  React.useEffect(() => {
1015
1079
  const listener = createListener(frontstageDef, ({ widgetDef }) => {
1016
1080
  (0, core_bentley_1.assert)(!!frontstageDef.nineZoneState);
1017
- frontstageDef.nineZoneState = (0, exports.showWidget)(frontstageDef.nineZoneState, widgetDef.id);
1081
+ frontstageDef.nineZoneState = showWidget(frontstageDef.nineZoneState, widgetDef.id);
1018
1082
  });
1019
1083
  FrontstageManager_1.FrontstageManager.onWidgetShowEvent.addListener(listener);
1020
1084
  return () => {
@@ -1024,8 +1088,8 @@ function useFrontstageManager(frontstageDef, useToolAsToolSettingsLabel) {
1024
1088
  React.useEffect(() => {
1025
1089
  const listener = createListener(frontstageDef, ({ widgetDef }) => {
1026
1090
  (0, core_bentley_1.assert)(!!frontstageDef.nineZoneState);
1027
- let nineZoneState = (0, exports.showWidget)(frontstageDef.nineZoneState, widgetDef.id);
1028
- nineZoneState = (0, exports.expandWidget)(nineZoneState, widgetDef.id);
1091
+ let nineZoneState = showWidget(frontstageDef.nineZoneState, widgetDef.id);
1092
+ nineZoneState = expandWidget(nineZoneState, widgetDef.id);
1029
1093
  frontstageDef.nineZoneState = nineZoneState;
1030
1094
  });
1031
1095
  FrontstageManager_1.FrontstageManager.onWidgetExpandEvent.addListener(listener);
@@ -1054,7 +1118,7 @@ function useFrontstageManager(frontstageDef, useToolAsToolSettingsLabel) {
1054
1118
  const listener = createListener(frontstageDef, ({ widgetDef }) => {
1055
1119
  (0, core_bentley_1.assert)(!!frontstageDef.nineZoneState);
1056
1120
  const label = widgetDef.label;
1057
- frontstageDef.nineZoneState = (0, exports.setWidgetLabel)(frontstageDef.nineZoneState, widgetDef.id, label);
1121
+ frontstageDef.nineZoneState = setWidgetLabel(frontstageDef.nineZoneState, widgetDef.id, label);
1058
1122
  });
1059
1123
  FrontstageManager_1.FrontstageManager.onWidgetLabelChangedEvent.addListener(listener);
1060
1124
  return () => {
@@ -1069,7 +1133,7 @@ function useFrontstageManager(frontstageDef, useToolAsToolSettingsLabel) {
1069
1133
  (0, core_bentley_1.assert)(!!frontstageDef.nineZoneState);
1070
1134
  const label = useToolAsToolSettingsLabel ?
1071
1135
  ((_a = core_frontend_1.IModelApp.tools.find(toolId)) === null || _a === void 0 ? void 0 : _a.flyover) || defaultLabel : defaultLabel;
1072
- frontstageDef.nineZoneState = (0, exports.setWidgetLabel)(frontstageDef.nineZoneState, appui_layout_react_1.toolSettingsTabId, label);
1136
+ frontstageDef.nineZoneState = setWidgetLabel(frontstageDef.nineZoneState, appui_layout_react_1.toolSettingsTabId, label);
1073
1137
  });
1074
1138
  // Whenever the frontstageDef or the useTool... changes, keep the label up to date.
1075
1139
  updateLabel();
@@ -1102,7 +1166,7 @@ function useItemsManager(frontstageDef) {
1102
1166
  return;
1103
1167
  state = addMissingWidgets(def, state);
1104
1168
  state = removeMissingWidgets(def, state);
1105
- state = removeHiddenWidgets(state, def); // TODO: should only apply to widgets provided by registered provider in onUiProviderRegisteredEvent.
1169
+ state = hideWidgets(state, def); // TODO: should only apply to widgets provided by registered provider in onUiProviderRegisteredEvent.
1106
1170
  def.nineZoneState = state;
1107
1171
  };
1108
1172
  React.useEffect(() => {
@@ -1116,48 +1180,8 @@ function useItemsManager(frontstageDef) {
1116
1180
  }, [frontstageDef]);
1117
1181
  }
1118
1182
  exports.useItemsManager = useItemsManager;
1119
- function tabShownInCurrentWidget(def, state) {
1120
- for (const [, widget] of Object.entries(state.widgets)) {
1121
- const foundTab = widget.tabs.find((tabId) => tabId === def.id);
1122
- // istanbul ignore else
1123
- if (foundTab)
1124
- return true;
1125
- }
1126
- return false;
1127
- }
1128
1183
  // istanbul ignore next
1129
1184
  function determineNewWidgets(defs, state) {
1130
- // if tab for widget.id is not found or the label does not match widget label (label is set to "undefined" when widgetDef is not initially available)
1131
- return (defs || []).filter((def) => !(def.id in state.tabs) || !tabShownInCurrentWidget(def, state));
1132
- }
1133
- /** @internal */
1134
- async function saveFrontstagePopoutWidgetSizeAndPosition(state, stageId, stageVersion, childWindowId, childWindow) {
1135
- const location = (0, appui_layout_react_1.findWidget)(state, childWindowId);
1136
- // istanbul ignore else
1137
- if (location) {
1138
- const adjustmentWidth = core_bentley_1.ProcessDetector.isElectronAppFrontend ? 16 : 0;
1139
- const adjustmentHeight = core_bentley_1.ProcessDetector.isElectronAppFrontend ? 39 : 0;
1140
- const newState = (0, immer_1.default)(state, (draft) => {
1141
- const widget = draft.widgets[childWindowId];
1142
- const tab = draft.tabs[widget.activeTabId];
1143
- tab.preferredPopoutWidgetSize = {
1144
- x: childWindow.screenX,
1145
- y: childWindow.screenY,
1146
- width: childWindow.innerWidth + adjustmentWidth,
1147
- height: childWindow.innerHeight + adjustmentHeight,
1148
- };
1149
- });
1150
- const setting = {
1151
- id: stageId,
1152
- nineZone: packNineZoneState(newState),
1153
- stateVersion,
1154
- version: stageVersion,
1155
- };
1156
- await UiFramework_1.UiFramework.getUiStateStorage().saveSetting(exports.FRONTSTAGE_SETTINGS_NAMESPACE, getFrontstageStateSettingName(stageId), setting);
1157
- return newState;
1158
- }
1159
- // istanbul ignore next
1160
- return state;
1185
+ return (defs || []).filter((def) => !(def.id in state.tabs));
1161
1186
  }
1162
- exports.saveFrontstagePopoutWidgetSizeAndPosition = saveFrontstagePopoutWidgetSizeAndPosition;
1163
1187
  //# sourceMappingURL=Frontstage.js.map