@acorex-platform/module-workplacesafety-management-client 0.0.33 → 0.0.38

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 (102) hide show
  1. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-acorex-platform-module-workplacesafety-management-client-mzaaZ6T3.mjs → acorex-platform-module-workplacesafety-management-client-acorex-platform-module-workplacesafety-management-client-Ds0Fkspp.mjs} +20 -12
  2. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-acorex-platform-module-workplacesafety-management-client-mzaaZ6T3.mjs.map → acorex-platform-module-workplacesafety-management-client-acorex-platform-module-workplacesafety-management-client-Ds0Fkspp.mjs.map} +1 -1
  3. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-control-hierarchy-levels.mjs.map +1 -1
  4. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-control-measure.mjs.map +1 -1
  5. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-hazard-ppe-rule.mjs +1 -1
  6. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-hazard-ppe-rule.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-hazard-register.mjs.map +1 -1
  8. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-hazard-risk.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-hazard.mjs +71 -88
  10. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-hazard.mjs.map +1 -1
  11. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-ppe-item.mjs.map +1 -1
  12. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-safety-plan-section.mjs +35 -1
  13. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-safety-plan-section.mjs.map +1 -1
  14. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-safety-plan-type-section.mjs +35 -1
  15. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-safety-plan-type-section.mjs.map +1 -1
  16. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-safety-plan-type.mjs.map +1 -1
  17. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-safety-plan-work-step.mjs.map +1 -1
  18. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-safety-plan.mjs +70 -11
  19. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-safety-plan.mjs.map +1 -1
  20. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-safety-template.mjs +3 -3
  21. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-safety-template.mjs.map +1 -1
  22. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-section-type.mjs.map +1 -1
  23. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-work-step-type.mjs +35 -1
  24. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entities-work-step-type.mjs.map +1 -1
  25. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-CeTmhod5.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-BI4TLvSE.mjs} +16 -16
  26. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-CeTmhod5.mjs.map → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-BI4TLvSE.mjs.map} +1 -1
  27. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-control-hierarchy-levels.entity-Dae2kkZe.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-control-hierarchy-levels.entity-COlCNnyK.mjs} +2 -2
  28. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-control-hierarchy-levels.entity-Dae2kkZe.mjs.map → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-control-hierarchy-levels.entity-COlCNnyK.mjs.map} +1 -1
  29. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-control-measure.entity-CpNcN6Pf.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-control-measure.entity-BrXGzqZU.mjs} +2 -2
  30. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-control-measure.entity-CpNcN6Pf.mjs.map → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-control-measure.entity-BrXGzqZU.mjs.map} +1 -1
  31. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard-ppe-rule.entity-BcsAnO9h.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard-ppe-rule.entity-DHJus7OP.mjs} +3 -3
  32. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard-ppe-rule.entity-DHJus7OP.mjs.map +1 -0
  33. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard-register.entity-C9wGZ3hB.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard-register.entity-CogjoDox.mjs} +2 -2
  34. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard-register.entity-C9wGZ3hB.mjs.map → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard-register.entity-CogjoDox.mjs.map} +1 -1
  35. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard-risk.entity-AUr2GVLU.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard-risk.entity-9UWHmIXV.mjs} +2 -2
  36. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard-risk.entity-AUr2GVLU.mjs.map → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard-risk.entity-9UWHmIXV.mjs.map} +1 -1
  37. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard.entity-J6fveZKA.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard.entity-CNPbxULL.mjs} +12 -29
  38. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard.entity-CNPbxULL.mjs.map +1 -0
  39. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-ppe-item.entity-3fQPlBBf.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-ppe-item.entity-D5iOBl3P.mjs} +2 -2
  40. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-ppe-item.entity-3fQPlBBf.mjs.map → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-ppe-item.entity-D5iOBl3P.mjs.map} +1 -1
  41. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-section-dependency-BRGcQo7H.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-section-dependency-TdIMIkM7.mjs} +37 -3
  42. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-section-dependency-TdIMIkM7.mjs.map +1 -0
  43. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-section.entity-BPx-3rYX.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-section.entity-DJAI-7lB.mjs} +3 -3
  44. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-section.entity-BPx-3rYX.mjs.map → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-section.entity-DJAI-7lB.mjs.map} +1 -1
  45. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-type-section.entity-_nG09ZpE.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-type-section.entity-BGZ1VAW3.mjs} +3 -3
  46. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-type-section.entity-_nG09ZpE.mjs.map → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-type-section.entity-BGZ1VAW3.mjs.map} +1 -1
  47. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-type.entity-CIH7W9R7.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-type.entity-B6NYL4xi.mjs} +2 -2
  48. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-type.entity-CIH7W9R7.mjs.map → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-type.entity-B6NYL4xi.mjs.map} +1 -1
  49. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-work-step.entity-DmFYsBhI.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-work-step.entity-BlCbf5qP.mjs} +2 -2
  50. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-work-step.entity-DmFYsBhI.mjs.map → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-work-step.entity-BlCbf5qP.mjs.map} +1 -1
  51. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan.entity-CUDh_ZfQ.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan.entity-BSUR9jqs.mjs} +72 -13
  52. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan.entity-BSUR9jqs.mjs.map +1 -0
  53. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-template.entity-BxNUXvae.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-template.entity-CIHy_hLh.mjs} +5 -5
  54. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-template.entity-CIHy_hLh.mjs.map +1 -0
  55. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-section-type.entity-73MUyaIk.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-section-type.entity-Cs4nIHou.mjs} +2 -2
  56. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-section-type.entity-73MUyaIk.mjs.map → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-section-type.entity-Cs4nIHou.mjs.map} +1 -1
  57. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-work-step-type.entity-Ujxum2GY.mjs → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-work-step-type.entity-CJFWDOoh.mjs} +3 -3
  58. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-work-step-type.entity-Ujxum2GY.mjs.map → acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-work-step-type.entity-CJFWDOoh.mjs.map} +1 -1
  59. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog.mjs +1 -1
  60. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts.mjs +38 -3
  61. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts.mjs.map +1 -1
  62. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-control-hierarchy-diagram-widget-view.component-CnTEwf_l.mjs → acorex-platform-module-workplacesafety-management-client-control-hierarchy-diagram-widget-view.component-eDWG-sJ7.mjs} +2 -2
  63. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-control-hierarchy-diagram-widget-view.component-CnTEwf_l.mjs.map → acorex-platform-module-workplacesafety-management-client-control-hierarchy-diagram-widget-view.component-eDWG-sJ7.mjs.map} +1 -1
  64. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-control-hierarchy-diagram.component-BI9VkzNw.mjs → acorex-platform-module-workplacesafety-management-client-control-hierarchy-diagram.component-CfxHwZtH.mjs} +3 -3
  65. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-control-hierarchy-diagram.component-BI9VkzNw.mjs.map → acorex-platform-module-workplacesafety-management-client-control-hierarchy-diagram.component-CfxHwZtH.mjs.map} +1 -1
  66. package/fesm2022/acorex-platform-module-workplacesafety-management-client-control-hierarchy-diagram.service-tMrUDnCb.mjs.map +1 -1
  67. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-hazard-ppe-rule-status.provider-o4bAwYcq.mjs → acorex-platform-module-workplacesafety-management-client-hazard-ppe-rule-status.provider-6ZWaO5DG.mjs} +3 -3
  68. package/fesm2022/acorex-platform-module-workplacesafety-management-client-hazard-ppe-rule-status.provider-6ZWaO5DG.mjs.map +1 -0
  69. package/fesm2022/acorex-platform-module-workplacesafety-management-client-hazard-risk-status.provider-B6IkRYbW.mjs.map +1 -1
  70. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-index-LxP1eZLY.mjs → acorex-platform-module-workplacesafety-management-client-index-gbDgxqrV.mjs} +316 -375
  71. package/fesm2022/acorex-platform-module-workplacesafety-management-client-index-gbDgxqrV.mjs.map +1 -0
  72. package/fesm2022/acorex-platform-module-workplacesafety-management-client-local-entities.mjs.map +1 -1
  73. package/fesm2022/acorex-platform-module-workplacesafety-management-client-ppe-item-viewer-widget-column.component-D2Mmow12.mjs.map +1 -1
  74. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-ppe-item-viewer-widget-edit.component-CQtVhCgw.mjs → acorex-platform-module-workplacesafety-management-client-ppe-item-viewer-widget-edit.component-BqHXrGn9.mjs} +2 -2
  75. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-ppe-item-viewer-widget-edit.component-CQtVhCgw.mjs.map → acorex-platform-module-workplacesafety-management-client-ppe-item-viewer-widget-edit.component-BqHXrGn9.mjs.map} +1 -1
  76. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-ppe-item-viewer.service-YS8FHiRu.mjs → acorex-platform-module-workplacesafety-management-client-ppe-item-viewer.service-BxcGph1I.mjs} +3 -3
  77. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-ppe-item-viewer.service-YS8FHiRu.mjs.map → acorex-platform-module-workplacesafety-management-client-ppe-item-viewer.service-BxcGph1I.mjs.map} +1 -1
  78. package/fesm2022/acorex-platform-module-workplacesafety-management-client-ppe-item-viewer.util-2Kl3_3sg.mjs.map +1 -1
  79. package/fesm2022/acorex-platform-module-workplacesafety-management-client-preview-control-hierarchy-diagram.command-Dd9xdo_y.mjs.map +1 -1
  80. package/fesm2022/acorex-platform-module-workplacesafety-management-client-preview-safety-plan.command-BU95c4xb.mjs +254 -0
  81. package/fesm2022/acorex-platform-module-workplacesafety-management-client-preview-safety-plan.command-BU95c4xb.mjs.map +1 -0
  82. package/fesm2022/acorex-platform-module-workplacesafety-management-client-publish-safety-plan.command-Ci-zcrmO.mjs.map +1 -1
  83. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-safety-plan-preview-modal.component-6i0RkG3L.mjs → acorex-platform-module-workplacesafety-management-client-safety-plan-preview-modal.component-CQ2xB7Va.mjs} +10 -10
  84. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-safety-plan-preview-modal.component-6i0RkG3L.mjs.map → acorex-platform-module-workplacesafety-management-client-safety-plan-preview-modal.component-CQ2xB7Va.mjs.map} +1 -1
  85. package/fesm2022/acorex-platform-module-workplacesafety-management-client-safety-plan-preview.service-DJP41MuL.mjs +36 -0
  86. package/fesm2022/acorex-platform-module-workplacesafety-management-client-safety-plan-preview.service-DJP41MuL.mjs.map +1 -0
  87. package/fesm2022/acorex-platform-module-workplacesafety-management-client-safety-plan-section-builder.types-LaN1NIgc.mjs +204 -0
  88. package/fesm2022/acorex-platform-module-workplacesafety-management-client-safety-plan-section-builder.types-LaN1NIgc.mjs.map +1 -0
  89. package/fesm2022/acorex-platform-module-workplacesafety-management-client-safety-plan-status.provider-BpWx3gIf.mjs.map +1 -1
  90. package/fesm2022/{acorex-platform-module-workplacesafety-management-client-save-safety-plan-sections.command-BlPzzCc2.mjs → acorex-platform-module-workplacesafety-management-client-save-safety-plan-sections.command-CLj3y_JD.mjs} +4 -209
  91. package/fesm2022/acorex-platform-module-workplacesafety-management-client-save-safety-plan-sections.command-CLj3y_JD.mjs.map +1 -0
  92. package/fesm2022/acorex-platform-module-workplacesafety-management-client.mjs +1 -1
  93. package/package.json +2 -2
  94. package/types/acorex-platform-module-workplacesafety-management-client-contracts.d.ts +26 -3
  95. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard-ppe-rule.entity-BcsAnO9h.mjs.map +0 -1
  96. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-hazard.entity-J6fveZKA.mjs.map +0 -1
  97. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan-section-dependency-BRGcQo7H.mjs.map +0 -1
  98. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-plan.entity-CUDh_ZfQ.mjs.map +0 -1
  99. package/fesm2022/acorex-platform-module-workplacesafety-management-client-contracts-entity-catalog-safety-template.entity-BxNUXvae.mjs.map +0 -1
  100. package/fesm2022/acorex-platform-module-workplacesafety-management-client-hazard-ppe-rule-status.provider-o4bAwYcq.mjs.map +0 -1
  101. package/fesm2022/acorex-platform-module-workplacesafety-management-client-index-LxP1eZLY.mjs.map +0 -1
  102. package/fesm2022/acorex-platform-module-workplacesafety-management-client-save-safety-plan-sections.command-BlPzzCc2.mjs.map +0 -1
@@ -1,31 +1,33 @@
1
- import { AXPWidgetsList, AXPWidgetsCatalog, AXPSystemStatusType } from '@acorex-platform/framework-shared/core';
2
- import { resolveEntityRowDisplayText } from '@acorex-platform/framework-client/common';
3
- import { AXPDataGenerator, AXPDeviceService, AXPHookService } from '@acorex-platform/framework-client/core';
1
+ import { AXPDataGenerator, AXPContextStore } from '@acorex-platform/framework-client/core';
4
2
  import { AXPEntityDataSelectorService, AXPEntityDefinitionRegistryService, AXPEntityService } from '@acorex-platform/framework-client/layout/entity';
5
- import { AXPCommandService, AXPRuntimeRemoteHookKeys } from '@acorex-platform/framework-client/runtime';
6
- import { AXPLayoutBuilderService, resolveLayoutBuilderDialogResult } from '@acorex-platform/framework-client/layout/builder';
3
+ import { AXPCommandService } from '@acorex-platform/framework-client/runtime';
7
4
  import { AXPPageLayoutBaseComponent, AXPPageLayoutBase } from '@acorex-platform/framework-client/layout/views';
8
- import { resolveSectionTypeKey, asSafetyPlanDisplayText, resolveEntityRefId, clearDependentItemsOnParentChange, enrichSectionTypeSnapshot, isStepTableSectionType, WORKPLACE_SAFETY_SECTION_TYPE_LOOKUP_WIDGET_OPTIONS, RootConfig, normalizeStepTableColumns, resolveSafetyPlanSectionItemFilterAsync, resolveSafetyPlanSectionItemEntityKey, resolveSafetyPlanSectionItemColumns, mapSafetyPlanSectionSelectedItems, dedupeSafetyPlanSectionItemSelection, sortStepTableColumns, stepTableColumnKey, resolveStepTableColumnLookupEntity, isStepTableColumnMultiLookup, stepTableColumnTitle, normalizeStepTableRows, AXMWorkplaceSafetyManagementCommandKeys, dedupeSafetyPlanSectionStructure, resolveSectionItemEntityName, collectBuiltInRepeatableSectionTypeIds, buildSectionStructureFromTypeSections, toBuilderValueFromStructure, SAFETY_PLAN_SECTIONS_PAGE_COMPONENT_KEY } from '@acorex-platform/module-workplacesafety-management-client/contracts';
5
+ import { resolveSectionTypeKey, asSafetyPlanDisplayText, resolveEntityRefId, clearDependentItemsOnParentChange, enrichSectionTypeSnapshot, isStepTableSectionType, WORKPLACE_SAFETY_SECTION_TYPE_LOOKUP_WIDGET_OPTIONS, RootConfig, normalizeStepTableColumns, resolveSafetyPlanSectionItemFilterAsync, resolveSafetyPlanSectionItemEntityKey, resolveSafetyPlanSectionItemColumns, mapSafetyPlanSectionSelectedItems, dedupeSafetyPlanSectionItemSelection, sortStepTableColumns, stepTableColumnKey, resolveStepTableColumnLookupEntity, isStepTableColumnMultiLookup, stepTableColumnTitle, normalizeStepTableRows, dedupeSafetyPlanSectionStructure, resolveSectionItemEntityName, collectBuiltInRepeatableSectionTypeIds, pickSafetyPlanTypeSectionsForStructure, buildSectionStructureFromTypeSections, toBuilderValueFromStructure, SAFETY_PLAN_SECTIONS_PAGE_COMPONENT_KEY } from '@acorex-platform/module-workplacesafety-management-client/contracts';
9
6
  import * as i0 from '@angular/core';
10
- import { inject, Injectable, input, output, viewChild, signal, computed, effect, ChangeDetectionStrategy, Component, untracked } from '@angular/core';
7
+ import { inject, Injectable, input, output, viewChild, signal, computed, effect, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
11
8
  import { isEqual, cloneDeep } from 'lodash';
12
- import { AXDialogService } from '@acorex/components/dialog';
9
+ import * as i1$1 from '@acorex/components/skeleton';
10
+ import { AXSkeletonModule } from '@acorex/components/skeleton';
11
+ import { AXPWidgetsList, AXPWidgetsCatalog, AXPSystemStatusType } from '@acorex-platform/framework-shared/core';
13
12
  import * as i1 from '@acorex/components/button';
14
13
  import { AXButtonModule } from '@acorex/components/button';
15
14
  import * as i2 from '@acorex/components/decorators';
16
15
  import { AXDecoratorModule } from '@acorex/components/decorators';
17
16
  import { AXToastService } from '@acorex/components/toast';
18
- import * as i1$1 from '@acorex/core/translation';
17
+ import * as i2$1 from '@acorex/core/translation';
19
18
  import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
19
+ import { AXPLayoutBuilderService } from '@acorex-platform/framework-client/layout/builder';
20
20
  import { AXPWidgetPropertyViewerService, AXPStandardSectionItemsBuilderComponent } from '@acorex-platform/framework-client/layout/components';
21
21
  import * as i3 from '@angular/common';
22
22
  import { CommonModule, AsyncPipe } from '@angular/common';
23
- import { n as normalizeSafetyPlanSectionBuilderValue, s as summarizeStepTableRow, S as SAFETY_PLAN_SECTIONS_SAVE_COMMAND, a as safetyPlanSectionsToBuilderValue, h as hydrateStepTableSectionsWithWorkSteps } from './acorex-platform-module-workplacesafety-management-client-save-safety-plan-sections.command-BlPzzCc2.mjs';
24
- export { A as AXMSaveSafetyPlanSectionsCommand } from './acorex-platform-module-workplacesafety-management-client-save-safety-plan-sections.command-BlPzzCc2.mjs';
25
- import { P as PPE_ITEM_VIEWER_WIDGET_NAME } from './acorex-platform-module-workplacesafety-management-client-acorex-platform-module-workplacesafety-management-client-mzaaZ6T3.mjs';
23
+ import { n as normalizeSafetyPlanSectionBuilderValue, s as summarizeStepTableRow, a as safetyPlanSectionsToBuilderValue, h as hydrateStepTableSectionsWithWorkSteps } from './acorex-platform-module-workplacesafety-management-client-safety-plan-section-builder.types-LaN1NIgc.mjs';
24
+ import { P as PPE_ITEM_VIEWER_WIDGET_NAME } from './acorex-platform-module-workplacesafety-management-client-acorex-platform-module-workplacesafety-management-client-Ds0Fkspp.mjs';
26
25
  import { AXP_BEHAVIOR_PROPERTY_GROUP } from '@acorex-platform/framework-client/layout/widgets';
27
26
  import { createBooleanProperty } from '@acorex-platform/framework-shared/widget-core';
28
- import { AXPopupService } from '@acorex/components/popup';
27
+ import { SAFETY_PLAN_SECTIONS_SAVE_COMMAND } from './acorex-platform-module-workplacesafety-management-client-save-safety-plan-sections.command-CLj3y_JD.mjs';
28
+ export { AXMSaveSafetyPlanSectionsCommand } from './acorex-platform-module-workplacesafety-management-client-save-safety-plan-sections.command-CLj3y_JD.mjs';
29
+ import { A as AXMSafetyPlanPreviewService } from './acorex-platform-module-workplacesafety-management-client-safety-plan-preview.service-DJP41MuL.mjs';
30
+ import { resolveEntityRowDisplayText } from '@acorex-platform/framework-client/common';
29
31
 
30
32
  //#region ----- Imports -----
31
33
  //#endregion
@@ -290,7 +292,11 @@ class AXMSafetyPlanSectionBuilderComponent {
290
292
  //#region ----- Lifecycle -----
291
293
  this.#syncValueToBuilder = effect(() => {
292
294
  const normalized = normalizeSafetyPlanSectionBuilderValue(this.value());
293
- this.builderValue.set(this.toBuilderValue(normalized));
295
+ const next = this.toBuilderValue(normalized);
296
+ if (isEqual(untracked(() => this.builderValue()), next)) {
297
+ return;
298
+ }
299
+ this.builderValue.set(next);
294
300
  }, /* @ts-ignore */
295
301
  ...(ngDevMode ? [{ debugName: "#syncValueToBuilder" }] : /* istanbul ignore next */ []));
296
302
  }
@@ -1258,59 +1264,29 @@ class AXMSafetyPlanSectionBuilderComponent {
1258
1264
  }
1259
1265
  }
1260
1266
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMSafetyPlanSectionBuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1261
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMSafetyPlanSectionBuilderComponent, isStandalone: true, selector: "axm-safety-plan-section-builder", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, safetyPlanId: { classPropertyName: "safetyPlanId", publicName: "safetyPlanId", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, viewQueries: [{ propertyName: "standardRef", first: true, predicate: AXPStandardSectionItemsBuilderComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"axm-safety-plan-section-builder\">\n @if (!readonly() && !hideHeaderActions() && allowAddSection()) {\n <div class=\"__header\">\n <div class=\"__header-left\"></div>\n <div class=\"__header-right\">\n <ax-button\n class=\"ax-sm\"\n [text]=\"\n '@workplacesafety-management:safety-plan-sections.entities.safety-plan-section.actions.add-section.title'\n | translate\n | async\n \"\n [color]=\"'primary'\"\n (onClick)=\"addSection()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-layer-group\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </div>\n }\n\n <axp-standard-section-items-builder\n class=\"block min-h-[200px]\"\n [value]=\"builderValue()\"\n [config]=\"standardConfig()\"\n [readonly]=\"readonly()\"\n (valueChange)=\"onBuilderValueChange($event)\"\n />\n</div>\n", styles: [".axm-safety-plan-section-builder .__header{margin-bottom:calc(var(--spacing, .25rem) * 3);display:flex;align-items:center;justify-content:space-between}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPStandardSectionItemsBuilderComponent, selector: "axp-standard-section-items-builder", inputs: ["value", "config", "readonly"], outputs: ["valueChange"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1267
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMSafetyPlanSectionBuilderComponent, isStandalone: true, selector: "axm-safety-plan-section-builder", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, safetyPlanId: { classPropertyName: "safetyPlanId", publicName: "safetyPlanId", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, viewQueries: [{ propertyName: "standardRef", first: true, predicate: AXPStandardSectionItemsBuilderComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"axm-safety-plan-section-builder\">\n @if (!readonly() && !hideHeaderActions() && allowAddSection()) {\n <div class=\"__header\">\n <div class=\"__header-left\"></div>\n <div class=\"__header-right\">\n <ax-button\n class=\"ax-sm\"\n [text]=\"\n '@workplacesafety-management:safety-plan-sections.entities.safety-plan-section.actions.add-section.title'\n | translate\n | async\n \"\n [color]=\"'primary'\"\n (onClick)=\"addSection()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-layer-group\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </div>\n }\n\n <axp-standard-section-items-builder\n class=\"block min-h-[200px]\"\n [value]=\"builderValue()\"\n [config]=\"standardConfig()\"\n [readonly]=\"readonly()\"\n (valueChange)=\"onBuilderValueChange($event)\"\n />\n</div>\n", styles: [".axm-safety-plan-section-builder .__header{margin-bottom:calc(var(--spacing, .25rem) * 3);display:flex;align-items:center;justify-content:space-between}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPStandardSectionItemsBuilderComponent, selector: "axp-standard-section-items-builder", inputs: ["value", "config", "readonly"], outputs: ["valueChange"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i2$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1262
1268
  }
1263
1269
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMSafetyPlanSectionBuilderComponent, decorators: [{
1264
1270
  type: Component,
1265
1271
  args: [{ selector: 'axm-safety-plan-section-builder', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, AXButtonModule, AXDecoratorModule, AXTranslationModule, AXPStandardSectionItemsBuilderComponent], template: "<div class=\"axm-safety-plan-section-builder\">\n @if (!readonly() && !hideHeaderActions() && allowAddSection()) {\n <div class=\"__header\">\n <div class=\"__header-left\"></div>\n <div class=\"__header-right\">\n <ax-button\n class=\"ax-sm\"\n [text]=\"\n '@workplacesafety-management:safety-plan-sections.entities.safety-plan-section.actions.add-section.title'\n | translate\n | async\n \"\n [color]=\"'primary'\"\n (onClick)=\"addSection()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-layer-group\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </div>\n }\n\n <axp-standard-section-items-builder\n class=\"block min-h-[200px]\"\n [value]=\"builderValue()\"\n [config]=\"standardConfig()\"\n [readonly]=\"readonly()\"\n (valueChange)=\"onBuilderValueChange($event)\"\n />\n</div>\n", styles: [".axm-safety-plan-section-builder .__header{margin-bottom:calc(var(--spacing, .25rem) * 3);display:flex;align-items:center;justify-content:space-between}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
1266
1272
  }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], safetyPlanId: [{ type: i0.Input, args: [{ isSignal: true, alias: "safetyPlanId", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], standardRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPStandardSectionItemsBuilderComponent), { isSignal: true }] }] } });
1267
1273
 
1268
- //#region ----- Imports -----
1269
- //#endregion
1270
- //#region ----- Service -----
1271
- class AXMSafetyPlanPreviewService {
1272
- constructor() {
1273
- //#region ----- Services & Dependencies -----
1274
- this.popupService = inject(AXPopupService);
1275
- this.deviceService = inject(AXPDeviceService);
1276
- }
1277
- //#endregion
1278
- //#region ----- Public API -----
1279
- async open(options) {
1280
- const { AXMSafetyPlanPreviewModalComponent } = await import('./acorex-platform-module-workplacesafety-management-client-safety-plan-preview-modal.component-6i0RkG3L.mjs');
1281
- await this.popupService.open(AXMSafetyPlanPreviewModalComponent, {
1282
- title: options.title,
1283
- size: this.deviceService.isSmall() ? 'full' : 'lg',
1284
- data: {
1285
- structure: options.structure,
1286
- },
1287
- });
1288
- }
1289
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMSafetyPlanPreviewService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1290
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMSafetyPlanPreviewService, providedIn: 'root' }); }
1291
- }
1292
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMSafetyPlanPreviewService, decorators: [{
1293
- type: Injectable,
1294
- args: [{ providedIn: 'root' }]
1295
- }] });
1296
-
1297
1274
  //#region ---- Imports ----
1298
1275
  //#endregion
1299
1276
  //#region ---- Constants ----
1300
1277
  const SAFETY_PLAN_SECTIONS_ADD_SECTION_COMMAND = 'SafetyPlan:Sections:AddSection';
1301
1278
  const SAFETY_PLAN_SECTIONS_PREVIEW_COMMAND = 'SafetyPlan:Sections:Preview';
1302
1279
  const SAFETY_PLAN_SECTIONS_DISCARD_COMMAND = 'SafetyPlan:Sections:Discard';
1303
- const SAFETY_PLAN_SECTIONS_CHANGE_PLAN_TYPE_COMMAND = 'SafetyPlan:Sections:ChangePlanType';
1304
1280
  const SAFETY_PLAN_SECTION_ENTITY = `${RootConfig.module.name}.${RootConfig.entities.safetyPlanSection.name}`;
1305
1281
  const SAFETY_PLAN_WORK_STEP_ENTITY = `${RootConfig.module.name}.${RootConfig.entities.safetyPlanWorkStep.name}`;
1306
1282
  const SAFETY_PLAN_TYPE_SECTION_ENTITY = `${RootConfig.module.name}.${RootConfig.entities.safetyPlanTypeSection.name}`;
1307
- const SAFETY_PLAN_TYPE_ENTITY = RootConfig.entities.safetyPlanType.source;
1308
1283
  const SECTION_TYPE_ENTITY = `${RootConfig.module.name}.${RootConfig.entities.sectionType.name}`;
1309
1284
  //#endregion
1310
1285
  //#region ---- Component ----
1311
1286
  class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
1312
1287
  constructor() {
1313
1288
  super(...arguments);
1289
+ /** Default `{}`: avoid NG0950 before page-component-renderer calls setInput. */
1314
1290
  this.rootContext = input({}, /* @ts-ignore */
1315
1291
  ...(ngDevMode ? [{ debugName: "rootContext" }] : /* istanbul ignore next */ []));
1316
1292
  this.pageConfig = input(/* @ts-ignore */
@@ -1321,9 +1297,7 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
1321
1297
  ...(ngDevMode ? [{ debugName: "builderRef" }] : /* istanbul ignore next */ []));
1322
1298
  this.commandService = inject(AXPCommandService);
1323
1299
  this.entityService = inject(AXPEntityService);
1324
- this.dialogService = inject(AXDialogService);
1325
- this.layoutBuilder = inject(AXPLayoutBuilderService);
1326
- this.hooks = inject(AXPHookService);
1300
+ this.contextStore = inject(AXPContextStore);
1327
1301
  this.hostPageLayout = inject(AXPPageLayoutBase, { optional: true, skipSelf: true });
1328
1302
  this.previewService = inject(AXMSafetyPlanPreviewService);
1329
1303
  this.baselineValue = signal(null, /* @ts-ignore */
@@ -1340,136 +1314,255 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
1340
1314
  ...(ngDevMode ? [{ debugName: "inflightSyncKey" }] : /* istanbul ignore next */ []));
1341
1315
  this.appliedPlanTypeId = signal(null, /* @ts-ignore */
1342
1316
  ...(ngDevMode ? [{ debugName: "appliedPlanTypeId" }] : /* istanbul ignore next */ []));
1343
- /** Keeps plan type in sync after Change Plan Type when parent form context is mutated in place. */
1344
- this.planTypeOverride = signal(null, /* @ts-ignore */
1345
- ...(ngDevMode ? [{ debugName: "planTypeOverride" }] : /* istanbul ignore next */ []));
1317
+ this.appliedStructureId = signal(null, /* @ts-ignore */
1318
+ ...(ngDevMode ? [{ debugName: "appliedStructureId" }] : /* istanbul ignore next */ []));
1319
+ /**
1320
+ * Bumped only when the user changes structure after a successful sync (see `#detectStructureUserChange`).
1321
+ * Keeps `#syncFromContext` from tracking context `structureId` during unrelated context churn.
1322
+ */
1323
+ this.structureReloadToken = signal(0, /* @ts-ignore */
1324
+ ...(ngDevMode ? [{ debugName: "structureReloadToken" }] : /* istanbul ignore next */ []));
1325
+ /**
1326
+ * Stable builder options — same pattern as questionnaire `prePostConfigStable`
1327
+ * (new object every CD caused builder config thrash / flicker).
1328
+ */
1329
+ this.builderOptionsStable = signal({
1330
+ hideHeaderActions: true,
1331
+ readonly: false,
1332
+ allowAddSection: true,
1333
+ allowAddItems: true,
1334
+ allowReorderSections: true,
1335
+ allowEditSection: false,
1336
+ allowEditItem: false,
1337
+ }, /* @ts-ignore */
1338
+ ...(ngDevMode ? [{ debugName: "builderOptionsStable" }] : /* istanbul ignore next */ []));
1346
1339
  this.safetyPlanId = computed(() => {
1347
1340
  const raw = this.rootContext()?.['id'];
1348
1341
  return typeof raw === 'string' && raw.length > 0 ? raw : null;
1349
1342
  }, /* @ts-ignore */
1350
1343
  ...(ngDevMode ? [{ debugName: "safetyPlanId" }] : /* istanbul ignore next */ []));
1351
1344
  this.planTypeId = computed(() => {
1352
- const override = this.planTypeOverride();
1353
- if (override) {
1354
- return override;
1355
- }
1356
1345
  const ctx = this.rootContext() ?? {};
1357
1346
  return (resolveEntityRefId(ctx['safetyPlanTypeId']) ??
1358
1347
  resolveEntityRefId(ctx['safetyPlanType']?.id) ??
1359
1348
  resolveEntityRefId(ctx['safetyPlanType']));
1360
1349
  }, /* @ts-ignore */
1361
1350
  ...(ngDevMode ? [{ debugName: "planTypeId" }] : /* istanbul ignore next */ []));
1362
- this.hasPlanType = computed(() => !!this.planTypeId(), /* @ts-ignore */
1363
- ...(ngDevMode ? [{ debugName: "hasPlanType" }] : /* istanbul ignore next */ []));
1351
+ this.structureId = computed(() => {
1352
+ const ctx = this.rootContext() ?? {};
1353
+ return (resolveEntityRefId(ctx['structureId']) ??
1354
+ resolveEntityRefId(ctx['structure']?.id) ??
1355
+ resolveEntityRefId(ctx['structure']));
1356
+ }, /* @ts-ignore */
1357
+ ...(ngDevMode ? [{ debugName: "structureId" }] : /* istanbul ignore next */ []));
1358
+ this.hasStructure = computed(() => !!this.structureId(), /* @ts-ignore */
1359
+ ...(ngDevMode ? [{ debugName: "hasStructure" }] : /* istanbul ignore next */ []));
1360
+ /**
1361
+ * Covers the first paint before `#syncFromContext` sets `isLoadingStructure`, and the full sync span.
1362
+ * Avoids flashing an empty builder after create-and-continue.
1363
+ */
1364
+ this.showStructureLoading = computed(() => {
1365
+ if (this.isLoadingStructure()) {
1366
+ return true;
1367
+ }
1368
+ if (!(this.safetyPlanId() || this.hasStructure())) {
1369
+ return false;
1370
+ }
1371
+ return this.lastSyncedKey() == null && this.committedValue() == null;
1372
+ }, /* @ts-ignore */
1373
+ ...(ngDevMode ? [{ debugName: "showStructureLoading" }] : /* istanbul ignore next */ []));
1364
1374
  this.isDraftPlan = computed(() => {
1365
1375
  const status = this.rootContext()?.['status'];
1366
1376
  return !status || status === AXPSystemStatusType.Draft;
1367
1377
  }, /* @ts-ignore */
1368
1378
  ...(ngDevMode ? [{ debugName: "isDraftPlan" }] : /* istanbul ignore next */ []));
1369
- this.builderOptions = computed(() => ({
1370
- hideHeaderActions: true,
1371
- readonly: !this.isDraftPlan() || this.isLoadingStructure(),
1372
- allowAddSection: this.isDraftPlan() && !this.isLoadingStructure(),
1373
- allowAddItems: this.isDraftPlan() && !this.isLoadingStructure(),
1374
- allowReorderSections: this.isDraftPlan() && !this.isLoadingStructure(),
1375
- ...(this.pageConfig() ?? {}),
1376
- ...(this.options() ?? {}),
1377
- allowEditSection: false,
1378
- allowEditItem: false,
1379
- }), /* @ts-ignore */
1379
+ /** Stable reference for the builder — updated only when option values change. */
1380
+ this.builderOptions = computed(() => this.builderOptionsStable(), /* @ts-ignore */
1380
1381
  ...(ngDevMode ? [{ debugName: "builderOptions" }] : /* istanbul ignore next */ []));
1381
1382
  this.isDirty = computed(() => {
1382
1383
  return !isEqual(this.baselineValue() ?? { sections: [] }, this.committedValue() ?? { sections: [] });
1383
1384
  }, /* @ts-ignore */
1384
1385
  ...(ngDevMode ? [{ debugName: "isDirty" }] : /* istanbul ignore next */ []));
1386
+ /** Keep builder options stable across rootContext snapshot churn (questionnaire pattern). */
1387
+ this.#stabilizeBuilderOptions = effect(() => {
1388
+ const draft = this.isDraftPlan();
1389
+ const next = {
1390
+ hideHeaderActions: true,
1391
+ readonly: !draft,
1392
+ allowAddSection: draft,
1393
+ allowAddItems: draft,
1394
+ allowReorderSections: draft,
1395
+ allowEditSection: false,
1396
+ allowEditItem: false,
1397
+ };
1398
+ const current = untracked(() => this.builderOptionsStable());
1399
+ if (!isEqual(current, next)) {
1400
+ this.builderOptionsStable.set(next);
1401
+ }
1402
+ }, /* @ts-ignore */
1403
+ ...(ngDevMode ? [{ debugName: "#stabilizeBuilderOptions" }] : /* istanbul ignore next */ []));
1404
+ /**
1405
+ * Plan type changed on the form — clear structure and wait for a manual structure pick.
1406
+ * Does not rebuild sections; structure selection drives the next load.
1407
+ */
1408
+ this.#detectPlanTypeUserChange = effect(() => {
1409
+ const typeId = this.planTypeId();
1410
+ const applied = untracked(() => this.appliedPlanTypeId());
1411
+ if (!typeId || applied == null || typeId === applied) {
1412
+ return;
1413
+ }
1414
+ this.appliedPlanTypeId.set(typeId);
1415
+ this.appliedStructureId.set(null);
1416
+ this.lastSyncedKey.set(null);
1417
+ this.inflightSyncKey.set(null);
1418
+ this.updateRootContextField('structureId', null);
1419
+ this.updateRootContextField('structure', null);
1420
+ }, /* @ts-ignore */
1421
+ ...(ngDevMode ? [{ debugName: "#detectPlanTypeUserChange" }] : /* istanbul ignore next */ []));
1422
+ /**
1423
+ * User changed structure after a successful sync — bump token so `#syncFromContext` reloads.
1424
+ */
1425
+ this.#detectStructureUserChange = effect(() => {
1426
+ const contextStructureId = this.structureId();
1427
+ const applied = untracked(() => this.appliedStructureId());
1428
+ if (!contextStructureId || applied == null) {
1429
+ return;
1430
+ }
1431
+ if (contextStructureId === applied) {
1432
+ return;
1433
+ }
1434
+ if (untracked(() => this.lastSyncedKey()) == null) {
1435
+ return;
1436
+ }
1437
+ this.lastSyncedKey.set(null);
1438
+ this.structureReloadToken.update((n) => n + 1);
1439
+ }, /* @ts-ignore */
1440
+ ...(ngDevMode ? [{ debugName: "#detectStructureUserChange" }] : /* istanbul ignore next */ []));
1385
1441
  this.#syncFromContext = effect((onCleanup) => {
1442
+ this.structureReloadToken();
1386
1443
  const planId = this.safetyPlanId();
1387
1444
  const typeId = this.planTypeId();
1388
- const syncKey = `${planId ?? ''}|${typeId ?? ''}`;
1389
- // Already applied or already loading for this plan/type pair.
1445
+ const structureId = this.structureId();
1446
+ const syncKey = this.buildSyncKey(planId, typeId, structureId);
1390
1447
  if (untracked(() => this.lastSyncedKey()) === syncKey ||
1391
1448
  untracked(() => this.inflightSyncKey()) === syncKey) {
1392
1449
  return;
1393
1450
  }
1451
+ const inflight = untracked(() => this.inflightSyncKey());
1452
+ if (inflight && inflight.startsWith(`${planId ?? ''}|${typeId ?? ''}|`)) {
1453
+ return;
1454
+ }
1394
1455
  this.inflightSyncKey.set(syncKey);
1395
1456
  let cancelled = false;
1457
+ let activeSyncKey = syncKey;
1396
1458
  const clearInflight = () => {
1397
- if (untracked(() => this.inflightSyncKey()) === syncKey) {
1459
+ if (untracked(() => this.inflightSyncKey()) === activeSyncKey) {
1398
1460
  this.inflightSyncKey.set(null);
1399
1461
  }
1400
1462
  };
1401
- const markSynced = () => {
1402
- this.lastSyncedKey.set(syncKey);
1403
- clearInflight();
1463
+ const markSynced = (finalStructureId = structureId) => {
1464
+ activeSyncKey = this.buildSyncKey(planId, typeId, finalStructureId);
1465
+ this.lastSyncedKey.set(activeSyncKey);
1466
+ this.inflightSyncKey.set(null);
1404
1467
  };
1405
1468
  const run = async () => {
1406
1469
  if (cancelled) {
1407
1470
  return;
1408
1471
  }
1409
- const repeatableSectionTypeIds = await this.loadRepeatableSectionTypeIds();
1410
- if (cancelled) {
1411
- return;
1412
- }
1413
- // Edit: load independent saved sections once — never append type defaults on top.
1414
- if (planId) {
1472
+ // Create (no plan yet): exit without SectionType query until structure defaults are needed.
1473
+ if (!planId) {
1474
+ if (!typeId) {
1475
+ this.appliedPlanTypeId.set(null);
1476
+ this.appliedStructureId.set(null);
1477
+ this.applyStructure({ sections: [] }, { asBaseline: true });
1478
+ markSynced(null);
1479
+ return;
1480
+ }
1481
+ // Plan type alone must not auto-pick a structure or rebuild sections.
1482
+ if (!structureId) {
1483
+ this.appliedPlanTypeId.set(typeId);
1484
+ this.appliedStructureId.set(null);
1485
+ markSynced(null);
1486
+ return;
1487
+ }
1415
1488
  this.isLoadingStructure.set(true);
1416
1489
  try {
1417
- const loaded = await this.fetchSectionsFromBackend(planId, repeatableSectionTypeIds);
1418
- if (cancelled)
1419
- return;
1420
- if (loaded.sections.length > 0) {
1421
- // Replace UI from backend (deduped). Never append defaults on top of saved rows.
1422
- this.applyStructure(loaded, { asBaseline: true });
1423
- this.appliedPlanTypeId.set(typeId);
1424
- markSynced();
1490
+ const repeatableSectionTypeIds = await this.loadRepeatableSectionTypeIds();
1491
+ if (cancelled) {
1425
1492
  return;
1426
1493
  }
1427
- // No saved rows yet — fall through to type defaults when type is known.
1494
+ const defaults = await this.loadDefaultsForStructure(typeId, structureId, repeatableSectionTypeIds);
1495
+ if (cancelled)
1496
+ return;
1497
+ this.applyStructure(defaults, { asBaseline: true });
1498
+ this.appliedPlanTypeId.set(typeId);
1499
+ this.appliedStructureId.set(structureId);
1500
+ markSynced(structureId);
1428
1501
  }
1429
1502
  catch {
1430
1503
  if (cancelled)
1431
1504
  return;
1432
1505
  clearInflight();
1433
1506
  await this.showStructureLoadError();
1434
- return;
1435
1507
  }
1436
1508
  finally {
1437
1509
  if (!cancelled) {
1438
1510
  this.isLoadingStructure.set(false);
1439
1511
  }
1440
1512
  }
1513
+ return;
1514
+ }
1515
+ // Edit / create-and-continue: one continuous loading span through SectionType → sections → defaults.
1516
+ this.isLoadingStructure.set(true);
1517
+ try {
1518
+ const repeatableSectionTypeIds = await this.loadRepeatableSectionTypeIds();
1441
1519
  if (cancelled) {
1442
1520
  return;
1443
1521
  }
1444
- }
1445
- if (!typeId) {
1446
- this.appliedPlanTypeId.set(null);
1447
- this.applyStructure({ sections: [] }, { asBaseline: true });
1448
- markSynced();
1449
- return;
1450
- }
1451
- const previousTypeId = untracked(() => this.appliedPlanTypeId());
1452
- const currentSections = untracked(() => this.committedValue()?.sections ?? []);
1453
- if (previousTypeId && previousTypeId !== typeId && currentSections.length > 0) {
1454
- const confirmed = await this.confirmReplaceStructure();
1522
+ // Load independent saved sections once — never append type defaults on top.
1523
+ const previousStructureId = untracked(() => this.appliedStructureId());
1524
+ const structureChanged = !!structureId && !!previousStructureId && previousStructureId !== structureId;
1525
+ if (structureChanged && this.isDraftPlan()) {
1526
+ const defaults = await this.loadDefaultsForStructure(typeId ?? '', structureId, repeatableSectionTypeIds);
1527
+ if (cancelled)
1528
+ return;
1529
+ this.applyStructure(defaults, { asBaseline: true });
1530
+ this.appliedPlanTypeId.set(typeId);
1531
+ this.appliedStructureId.set(structureId);
1532
+ markSynced(structureId);
1533
+ return;
1534
+ }
1535
+ const loaded = await this.fetchSectionsFromBackend(planId, repeatableSectionTypeIds);
1455
1536
  if (cancelled)
1456
1537
  return;
1457
- if (!confirmed) {
1458
- // Keep previous structure; mark new type as handled so we do not loop.
1538
+ if (loaded.sections.length > 0) {
1539
+ this.applyStructure(loaded, { asBaseline: true });
1459
1540
  this.appliedPlanTypeId.set(typeId);
1460
- markSynced();
1541
+ this.appliedStructureId.set(structureId);
1542
+ markSynced(structureId);
1461
1543
  return;
1462
1544
  }
1463
- }
1464
- this.isLoadingStructure.set(true);
1465
- try {
1466
- const defaults = await this.loadDefaultsForPlanType(typeId, repeatableSectionTypeIds);
1545
+ if (!typeId) {
1546
+ this.appliedPlanTypeId.set(null);
1547
+ this.appliedStructureId.set(null);
1548
+ this.applyStructure({ sections: [] }, { asBaseline: true });
1549
+ markSynced(null);
1550
+ return;
1551
+ }
1552
+ // Plan type alone must not auto-pick a structure or rebuild sections.
1553
+ if (!structureId) {
1554
+ this.appliedPlanTypeId.set(typeId);
1555
+ this.appliedStructureId.set(null);
1556
+ markSynced(null);
1557
+ return;
1558
+ }
1559
+ const defaults = await this.loadDefaultsForStructure(typeId, structureId, repeatableSectionTypeIds);
1467
1560
  if (cancelled)
1468
1561
  return;
1469
- // Replace (never append) the current collection with type defaults.
1470
1562
  this.applyStructure(defaults, { asBaseline: true });
1471
1563
  this.appliedPlanTypeId.set(typeId);
1472
- markSynced();
1564
+ this.appliedStructureId.set(structureId);
1565
+ markSynced(structureId);
1473
1566
  }
1474
1567
  catch {
1475
1568
  if (cancelled)
@@ -1491,6 +1584,17 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
1491
1584
  }, /* @ts-ignore */
1492
1585
  ...(ngDevMode ? [{ debugName: "#syncFromContext" }] : /* istanbul ignore next */ []));
1493
1586
  }
1587
+ /** Keep builder options stable across rootContext snapshot churn (questionnaire pattern). */
1588
+ #stabilizeBuilderOptions;
1589
+ /**
1590
+ * Plan type changed on the form — clear structure and wait for a manual structure pick.
1591
+ * Does not rebuild sections; structure selection drives the next load.
1592
+ */
1593
+ #detectPlanTypeUserChange;
1594
+ /**
1595
+ * User changed structure after a successful sync — bump token so `#syncFromContext` reloads.
1596
+ */
1597
+ #detectStructureUserChange;
1494
1598
  #syncFromContext;
1495
1599
  onValueChange(value) {
1496
1600
  const withOrder = normalizeSafetyPlanSectionBuilderValue({
@@ -1499,9 +1603,12 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
1499
1603
  sortOrder: index + 1,
1500
1604
  })),
1501
1605
  });
1606
+ if (isEqual(untracked(() => this.committedValue()), withOrder)) {
1607
+ return;
1608
+ }
1502
1609
  this.committedValue.set(withOrder);
1503
- this.updateRootContextField('sectionStructure', withOrder);
1504
- this.updateRootContextField('sections', withOrder);
1610
+ this.persistContextField('sectionStructure', withOrder, 'user');
1611
+ this.persistContextField('sections', withOrder, 'user');
1505
1612
  this.recompute();
1506
1613
  }
1507
1614
  getWizardStepContext() {
@@ -1517,9 +1624,10 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
1517
1624
  }
1518
1625
  async getPrimaryMenuItems() {
1519
1626
  const actions = [];
1520
- const canPreview = !this.isLoadingStructure() &&
1521
- (!!this.hasPlanType() || !!this.safetyPlanId() || (this.committedValue()?.sections.length ?? 0) > 0);
1522
- if (this.isDraftPlan() && !this.isLoadingStructure()) {
1627
+ const loading = this.showStructureLoading();
1628
+ const canPreview = !loading &&
1629
+ (!!this.hasStructure() || !!this.safetyPlanId() || (this.committedValue()?.sections.length ?? 0) > 0);
1630
+ if (this.isDraftPlan() && !loading) {
1523
1631
  actions.push({
1524
1632
  title: '@workplacesafety-management:safety-plan-sections.entities.safety-plan-section.actions.add-section.title',
1525
1633
  icon: 'fa-light fa-layer-group',
@@ -1534,23 +1642,14 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
1534
1642
  title: '@workplacesafety-management:safety-plan-sections.entities.safety-plan-section.actions.preview.title',
1535
1643
  icon: 'fa-light fa-eye',
1536
1644
  zone: 'header',
1537
- priority: 'secondary',
1645
+ priority: 'primary',
1538
1646
  color: 'default',
1539
1647
  command: { name: SAFETY_PLAN_SECTIONS_PREVIEW_COMMAND, options: {} },
1540
1648
  });
1541
1649
  }
1542
- if (!this.isDraftPlan() || this.isLoadingStructure()) {
1650
+ if (!this.isDraftPlan() || loading) {
1543
1651
  return actions;
1544
1652
  }
1545
- actions.push({
1546
- title: '@workplacesafety-management:safety-plans.actions.change-plan-type.title',
1547
- icon: 'fa-light fa-arrow-right-arrow-left',
1548
- zone: 'header',
1549
- priority: 'secondary',
1550
- color: 'default',
1551
- visible: this.isDraftPlan() && (!!this.planTypeId() || !!this.safetyPlanId()),
1552
- command: { name: SAFETY_PLAN_SECTIONS_CHANGE_PLAN_TYPE_COMMAND, options: {} },
1553
- });
1554
1653
  if (this.safetyPlanId()) {
1555
1654
  actions.push({
1556
1655
  title: '@general:actions.discard.title',
@@ -1581,10 +1680,6 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
1581
1680
  await this.handlePreview();
1582
1681
  return;
1583
1682
  }
1584
- if (command.name === SAFETY_PLAN_SECTIONS_CHANGE_PLAN_TYPE_COMMAND) {
1585
- await this.handleChangePlanType();
1586
- return;
1587
- }
1588
1683
  if (command.name === SAFETY_PLAN_SECTIONS_DISCARD_COMMAND) {
1589
1684
  this.handleDiscard();
1590
1685
  return;
@@ -1603,186 +1698,6 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
1603
1698
  structure: cloneDeep(this.committedValue() ?? { sections: [] }),
1604
1699
  });
1605
1700
  }
1606
- async handleChangePlanType() {
1607
- if (!this.isDraftPlan()) {
1608
- this.toastService.show({
1609
- color: 'warning',
1610
- title: await this.translateService.translateAsync('@general:messages.generic.error.title'),
1611
- content: await this.translateService.translateAsync('@workplacesafety-management:safety-plans.messages.section-structure.draft-only'),
1612
- });
1613
- return;
1614
- }
1615
- const selection = await this.promptChangePlanTypeDialog();
1616
- if (!selection) {
1617
- return;
1618
- }
1619
- const currentTypeId = this.planTypeId();
1620
- if (currentTypeId && currentTypeId === selection.safetyPlanTypeId) {
1621
- this.toastService.show({
1622
- color: 'warning',
1623
- title: await this.translateService.translateAsync('@general:messages.generic.error.title'),
1624
- content: await this.translateService.translateAsync('@workplacesafety-management:safety-plans.messages.section-structure.same-plan-type'),
1625
- });
1626
- return;
1627
- }
1628
- const confirmed = await this.confirmChangePlanType();
1629
- if (!confirmed) {
1630
- return;
1631
- }
1632
- const planId = this.safetyPlanId();
1633
- this.isLoadingStructure.set(true);
1634
- try {
1635
- if (planId) {
1636
- await this.applyPersistedPlanTypeChange(planId, selection);
1637
- }
1638
- else {
1639
- await this.applyWizardPlanTypeChange(selection);
1640
- }
1641
- }
1642
- catch {
1643
- this.toastService.show({
1644
- color: 'danger',
1645
- title: await this.translateService.translateAsync('@general:messages.generic.error.title'),
1646
- content: await this.translateService.translateAsync('@workplacesafety-management:safety-plans.messages.section-structure.change-plan-type-failed'),
1647
- });
1648
- }
1649
- finally {
1650
- this.isLoadingStructure.set(false);
1651
- }
1652
- }
1653
- async promptChangePlanTypeDialog() {
1654
- const ctx = this.rootContext() ?? {};
1655
- const currentType = ctx['safetyPlanType'] ?? {};
1656
- const currentTypeId = this.planTypeId() ?? '';
1657
- const result = await this.layoutBuilder
1658
- .create()
1659
- .dialog((dialog) => {
1660
- dialog
1661
- .setTitle('@workplacesafety-management:safety-plans.actions.change-plan-type.dialog.title')
1662
- .setSize('md')
1663
- .setCloseButton(true)
1664
- .setContext({
1665
- safetyPlanTypeId: currentTypeId,
1666
- safetyPlanType: currentTypeId
1667
- ? {
1668
- id: currentTypeId,
1669
- title: typeof currentType.title === 'string' ? currentType.title : undefined,
1670
- code: typeof currentType.code === 'string' ? currentType.code : undefined,
1671
- }
1672
- : undefined,
1673
- })
1674
- .content((flex) => {
1675
- flex
1676
- .setDirection('column')
1677
- .setGap('12px')
1678
- .formField('@workplacesafety-management:safety-plans.actions.change-plan-type.dialog.fields.plan-type.title', (field) => {
1679
- field.path('safetyPlanTypeId');
1680
- field.lookupBox({
1681
- entity: SAFETY_PLAN_TYPE_ENTITY,
1682
- look: 'select',
1683
- searchable: true,
1684
- textField: 'title',
1685
- valueField: 'id',
1686
- columns: ['code', 'title'],
1687
- expose: [
1688
- { source: 'id', target: 'safetyPlanType.id' },
1689
- { source: 'title', target: 'safetyPlanType.title' },
1690
- { source: 'code', target: 'safetyPlanType.code' },
1691
- ],
1692
- validations: [{ rule: 'required' }],
1693
- });
1694
- });
1695
- })
1696
- .setActions((actions) => {
1697
- actions
1698
- .cancel('@general:actions.cancel.title')
1699
- .submit('@workplacesafety-management:safety-plans.actions.change-plan-type.dialog.actions.continue');
1700
- })
1701
- .onAction(async (dialogRef) => {
1702
- if (dialogRef.action() === 'cancel') {
1703
- return null;
1704
- }
1705
- const context = dialogRef.context();
1706
- const safetyPlanTypeId = resolveEntityRefId(context.safetyPlanTypeId);
1707
- if (!safetyPlanTypeId) {
1708
- throw new Error((await this.translateService.translateAsync('@workplacesafety-management:safety-plans.actions.change-plan-type.dialog.fields.plan-type.placeholder')) || 'Select a Plan Type');
1709
- }
1710
- return {
1711
- safetyPlanTypeId,
1712
- safetyPlanType: context.safetyPlanType?.id
1713
- ? context.safetyPlanType
1714
- : { id: safetyPlanTypeId },
1715
- };
1716
- });
1717
- })
1718
- .show();
1719
- return resolveLayoutBuilderDialogResult(result);
1720
- }
1721
- async confirmChangePlanType() {
1722
- const title = (await this.translateService.translateAsync('@workplacesafety-management:safety-plans.messages.section-structure.confirm-change-plan-type.title')) || 'Change Plan Type?';
1723
- const message = (await this.translateService.translateAsync('@workplacesafety-management:safety-plans.messages.section-structure.confirm-change-plan-type.message')) ||
1724
- 'Changing the Plan Type will discard all existing sections and their selected values. The default sections for the new Plan Type will be loaded. Do you want to continue?';
1725
- const dialogResult = await this.dialogService.confirm(title, message, 'danger', 'horizontal');
1726
- return dialogResult.result === true;
1727
- }
1728
- async applyPersistedPlanTypeChange(planId, selection) {
1729
- const payload = await this.hooks.runAsync(AXPRuntimeRemoteHookKeys.CommandExecute, {
1730
- name: AXMWorkplaceSafetyManagementCommandKeys.SafetyPlan.ChangeType,
1731
- input: {
1732
- id: planId,
1733
- safetyPlanTypeId: selection.safetyPlanTypeId,
1734
- safetyPlanType: selection.safetyPlanType,
1735
- },
1736
- });
1737
- if (!payload.handled || !payload.result?.success) {
1738
- const text = payload.result?.message?.text;
1739
- this.toastService.show({
1740
- color: 'danger',
1741
- title: await this.translateService.translateAsync('@general:messages.generic.error.title'),
1742
- content: typeof text === 'string' && text.startsWith('@')
1743
- ? await this.translateService.translateAsync(text)
1744
- : await this.translateService.translateAsync('@workplacesafety-management:safety-plans.messages.section-structure.change-plan-type-failed'),
1745
- });
1746
- return;
1747
- }
1748
- const data = payload.result.data;
1749
- const nextTypeId = data?.safetyPlanTypeId ?? selection.safetyPlanTypeId;
1750
- const nextType = data?.safetyPlanType ?? selection.safetyPlanType ?? { id: nextTypeId };
1751
- const repeatableSectionTypeIds = await this.loadRepeatableSectionTypeIds();
1752
- const saved = dedupeSafetyPlanSectionStructure(safetyPlanSectionsToBuilderValue((data?.sections ?? [])), { repeatableSectionTypeIds });
1753
- this.planTypeOverride.set(nextTypeId);
1754
- this.updateRootContextField('safetyPlanTypeId', nextTypeId);
1755
- this.updateRootContextField('safetyPlanType', nextType);
1756
- this.appliedPlanTypeId.set(nextTypeId);
1757
- this.lastSyncedKey.set(`${planId}|${nextTypeId}`);
1758
- this.inflightSyncKey.set(null);
1759
- this.applyStructure(saved, { asBaseline: true });
1760
- this.builderRef()?.syncAfterSave(saved);
1761
- this.recompute();
1762
- this.toastService.show({
1763
- color: 'success',
1764
- title: await this.translateService.translateAsync('@general:messages.generic.success.title'),
1765
- content: await this.translateService.translateAsync('@workplacesafety-management:safety-plans.actions.change-plan-type.dialog.success'),
1766
- });
1767
- }
1768
- async applyWizardPlanTypeChange(selection) {
1769
- const repeatableSectionTypeIds = await this.loadRepeatableSectionTypeIds();
1770
- const defaults = await this.loadDefaultsForPlanType(selection.safetyPlanTypeId, repeatableSectionTypeIds);
1771
- this.planTypeOverride.set(selection.safetyPlanTypeId);
1772
- this.updateRootContextField('safetyPlanTypeId', selection.safetyPlanTypeId);
1773
- this.updateRootContextField('safetyPlanType', selection.safetyPlanType ?? { id: selection.safetyPlanTypeId });
1774
- this.appliedPlanTypeId.set(selection.safetyPlanTypeId);
1775
- this.lastSyncedKey.set(`|${selection.safetyPlanTypeId}`);
1776
- this.inflightSyncKey.set(null);
1777
- this.applyStructure(defaults, { asBaseline: true });
1778
- this.builderRef()?.syncAfterSave(defaults);
1779
- this.recompute();
1780
- this.toastService.show({
1781
- color: 'success',
1782
- title: await this.translateService.translateAsync('@general:messages.generic.success.title'),
1783
- content: await this.translateService.translateAsync('@workplacesafety-management:safety-plans.actions.change-plan-type.dialog.success'),
1784
- });
1785
- }
1786
1701
  async handleSave(options) {
1787
1702
  const silent = options?.silent === true;
1788
1703
  const id = this.safetyPlanId();
@@ -1803,7 +1718,7 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
1803
1718
  const repeatableSectionTypeIds = await this.loadRepeatableSectionTypeIds();
1804
1719
  const saved = await this.fetchSectionsFromBackend(id, repeatableSectionTypeIds);
1805
1720
  this.applyStructure(saved, { asBaseline: true });
1806
- this.lastSyncedKey.set(`${id}|${this.planTypeId() ?? ''}`);
1721
+ this.lastSyncedKey.set(this.buildSyncKey(id, this.planTypeId(), this.structureId()));
1807
1722
  this.inflightSyncKey.set(null);
1808
1723
  this.builderRef()?.syncAfterSave(saved);
1809
1724
  this.recompute();
@@ -1842,16 +1757,37 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
1842
1757
  if (options.asBaseline) {
1843
1758
  this.baselineValue.set(normalized);
1844
1759
  }
1845
- this.committedValue.set(normalized);
1846
- // Keep both form fields in sync with the same replaced value (never merge/append).
1847
- this.updateRootContextField('sectionStructure', normalized);
1848
- this.updateRootContextField('sections', normalized);
1849
- // Defer host recompute so it cannot re-enter the sync effect synchronously.
1850
- queueMicrotask(() => {
1851
- untracked(() => this.recompute());
1852
- });
1760
+ if (!isEqual(untracked(() => this.committedValue()), normalized)) {
1761
+ this.committedValue.set(normalized);
1762
+ }
1763
+ // Mirror onto the current rootContext object only (no contextStore.update).
1764
+ // Store writes during load re-snapshot rootContext and remount/lazy-reload the page.
1765
+ this.mirrorRootContextField('sectionStructure', normalized);
1766
+ this.mirrorRootContextField('sections', normalized);
1767
+ }
1768
+ buildSyncKey(planId, typeId, structureId) {
1769
+ return `${planId ?? ''}|${typeId ?? ''}|${structureId ?? ''}`;
1770
+ }
1771
+ /** Mutate the current rootContext input object without notifying the context store. */
1772
+ mirrorRootContextField(field, value) {
1773
+ const ctx = this.rootContext();
1774
+ if (!ctx || typeof ctx !== 'object') {
1775
+ return;
1776
+ }
1777
+ ctx[field] = cloneDeep(value);
1778
+ }
1779
+ /**
1780
+ * User edits / explicit plan-type changes: write through AXPContextStore (skips when equal)
1781
+ * and mirror onto the current rootContext input object.
1782
+ */
1783
+ persistContextField(field, value, origin) {
1784
+ this.contextStore.update(field, cloneDeep(value), { origin });
1785
+ this.mirrorRootContextField(field, value);
1786
+ }
1787
+ updateRootContextField(field, value) {
1788
+ // Prefer store writes for explicit field updates (plan type / structure / discard).
1789
+ this.persistContextField(field, value, 'system');
1853
1790
  }
1854
- /** Query plan sections from storage and return a deduped builder value (replace, never append). */
1855
1791
  async fetchSectionsFromBackend(planId, repeatableSectionTypeIds = []) {
1856
1792
  const result = await this.entityService.withEntity(SAFETY_PLAN_SECTION_ENTITY).data().query({
1857
1793
  skip: 0,
@@ -1994,7 +1930,7 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
1994
1930
  return builtIn;
1995
1931
  }
1996
1932
  }
1997
- async loadDefaultsForPlanType(typeId, repeatableSectionTypeIds = []) {
1933
+ async queryTypeSectionsForPlanType(typeId) {
1998
1934
  const result = await this.entityService.withEntity(SAFETY_PLAN_TYPE_SECTION_ENTITY).data().query({
1999
1935
  skip: 0,
2000
1936
  take: 1000,
@@ -2007,8 +1943,15 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
2007
1943
  ],
2008
1944
  },
2009
1945
  });
2010
- const typeSections = (result.items ?? []).filter((row) => resolveEntityRefId(row.safetyPlanTypeId) === typeId);
2011
- const structure = dedupeSafetyPlanSectionStructure(buildSectionStructureFromTypeSections(typeSections, {
1946
+ return (result.items ?? []).filter((row) => resolveEntityRefId(row.safetyPlanTypeId) === typeId);
1947
+ }
1948
+ async loadDefaultsForStructure(typeId, structureId, repeatableSectionTypeIds = []) {
1949
+ if (!typeId) {
1950
+ return { sections: [] };
1951
+ }
1952
+ const typeSections = await this.queryTypeSectionsForPlanType(typeId);
1953
+ const sourceRows = pickSafetyPlanTypeSectionsForStructure(typeSections, structureId);
1954
+ const structure = dedupeSafetyPlanSectionStructure(buildSectionStructureFromTypeSections(sourceRows, {
2012
1955
  createId: () => AXPDataGenerator.uuid(),
2013
1956
  }), { repeatableSectionTypeIds });
2014
1957
  return toBuilderValueFromStructure(await this.enrichSectionTitlesFromSectionTypes(structure));
@@ -2071,13 +2014,6 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
2071
2014
  }),
2072
2015
  };
2073
2016
  }
2074
- async confirmReplaceStructure() {
2075
- const title = (await this.translateService.translateAsync('@workplacesafety-management:safety-plans.messages.section-structure.confirm-change-plan-type.title')) || 'Change Plan Type?';
2076
- const message = (await this.translateService.translateAsync('@workplacesafety-management:safety-plans.messages.section-structure.confirm-change-plan-type.message')) ||
2077
- 'Changing the Plan Type will discard all existing sections and their selected values. The default sections for the new Plan Type will be loaded. Do you want to continue?';
2078
- const dialogResult = await this.dialogService.confirm(title, message, 'danger', 'horizontal');
2079
- return dialogResult.result === true;
2080
- }
2081
2017
  async showStructureLoadError() {
2082
2018
  this.toastService.show({
2083
2019
  color: 'danger',
@@ -2085,13 +2021,6 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
2085
2021
  content: await this.translateService.translateAsync('@workplacesafety-management:safety-plans.messages.section-structure.load-failed'),
2086
2022
  });
2087
2023
  }
2088
- updateRootContextField(field, value) {
2089
- const ctx = this.rootContext();
2090
- if (!ctx || typeof ctx !== 'object') {
2091
- return;
2092
- }
2093
- ctx[field] = cloneDeep(value);
2094
- }
2095
2024
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMSafetyPlanSectionsPageComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2096
2025
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMSafetyPlanSectionsPageComponent, isStandalone: true, selector: "axm-safety-plan-sections-page", inputs: { rootContext: { classPropertyName: "rootContext", publicName: "rootContext", isSignal: true, isRequired: false, transformFunction: null }, pageConfig: { classPropertyName: "pageConfig", publicName: "pageConfig", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "block w-full min-h-0" }, providers: [
2097
2026
  {
@@ -2099,23 +2028,29 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
2099
2028
  useExisting: AXMSafetyPlanSectionsPageComponent,
2100
2029
  },
2101
2030
  ], viewQueries: [{ propertyName: "builderRef", first: true, predicate: ["builderRef"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
2102
- @if (isLoadingStructure()) {
2103
- <p class="text-muted p-4">
2104
- {{
2105
- '@workplacesafety-management:safety-plans.entities.safety-plan.pages.sections.loading'
2106
- | translate
2107
- | async
2108
- }}
2109
- </p>
2110
- } @else if (safetyPlanId() || hasPlanType()) {
2111
- <axm-safety-plan-section-builder
2112
- #builderRef
2113
- [value]="committedValue()"
2114
- [safetyPlanId]="safetyPlanId() ?? undefined"
2115
- [options]="builderOptions()"
2116
- (valueChange)="onValueChange($event)"
2117
- />
2118
- } @else {
2031
+ @if (safetyPlanId() || hasStructure()) {
2032
+ <div class="relative block w-full min-h-0">
2033
+ <!-- ----- Skeleton overlay while structure loads (builder stays mounted) ----- -->
2034
+ @if (showStructureLoading()) {
2035
+ <div class="flex flex-col gap-3 p-4 absolute inset-0 z-10 bg-white/80 dark:bg-black/40">
2036
+ <ax-skeleton [animated]="true" class="h-5 w-2/5 rounded-md"></ax-skeleton>
2037
+ <ax-skeleton [animated]="true" class="h-24 w-full rounded-md"></ax-skeleton>
2038
+ <ax-skeleton [animated]="true" class="h-24 w-full rounded-md"></ax-skeleton>
2039
+ <ax-skeleton [animated]="true" class="h-4 w-3/5 rounded-md"></ax-skeleton>
2040
+ </div>
2041
+ }
2042
+ <!-- ----- Sections builder — mounted once structure is known (or editing an existing plan) ----- -->
2043
+ <axm-safety-plan-section-builder
2044
+ #builderRef
2045
+ [value]="committedValue()"
2046
+ [safetyPlanId]="safetyPlanId() ?? undefined"
2047
+ [options]="builderOptions()"
2048
+ (valueChange)="onValueChange($event)"
2049
+ />
2050
+ </div>
2051
+ }
2052
+ <!-- ----- Prompt to select plan type + structure before sections can load ----- -->
2053
+ @else {
2119
2054
  <p class="text-muted p-4">
2120
2055
  {{
2121
2056
  '@workplacesafety-management:safety-plans.entities.safety-plan.pages.sections.select-plan-type-first'
@@ -2124,32 +2059,38 @@ class AXMSafetyPlanSectionsPageComponent extends AXPPageLayoutBaseComponent {
2124
2059
  }}
2125
2060
  </p>
2126
2061
  }
2127
- `, isInline: true, dependencies: [{ kind: "component", type: AXMSafetyPlanSectionBuilderComponent, selector: "axm-safety-plan-section-builder", inputs: ["value", "safetyPlanId", "options"], outputs: ["valueChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1$1.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2062
+ `, isInline: true, dependencies: [{ kind: "component", type: AXMSafetyPlanSectionBuilderComponent, selector: "axm-safety-plan-section-builder", inputs: ["value", "safetyPlanId", "options"], outputs: ["valueChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i1$1.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "pipe", type: i2$1.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2128
2063
  }
2129
2064
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMSafetyPlanSectionsPageComponent, decorators: [{
2130
2065
  type: Component,
2131
2066
  args: [{
2132
2067
  selector: 'axm-safety-plan-sections-page',
2133
2068
  standalone: true,
2134
- imports: [AXMSafetyPlanSectionBuilderComponent, AXTranslationModule, AsyncPipe],
2069
+ imports: [AXMSafetyPlanSectionBuilderComponent, AXTranslationModule, AsyncPipe, AXSkeletonModule],
2135
2070
  template: `
2136
- @if (isLoadingStructure()) {
2137
- <p class="text-muted p-4">
2138
- {{
2139
- '@workplacesafety-management:safety-plans.entities.safety-plan.pages.sections.loading'
2140
- | translate
2141
- | async
2142
- }}
2143
- </p>
2144
- } @else if (safetyPlanId() || hasPlanType()) {
2145
- <axm-safety-plan-section-builder
2146
- #builderRef
2147
- [value]="committedValue()"
2148
- [safetyPlanId]="safetyPlanId() ?? undefined"
2149
- [options]="builderOptions()"
2150
- (valueChange)="onValueChange($event)"
2151
- />
2152
- } @else {
2071
+ @if (safetyPlanId() || hasStructure()) {
2072
+ <div class="relative block w-full min-h-0">
2073
+ <!-- ----- Skeleton overlay while structure loads (builder stays mounted) ----- -->
2074
+ @if (showStructureLoading()) {
2075
+ <div class="flex flex-col gap-3 p-4 absolute inset-0 z-10 bg-white/80 dark:bg-black/40">
2076
+ <ax-skeleton [animated]="true" class="h-5 w-2/5 rounded-md"></ax-skeleton>
2077
+ <ax-skeleton [animated]="true" class="h-24 w-full rounded-md"></ax-skeleton>
2078
+ <ax-skeleton [animated]="true" class="h-24 w-full rounded-md"></ax-skeleton>
2079
+ <ax-skeleton [animated]="true" class="h-4 w-3/5 rounded-md"></ax-skeleton>
2080
+ </div>
2081
+ }
2082
+ <!-- ----- Sections builder — mounted once structure is known (or editing an existing plan) ----- -->
2083
+ <axm-safety-plan-section-builder
2084
+ #builderRef
2085
+ [value]="committedValue()"
2086
+ [safetyPlanId]="safetyPlanId() ?? undefined"
2087
+ [options]="builderOptions()"
2088
+ (valueChange)="onValueChange($event)"
2089
+ />
2090
+ </div>
2091
+ }
2092
+ <!-- ----- Prompt to select plan type + structure before sections can load ----- -->
2093
+ @else {
2153
2094
  <p class="text-muted p-4">
2154
2095
  {{
2155
2096
  '@workplacesafety-management:safety-plans.entities.safety-plan.pages.sections.select-plan-type-first'
@@ -2196,4 +2137,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2196
2137
  }] });
2197
2138
 
2198
2139
  export { AXMSafetyPlanSectionBuilderComponent, AXMSafetyPlanSectionsPageComponent, AXMSafetyPlanSectionsPageComponentProvider, SAFETY_PLAN_SECTIONS_SAVE_COMMAND };
2199
- //# sourceMappingURL=acorex-platform-module-workplacesafety-management-client-index-LxP1eZLY.mjs.map
2140
+ //# sourceMappingURL=acorex-platform-module-workplacesafety-management-client-index-gbDgxqrV.mjs.map