@plumile/backoffice-react 0.1.108 → 0.1.112

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 (319) hide show
  1. package/lib/esm/auth/AuthRefreshNotice.js +2 -2
  2. package/lib/esm/auth/AuthRefreshNotice.js.map +1 -1
  3. package/lib/esm/auth/authRefreshNotice.css.js +1 -0
  4. package/lib/esm/auth/authRefreshNotice.css.js.map +1 -1
  5. package/lib/esm/auth/login/EmailCapturePanel.js +12 -9
  6. package/lib/esm/auth/login/EmailCapturePanel.js.map +1 -1
  7. package/lib/esm/auth/login/LoginFlow.js +10 -10
  8. package/lib/esm/auth/login/LoginFlow.js.map +1 -1
  9. package/lib/esm/auth/login/MethodChooser.js +14 -12
  10. package/lib/esm/auth/login/MethodChooser.js.map +1 -1
  11. package/lib/esm/auth/login/MfaChallengeForm.js +13 -10
  12. package/lib/esm/auth/login/MfaChallengeForm.js.map +1 -1
  13. package/lib/esm/auth/login/OidcButtons.js +4 -4
  14. package/lib/esm/auth/login/OidcButtons.js.map +1 -1
  15. package/lib/esm/auth/login/PasskeyLoginForm.js +13 -10
  16. package/lib/esm/auth/login/PasskeyLoginForm.js.map +1 -1
  17. package/lib/esm/auth/login/PasswordLoginPanel.js +8 -8
  18. package/lib/esm/auth/login/PasswordLoginPanel.js.map +1 -1
  19. package/lib/esm/auth/login/loginPage.css.js.map +1 -1
  20. package/lib/esm/auth/pages/AcceptInvitationScreen.js +18 -14
  21. package/lib/esm/auth/pages/AcceptInvitationScreen.js.map +1 -1
  22. package/lib/esm/auth/pages/PasswordResetCompleteScreen.js +16 -12
  23. package/lib/esm/auth/pages/PasswordResetCompleteScreen.js.map +1 -1
  24. package/lib/esm/auth/pages/PasswordResetRequestScreen.js +15 -11
  25. package/lib/esm/auth/pages/PasswordResetRequestScreen.js.map +1 -1
  26. package/lib/esm/auth/pages/VerifyEmailScreen.js +13 -11
  27. package/lib/esm/auth/pages/VerifyEmailScreen.js.map +1 -1
  28. package/lib/esm/components/backoffice/actions/BackofficeEntityActionFormDialog.js +66 -54
  29. package/lib/esm/components/backoffice/actions/BackofficeEntityActionFormDialog.js.map +1 -1
  30. package/lib/esm/components/backoffice/actions/LazyBackofficeEntityActionFormDialog.js +8 -8
  31. package/lib/esm/components/backoffice/actions/LazyBackofficeEntityActionFormDialog.js.map +1 -1
  32. package/lib/esm/components/backoffice/actions/backofficeEntityActionFormDialog.css.js.map +1 -1
  33. package/lib/esm/components/backoffice/actions/toastViewAction.js.map +1 -1
  34. package/lib/esm/components/backoffice/columns/buildDataTableColumns.js +13 -12
  35. package/lib/esm/components/backoffice/columns/buildDataTableColumns.js.map +1 -1
  36. package/lib/esm/components/backoffice/detail/BackofficeCopyButton.js +3 -3
  37. package/lib/esm/components/backoffice/detail/BackofficeCopyButton.js.map +1 -1
  38. package/lib/esm/components/backoffice/detail/BackofficeDetailBadgeRow.js +8 -8
  39. package/lib/esm/components/backoffice/detail/BackofficeDetailBadgeRow.js.map +1 -1
  40. package/lib/esm/components/backoffice/detail/BackofficeDetailErrorList.js +12 -11
  41. package/lib/esm/components/backoffice/detail/BackofficeDetailErrorList.js.map +1 -1
  42. package/lib/esm/components/backoffice/detail/BackofficeDetailField.js +8 -7
  43. package/lib/esm/components/backoffice/detail/BackofficeDetailField.js.map +1 -1
  44. package/lib/esm/components/backoffice/detail/BackofficeDetailFlagTag.css.js.map +1 -1
  45. package/lib/esm/components/backoffice/detail/BackofficeDetailFlagTag.js +6 -6
  46. package/lib/esm/components/backoffice/detail/BackofficeDetailFlagTag.js.map +1 -1
  47. package/lib/esm/components/backoffice/detail/BackofficeDetailHeader.js +3 -3
  48. package/lib/esm/components/backoffice/detail/BackofficeDetailHeader.js.map +1 -1
  49. package/lib/esm/components/backoffice/detail/BackofficeDetailPage.js +3 -3
  50. package/lib/esm/components/backoffice/detail/BackofficeDetailPage.js.map +1 -1
  51. package/lib/esm/components/backoffice/detail/BackofficeDetailPayload.js +4 -4
  52. package/lib/esm/components/backoffice/detail/BackofficeDetailPayload.js.map +1 -1
  53. package/lib/esm/components/backoffice/detail/BackofficeDetailRelationLink.js +1 -1
  54. package/lib/esm/components/backoffice/detail/BackofficeDetailRelationLink.js.map +1 -1
  55. package/lib/esm/components/backoffice/detail/BackofficeDetailRelationListBlock.js +30 -29
  56. package/lib/esm/components/backoffice/detail/BackofficeDetailRelationListBlock.js.map +1 -1
  57. package/lib/esm/components/backoffice/detail/BackofficeDetailTable.js +3 -3
  58. package/lib/esm/components/backoffice/detail/BackofficeDetailTable.js.map +1 -1
  59. package/lib/esm/components/backoffice/detail/BackofficeDetailTaggedValue.js +5 -5
  60. package/lib/esm/components/backoffice/detail/BackofficeDetailTaggedValue.js.map +1 -1
  61. package/lib/esm/components/backoffice/detail/BackofficeEntitySummaryHeader.js +21 -19
  62. package/lib/esm/components/backoffice/detail/BackofficeEntitySummaryHeader.js.map +1 -1
  63. package/lib/esm/components/backoffice/detail/BackofficeKpiStrip.js +9 -6
  64. package/lib/esm/components/backoffice/detail/BackofficeKpiStrip.js.map +1 -1
  65. package/lib/esm/components/backoffice/detail/BackofficeLifecycleTimelineSection.js +7 -7
  66. package/lib/esm/components/backoffice/detail/BackofficeLifecycleTimelineSection.js.map +1 -1
  67. package/lib/esm/components/backoffice/detail/BackofficePayloadInspectorSection.js +8 -8
  68. package/lib/esm/components/backoffice/detail/BackofficePayloadInspectorSection.js.map +1 -1
  69. package/lib/esm/components/backoffice/detail/BackofficeReferenceValue.js +5 -5
  70. package/lib/esm/components/backoffice/detail/BackofficeReferenceValue.js.map +1 -1
  71. package/lib/esm/components/backoffice/detail/BackofficeRelationsSummaryGrid.js +1 -1
  72. package/lib/esm/components/backoffice/detail/BackofficeRelationsSummaryGrid.js.map +1 -1
  73. package/lib/esm/components/backoffice/detail/BackofficeStatusMetaBadge.js +4 -4
  74. package/lib/esm/components/backoffice/detail/BackofficeStatusMetaBadge.js.map +1 -1
  75. package/lib/esm/components/backoffice/detail/BackofficeUsageCostBreakdown.js +1 -1
  76. package/lib/esm/components/backoffice/detail/BackofficeUsageCostBreakdown.js.map +1 -1
  77. package/lib/esm/components/backoffice/detail/backofficeAuditMetadataPanel.css.js.map +1 -1
  78. package/lib/esm/components/backoffice/detail/backofficeDetailBadgeRow.css.js.map +1 -1
  79. package/lib/esm/components/backoffice/detail/backofficeDetailErrorList.css.js.map +1 -1
  80. package/lib/esm/components/backoffice/detail/backofficeDetailField.css.js.map +1 -1
  81. package/lib/esm/components/backoffice/detail/backofficeDetailLayout.css.js.map +1 -1
  82. package/lib/esm/components/backoffice/detail/backofficeDetailRelationLink.css.js.map +1 -1
  83. package/lib/esm/components/backoffice/detail/backofficeDetailRelationList.css.js.map +1 -1
  84. package/lib/esm/components/backoffice/detail/backofficeDetailSection.css.js.map +1 -1
  85. package/lib/esm/components/backoffice/detail/backofficeDetailTaggedValue.css.js.map +1 -1
  86. package/lib/esm/components/backoffice/detail/backofficeEntitySummaryHeader.css.js.map +1 -1
  87. package/lib/esm/components/backoffice/detail/backofficeKpiStrip.css.js.map +1 -1
  88. package/lib/esm/components/backoffice/detail/backofficeLifecycleTimelineSection.css.js.map +1 -1
  89. package/lib/esm/components/backoffice/detail/backofficePayloadInspectorSection.css.js.map +1 -1
  90. package/lib/esm/components/backoffice/detail/backofficeReferenceValue.css.js.map +1 -1
  91. package/lib/esm/components/backoffice/detail/backofficeRelationsSummaryGrid.css.js.map +1 -1
  92. package/lib/esm/components/backoffice/detail/backofficeScopeStack.css.js.map +1 -1
  93. package/lib/esm/components/backoffice/detail/backofficeStatusMetaBadge.css.js.map +1 -1
  94. package/lib/esm/components/backoffice/detail/backofficeUsageCostBreakdown.css.js.map +1 -1
  95. package/lib/esm/components/backoffice/filters/BackofficeFilterAction.js +12 -12
  96. package/lib/esm/components/backoffice/filters/BackofficeFilterAction.js.map +1 -1
  97. package/lib/esm/components/backoffice/filters/DeferredFilterSearchInput.js +11 -9
  98. package/lib/esm/components/backoffice/filters/DeferredFilterSearchInput.js.map +1 -1
  99. package/lib/esm/components/backoffice/filters/EntityFilterValue.js +16 -8
  100. package/lib/esm/components/backoffice/filters/EntityFilterValue.js.map +1 -1
  101. package/lib/esm/components/backoffice/filters/EntityIdFilterField.js +86 -53
  102. package/lib/esm/components/backoffice/filters/EntityIdFilterField.js.map +1 -1
  103. package/lib/esm/components/backoffice/filters/backofficeFilterAction.css.js.map +1 -1
  104. package/lib/esm/components/backoffice/filters/deferredFilterSearchInput.css.js.map +1 -1
  105. package/lib/esm/components/backoffice/filters/entityIdFilterField.css.js +2 -2
  106. package/lib/esm/components/backoffice/filters/entityIdFilterField.css.js.map +1 -1
  107. package/lib/esm/components/backoffice/hub/BackofficeHubTemplate.js +25 -23
  108. package/lib/esm/components/backoffice/hub/BackofficeHubTemplate.js.map +1 -1
  109. package/lib/esm/components/backoffice/hub/backofficeHubTemplate.css.js.map +1 -1
  110. package/lib/esm/components/backoffice/layout/backofficeSidebarActions.css.js.map +1 -1
  111. package/lib/esm/components/backoffice/layout/breadcrumb/BackofficeTopbarBreadcrumb.js +14 -14
  112. package/lib/esm/components/backoffice/layout/breadcrumb/BackofficeTopbarBreadcrumb.js.map +1 -1
  113. package/lib/esm/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.js.map +1 -1
  114. package/lib/esm/components/backoffice/layout/buildSidebarSections.js +42 -37
  115. package/lib/esm/components/backoffice/layout/buildSidebarSections.js.map +1 -1
  116. package/lib/esm/components/backoffice/layout/mapViewerToSidebarProfileView.js.map +1 -1
  117. package/lib/esm/components/backoffice/links/BackofficeInlineLink.js +1 -1
  118. package/lib/esm/components/backoffice/links/BackofficeInlineLink.js.map +1 -1
  119. package/lib/esm/components/backoffice/links/BackofficeLink.js +1 -1
  120. package/lib/esm/components/backoffice/links/BackofficeLink.js.map +1 -1
  121. package/lib/esm/components/backoffice/links/backofficeLink.css.js.map +1 -1
  122. package/lib/esm/components/backoffice/lists/BackofficeListToolbar.js +1 -1
  123. package/lib/esm/components/backoffice/lists/BackofficeListToolbar.js.map +1 -1
  124. package/lib/esm/components/backoffice/lists/backofficeListToolbar.css.js.map +1 -1
  125. package/lib/esm/components/backoffice/overview/BackofficeOverviewLayout.js +1 -1
  126. package/lib/esm/components/backoffice/overview/BackofficeOverviewLayout.js.map +1 -1
  127. package/lib/esm/components/backoffice/overview/backofficeOverviewLayout.css.js.map +1 -1
  128. package/lib/esm/components/backoffice/pickers/EntityIdPickerDialog.js +31 -27
  129. package/lib/esm/components/backoffice/pickers/EntityIdPickerDialog.js.map +1 -1
  130. package/lib/esm/components/backoffice/pickers/entityIdPickerDialog.css.js +2 -2
  131. package/lib/esm/components/backoffice/pickers/entityIdPickerDialog.css.js.map +1 -1
  132. package/lib/esm/components/backoffice/pickers/shared/EntityPickerList.js +26 -20
  133. package/lib/esm/components/backoffice/pickers/shared/EntityPickerList.js.map +1 -1
  134. package/lib/esm/components/backoffice/pickers/shared/EntityPickerShell.js +4 -4
  135. package/lib/esm/components/backoffice/pickers/shared/EntityPickerShell.js.map +1 -1
  136. package/lib/esm/components/backoffice/refs/BackofficeRelatedCountLink.js +1 -1
  137. package/lib/esm/components/backoffice/refs/BackofficeRelatedCountLink.js.map +1 -1
  138. package/lib/esm/components/backoffice/refs/backofficeEntityIdRef.css.js.map +1 -1
  139. package/lib/esm/components/backoffice/refs/backofficeRelatedCountLink.css.js.map +1 -1
  140. package/lib/esm/components/backoffice/routing/BackofficeContentError.js +6 -5
  141. package/lib/esm/components/backoffice/routing/BackofficeContentError.js.map +1 -1
  142. package/lib/esm/components/backoffice/routing/BackofficeContentFallback.js +10 -10
  143. package/lib/esm/components/backoffice/routing/BackofficeContentFallback.js.map +1 -1
  144. package/lib/esm/components/backoffice/routing/BackofficeRouteFallback.js +10 -10
  145. package/lib/esm/components/backoffice/routing/BackofficeRouteFallback.js.map +1 -1
  146. package/lib/esm/components/backoffice/routing/backofficeContentBoundary.css.js.map +1 -1
  147. package/lib/esm/components/backoffice/routing/backofficeContentError.css.js.map +1 -1
  148. package/lib/esm/components/backoffice/routing/backofficeContentFallback.css.js.map +1 -1
  149. package/lib/esm/components/backoffice/routing/backofficeRouteFallback.css.js.map +1 -1
  150. package/lib/esm/components/backoffice/routing/backofficeRoutePendingBar.css.js.map +1 -1
  151. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityDetailScaffold.js +3 -3
  152. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityDetailScaffold.js.map +1 -1
  153. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js +198 -181
  154. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js.map +1 -1
  155. package/lib/esm/components/backoffice/scaffolds/BackofficeTabbedDetailShell.js +6 -5
  156. package/lib/esm/components/backoffice/scaffolds/BackofficeTabbedDetailShell.js.map +1 -1
  157. package/lib/esm/components/backoffice/scaffolds/backofficeEntityListScaffold.css.js.map +1 -1
  158. package/lib/esm/components/backoffice/scaffolds/backofficeTabbedDetailShell.css.js.map +1 -1
  159. package/lib/esm/components/backoffice/shared/BackofficeFilterableCell.js +10 -9
  160. package/lib/esm/components/backoffice/shared/BackofficeFilterableCell.js.map +1 -1
  161. package/lib/esm/components/backoffice/shared/BackofficeInlineFilterRow.js +1 -1
  162. package/lib/esm/components/backoffice/shared/BackofficeInlineFilterRow.js.map +1 -1
  163. package/lib/esm/components/backoffice/shared/backofficeFilterableCell.css.js.map +1 -1
  164. package/lib/esm/components/backoffice/shared/backofficeInlineFilterRow.css.js.map +1 -1
  165. package/lib/esm/components/backoffice/tools/BackofficeToolsDocPanel.js +11 -9
  166. package/lib/esm/components/backoffice/tools/BackofficeToolsDocPanel.js.map +1 -1
  167. package/lib/esm/components/backoffice/tools/BackofficeToolsErrorFallback.js +7 -7
  168. package/lib/esm/components/backoffice/tools/BackofficeToolsErrorFallback.js.map +1 -1
  169. package/lib/esm/components/backoffice/tools/BackofficeToolsJsonForm.js +17 -12
  170. package/lib/esm/components/backoffice/tools/BackofficeToolsJsonForm.js.map +1 -1
  171. package/lib/esm/components/backoffice/tools/BackofficeToolsQueryBoundary.js +10 -10
  172. package/lib/esm/components/backoffice/tools/BackofficeToolsQueryBoundary.js.map +1 -1
  173. package/lib/esm/components/backoffice/tools/backofficeToolsDocPanel.css.js.map +1 -1
  174. package/lib/esm/components/backoffice/tools/backofficeToolsForm.css.js.map +1 -1
  175. package/lib/esm/components/backoffice/tools/backofficeToolsJsonForm.css.js.map +1 -1
  176. package/lib/esm/hooks/useBackofficeListUrlState.js +2 -1
  177. package/lib/esm/hooks/useBackofficeListUrlState.js.map +1 -1
  178. package/lib/esm/pages/BackofficeAcceptInvitationPage.js +1 -1
  179. package/lib/esm/pages/BackofficeAcceptInvitationPage.js.map +1 -1
  180. package/lib/esm/pages/BackofficeDashboardPage.js +72 -68
  181. package/lib/esm/pages/BackofficeDashboardPage.js.map +1 -1
  182. package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js +1 -1
  183. package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js.map +1 -1
  184. package/lib/esm/pages/BackofficeEntityDetailPage.js +207 -184
  185. package/lib/esm/pages/BackofficeEntityDetailPage.js.map +1 -1
  186. package/lib/esm/pages/BackofficeEntityDetailUnknownPageRedirect.js +1 -1
  187. package/lib/esm/pages/BackofficeEntityDetailUnknownPageRedirect.js.map +1 -1
  188. package/lib/esm/pages/BackofficeEntityListPage.helpers.js.map +1 -1
  189. package/lib/esm/pages/BackofficeEntityListPage.js +143 -139
  190. package/lib/esm/pages/BackofficeEntityListPage.js.map +1 -1
  191. package/lib/esm/pages/BackofficeHubPage.js +10 -9
  192. package/lib/esm/pages/BackofficeHubPage.js.map +1 -1
  193. package/lib/esm/pages/BackofficeLayoutPage.js +44 -39
  194. package/lib/esm/pages/BackofficeLayoutPage.js.map +1 -1
  195. package/lib/esm/pages/BackofficeLoginPage.js +1 -1
  196. package/lib/esm/pages/BackofficeLoginPage.js.map +1 -1
  197. package/lib/esm/pages/BackofficePasswordResetCompletePage.js +1 -1
  198. package/lib/esm/pages/BackofficePasswordResetCompletePage.js.map +1 -1
  199. package/lib/esm/pages/BackofficeVerifyEmailPage.js +1 -1
  200. package/lib/esm/pages/BackofficeVerifyEmailPage.js.map +1 -1
  201. package/lib/esm/pages/backofficeDashboardPage.css.js.map +1 -1
  202. package/lib/esm/pages/backofficeEntityDetailPage.css.js.map +1 -1
  203. package/lib/esm/pages/backofficeEntityListPage.css.js.map +1 -1
  204. package/lib/esm/pages/dashboard/DashboardMetricGroup.js +10 -9
  205. package/lib/esm/pages/dashboard/DashboardMetricGroup.js.map +1 -1
  206. package/lib/esm/pages/dashboard/DashboardPanel.js +3 -3
  207. package/lib/esm/pages/dashboard/DashboardPanel.js.map +1 -1
  208. package/lib/esm/pages/dashboard/DashboardQuickActions.js +2 -2
  209. package/lib/esm/pages/dashboard/DashboardQuickActions.js.map +1 -1
  210. package/lib/esm/pages/dashboard/DashboardStatusList.js +1 -1
  211. package/lib/esm/pages/dashboard/DashboardStatusList.js.map +1 -1
  212. package/lib/esm/pages/dashboard/dashboardMetricGroup.css.js.map +1 -1
  213. package/lib/esm/pages/dashboard/dashboardPanel.css.js.map +1 -1
  214. package/lib/esm/pages/dashboard/dashboardQuickActions.css.js.map +1 -1
  215. package/lib/esm/pages/dashboard/dashboardStatusList.css.js.map +1 -1
  216. package/lib/esm/pages/detail/buildTabsItems.js.map +1 -1
  217. package/lib/esm/provider/BackofficeProvider.js +22 -20
  218. package/lib/esm/provider/BackofficeProvider.js.map +1 -1
  219. package/lib/esm/router/createBackofficeRoutes.js +33 -30
  220. package/lib/esm/router/createBackofficeRoutes.js.map +1 -1
  221. package/lib/esm/storybook/relay/RelayStory.css.js.map +1 -1
  222. package/lib/esm/style.css +1 -1
  223. package/lib/types/auth/AuthFlows.stories.d.ts +19 -0
  224. package/lib/types/auth/AuthFlows.stories.d.ts.map +1 -0
  225. package/lib/types/auth/AuthRefreshNotice.d.ts +1 -1
  226. package/lib/types/auth/AuthRefreshNotice.d.ts.map +1 -1
  227. package/lib/types/auth/authRefreshNotice.css.d.ts.map +1 -1
  228. package/lib/types/auth/login/EmailCapturePanel.d.ts.map +1 -1
  229. package/lib/types/auth/login/MethodChooser.d.ts.map +1 -1
  230. package/lib/types/auth/login/MfaChallengeForm.d.ts.map +1 -1
  231. package/lib/types/auth/login/PasskeyLoginForm.d.ts.map +1 -1
  232. package/lib/types/auth/login/PasswordLoginPanel.d.ts +1 -1
  233. package/lib/types/auth/login/PasswordLoginPanel.d.ts.map +1 -1
  234. package/lib/types/auth/login/loginPage.css.d.ts.map +1 -1
  235. package/lib/types/auth/pages/AcceptInvitationScreen.d.ts.map +1 -1
  236. package/lib/types/auth/pages/PasswordResetCompleteScreen.d.ts.map +1 -1
  237. package/lib/types/auth/pages/PasswordResetRequestScreen.d.ts.map +1 -1
  238. package/lib/types/auth/pages/VerifyEmailScreen.d.ts.map +1 -1
  239. package/lib/types/components/backoffice/actions/BackofficeEntityActionFormDialog.d.ts.map +1 -1
  240. package/lib/types/components/backoffice/actions/toastViewAction.d.ts +1 -1
  241. package/lib/types/components/backoffice/actions/toastViewAction.d.ts.map +1 -1
  242. package/lib/types/components/backoffice/columns/buildDataTableColumns.d.ts +1 -1
  243. package/lib/types/components/backoffice/columns/buildDataTableColumns.d.ts.map +1 -1
  244. package/lib/types/components/backoffice/detail/BackofficeCopyButton.d.ts +1 -1
  245. package/lib/types/components/backoffice/detail/BackofficeCopyButton.d.ts.map +1 -1
  246. package/lib/types/components/backoffice/detail/BackofficeDetailErrorList.d.ts.map +1 -1
  247. package/lib/types/components/backoffice/detail/BackofficeDetailField.d.ts.map +1 -1
  248. package/lib/types/components/backoffice/detail/BackofficeDetailFlagTag.d.ts +1 -1
  249. package/lib/types/components/backoffice/detail/BackofficeDetailFlagTag.d.ts.map +1 -1
  250. package/lib/types/components/backoffice/detail/BackofficeDetailPrimitives.stories.d.ts +17 -0
  251. package/lib/types/components/backoffice/detail/BackofficeDetailPrimitives.stories.d.ts.map +1 -0
  252. package/lib/types/components/backoffice/detail/BackofficeDetailRelationListBlock.d.ts.map +1 -1
  253. package/lib/types/components/backoffice/detail/BackofficeDetailTable.d.ts +1 -1
  254. package/lib/types/components/backoffice/detail/BackofficeDetailTable.d.ts.map +1 -1
  255. package/lib/types/components/backoffice/detail/BackofficeEntitySummaryHeader.d.ts.map +1 -1
  256. package/lib/types/components/backoffice/detail/BackofficeKpiStrip.d.ts.map +1 -1
  257. package/lib/types/components/backoffice/detail/backofficeDetailRelationLink.css.d.ts.map +1 -1
  258. package/lib/types/components/backoffice/filters/DeferredFilterSearchInput.d.ts.map +1 -1
  259. package/lib/types/components/backoffice/filters/EntityFilterValue.d.ts +5 -1
  260. package/lib/types/components/backoffice/filters/EntityFilterValue.d.ts.map +1 -1
  261. package/lib/types/components/backoffice/filters/EntityIdFilterField.d.ts +1 -0
  262. package/lib/types/components/backoffice/filters/EntityIdFilterField.d.ts.map +1 -1
  263. package/lib/types/components/backoffice/filters/backofficeFilterAction.css.d.ts.map +1 -1
  264. package/lib/types/components/backoffice/filters/entityIdFilterField.css.d.ts +5 -2
  265. package/lib/types/components/backoffice/filters/entityIdFilterField.css.d.ts.map +1 -1
  266. package/lib/types/components/backoffice/hub/BackofficeHubTemplate.d.ts.map +1 -1
  267. package/lib/types/components/backoffice/hub/BackofficeHubTemplate.stories.d.ts +48 -0
  268. package/lib/types/components/backoffice/hub/BackofficeHubTemplate.stories.d.ts.map +1 -0
  269. package/lib/types/components/backoffice/hub/backofficeHubTemplate.css.d.ts.map +1 -1
  270. package/lib/types/components/backoffice/layout/backofficeSidebarActions.css.d.ts.map +1 -1
  271. package/lib/types/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.d.ts.map +1 -1
  272. package/lib/types/components/backoffice/layout/buildSidebarSections.d.ts +1 -1
  273. package/lib/types/components/backoffice/layout/buildSidebarSections.d.ts.map +1 -1
  274. package/lib/types/components/backoffice/layout/mapViewerToSidebarProfileView.d.ts +1 -1
  275. package/lib/types/components/backoffice/layout/mapViewerToSidebarProfileView.d.ts.map +1 -1
  276. package/lib/types/components/backoffice/lists/BackofficeListToolbar.stories.d.ts +13 -0
  277. package/lib/types/components/backoffice/lists/BackofficeListToolbar.stories.d.ts.map +1 -0
  278. package/lib/types/components/backoffice/overview/BackofficeOverviewLayout.stories.d.ts.map +1 -1
  279. package/lib/types/components/backoffice/pickers/EntityIdPickerDialog.d.ts.map +1 -1
  280. package/lib/types/components/backoffice/pickers/EntityIdPickerDialog.stories.d.ts +11 -0
  281. package/lib/types/components/backoffice/pickers/EntityIdPickerDialog.stories.d.ts.map +1 -0
  282. package/lib/types/components/backoffice/pickers/entityIdPickerDialog.css.d.ts +2 -0
  283. package/lib/types/components/backoffice/pickers/entityIdPickerDialog.css.d.ts.map +1 -1
  284. package/lib/types/components/backoffice/pickers/shared/EntityPickerList.d.ts.map +1 -1
  285. package/lib/types/components/backoffice/refs/backofficeRelatedCountLink.css.d.ts.map +1 -1
  286. package/lib/types/components/backoffice/routing/BackofficeContentError.d.ts.map +1 -1
  287. package/lib/types/components/backoffice/routing/backofficeRoutePendingBar.css.d.ts.map +1 -1
  288. package/lib/types/components/backoffice/scaffolds/BackofficeEntityListScaffold.d.ts +1 -1
  289. package/lib/types/components/backoffice/scaffolds/BackofficeEntityListScaffold.d.ts.map +1 -1
  290. package/lib/types/components/backoffice/scaffolds/BackofficeTabbedDetailShell.d.ts +1 -1
  291. package/lib/types/components/backoffice/scaffolds/BackofficeTabbedDetailShell.d.ts.map +1 -1
  292. package/lib/types/components/backoffice/scaffolds/BackofficeTabbedDetailShell.stories.d.ts.map +1 -1
  293. package/lib/types/components/backoffice/shared/BackofficeFilterableCell.d.ts.map +1 -1
  294. package/lib/types/components/backoffice/shared/backofficeFilterableCell.css.d.ts.map +1 -1
  295. package/lib/types/components/backoffice/tools/BackofficeTools.stories.d.ts +17 -0
  296. package/lib/types/components/backoffice/tools/BackofficeTools.stories.d.ts.map +1 -0
  297. package/lib/types/components/backoffice/tools/BackofficeToolsDocPanel.d.ts.map +1 -1
  298. package/lib/types/components/backoffice/tools/BackofficeToolsJsonForm.d.ts.map +1 -1
  299. package/lib/types/components/backoffice/tools/backofficeToolsDocPanel.css.d.ts.map +1 -1
  300. package/lib/types/hooks/useBackofficeListUrlState.d.ts.map +1 -1
  301. package/lib/types/pages/BackofficeEntityDetailPage.d.ts.map +1 -1
  302. package/lib/types/pages/BackofficeEntityListPage.helpers.d.ts +2 -1
  303. package/lib/types/pages/BackofficeEntityListPage.helpers.d.ts.map +1 -1
  304. package/lib/types/pages/BackofficeHubPage.d.ts.map +1 -1
  305. package/lib/types/pages/BackofficeLayoutPage.d.ts.map +1 -1
  306. package/lib/types/pages/backofficeEntityDetailPage.css.d.ts.map +1 -1
  307. package/lib/types/pages/dashboard/DashboardMetricGroup.d.ts.map +1 -1
  308. package/lib/types/pages/dashboard/dashboardMetricGroup.css.d.ts.map +1 -1
  309. package/lib/types/pages/dashboard/dashboardPanel.css.d.ts.map +1 -1
  310. package/lib/types/pages/dashboard/dashboardQuickActions.css.d.ts.map +1 -1
  311. package/lib/types/pages/dashboard/dashboardStatusList.css.d.ts.map +1 -1
  312. package/lib/types/pages/detail/buildTabsItems.d.ts +1 -1
  313. package/lib/types/pages/detail/buildTabsItems.d.ts.map +1 -1
  314. package/lib/types/provider/BackofficeProvider.d.ts.map +1 -1
  315. package/lib/types/provider/types.d.ts +2 -1
  316. package/lib/types/provider/types.d.ts.map +1 -1
  317. package/lib/types/router/createBackofficeRoutes.d.ts +2 -1
  318. package/lib/types/router/createBackofficeRoutes.d.ts.map +1 -1
  319. package/package.json +14 -10
@@ -6,12 +6,13 @@ import { useBackofficePermissions as i } from "../components/backoffice/layout/B
6
6
  import { BackofficeRightPageLayout as a } from "../components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js";
7
7
  import { buildHubBreadcrumb as o } from "../components/backoffice/layout/breadcrumb/buildBreadcrumbs.js";
8
8
  import { useMemo as s, useState as c } from "react";
9
- import { DetailPageTemplate as l, SidebarTasksSvg as u } from "@plumile/ui";
10
- import { jsx as d } from "react/jsx-runtime";
11
- import { useTranslation as f } from "react-i18next";
9
+ import { jsx as l } from "react/jsx-runtime";
10
+ import { useTranslation as u } from "react-i18next";
11
+ import { DetailPageTemplate as d } from "@plumile/ui/backoffice/templates/detail_page_template/DetailPageTemplate.js";
12
+ import { SidebarTasksSvg as f } from "@plumile/ui/icons/SidebarTasksSvg.js";
12
13
  //#region src/pages/BackofficeHubPage.tsx
13
14
  var p = (e, t) => {
14
- if (e != null) return /* @__PURE__ */ d(e, {
15
+ if (e != null) return /* @__PURE__ */ l(e, {
15
16
  width: t,
16
17
  height: t,
17
18
  "aria-hidden": "true"
@@ -23,7 +24,7 @@ var p = (e, t) => {
23
24
  id: t.id
24
25
  }, r) !== !1;
25
26
  }, h = ({ prepared: h }) => {
26
- let { t: g } = f(), { t: _ } = e(), { entities: v, sidebar: y } = t(), b = i(), [x, S] = c(""), { hub: C } = h, w = n(C.title, g), T;
27
+ let { t: g } = u(), { t: _ } = e(), { entities: v, sidebar: y } = t(), b = i(), [x, S] = c(""), { hub: C } = h, w = n(C.title, g), T;
27
28
  C.description != null && (T = n(C.description, g));
28
29
  let E = o({
29
30
  id: C.id,
@@ -93,20 +94,20 @@ var p = (e, t) => {
93
94
  value: x,
94
95
  onChange: S,
95
96
  placeholder: k
96
- }), /* @__PURE__ */ d(a, {
97
+ }), /* @__PURE__ */ l(a, {
97
98
  breadcrumb: E,
98
- children: /* @__PURE__ */ d(l, {
99
+ children: /* @__PURE__ */ l(d, {
99
100
  header: {
100
101
  title: w,
101
102
  subtitle: N
102
103
  },
103
- children: /* @__PURE__ */ d(r, {
104
+ children: /* @__PURE__ */ l(r, {
104
105
  groups: F,
105
106
  search: I,
106
107
  emptyState: {
107
108
  title: j,
108
109
  description: M,
109
- icon: /* @__PURE__ */ d(u, {
110
+ icon: /* @__PURE__ */ l(f, {
110
111
  width: 28,
111
112
  height: 28,
112
113
  "aria-hidden": "true"
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeHubPage.js","names":[],"sources":["../../../src/pages/BackofficeHubPage.tsx"],"sourcesContent":["import { useMemo, useState, type JSX, type ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { DetailPageTemplate, SidebarTasksSvg } from '@plumile/ui';\nimport type { BackofficeEntityManifestMap } from '@plumile/backoffice-core/types.js';\n\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport type { BackofficeIconComponent } from '../provider/types.js';\nimport type { BackofficePreparedHubRoute } from '../router/createBackofficeRoutes.js';\nimport {\n BackofficeHubTemplate,\n type BackofficeHubTemplateGroup,\n type BackofficeHubTemplateSearch,\n} from '../components/backoffice/hub/BackofficeHubTemplate.js';\nimport { BackofficeRightPageLayout } from '../components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js';\nimport { buildHubBreadcrumb } from '../components/backoffice/layout/breadcrumb/buildBreadcrumbs.js';\nimport { useBackofficePermissions } from '../components/backoffice/layout/BackofficePermissionsContext.js';\nimport { resolveLabel } from '../components/backoffice/layout/sidebarUtils.js';\n\nexport type BackofficeHubPageProps = {\n prepared: BackofficePreparedHubRoute;\n};\n\ntype HubPageItemView = {\n id: string;\n kind: 'entity' | 'tool';\n label: string;\n href: string;\n icon: ReactNode;\n};\n\ntype HubPageGroupView = {\n id: string;\n title: string;\n description: string | null;\n icon: ReactNode | undefined;\n items: readonly HubPageItemView[];\n};\n\nconst renderIcon = (\n Icon: BackofficeIconComponent | undefined,\n size: number,\n): ReactNode | undefined => {\n if (Icon == null) {\n return undefined;\n }\n return <Icon width={size} height={size} aria-hidden=\"true\" />;\n};\n\nconst isItemVisible = (input: {\n entity: BackofficeEntityManifestMap[string] | null | undefined;\n kind: 'entity' | 'tool';\n permissions: unknown;\n sidebar: ReturnType<typeof useBackofficeConfig>['sidebar'];\n}): boolean => {\n const { entity, kind, permissions, sidebar } = input;\n if (entity == null) {\n return false;\n }\n if (kind === 'entity' && entity.kind !== 'tool' && !entity.hasList) {\n return false;\n }\n const isVisible = sidebar?.isItemVisible?.(\n {\n kind,\n id: entity.id,\n },\n permissions,\n );\n return isVisible !== false;\n};\n\nexport const BackofficeHubPage = ({\n prepared,\n}: BackofficeHubPageProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { entities, sidebar } = useBackofficeConfig();\n const permissions = useBackofficePermissions();\n const [search, setSearch] = useState('');\n const { hub } = prepared;\n const title = resolveLabel(hub.title, tApp);\n let description: string | undefined;\n if (hub.description != null) {\n description = resolveLabel(hub.description, tApp);\n }\n const breadcrumb = buildHubBreadcrumb({ id: hub.id, title });\n const normalizedSearch = search.trim().toLowerCase();\n const searchEnabled = hub.search?.enabled !== false;\n let searchPlaceholder = t('hub.search.placeholder');\n if (hub.search?.placeholder != null) {\n searchPlaceholder = resolveLabel(hub.search.placeholder, tApp);\n }\n\n const groups = useMemo<readonly HubPageGroupView[]>(() => {\n return hub.groups\n .map((group) => {\n const items = group.items\n .map((item): HubPageItemView | null => {\n const entity = entities[item.id];\n if (entity == null) {\n return null;\n }\n if (\n !isItemVisible({\n entity,\n kind: item.kind,\n permissions,\n sidebar,\n })\n ) {\n return null;\n }\n const entityConfig = entity;\n const label = resolveLabel(entityConfig.label, tApp);\n if (\n normalizedSearch !== '' &&\n !label.toLowerCase().includes(normalizedSearch)\n ) {\n return null;\n }\n return {\n id: item.id,\n kind: item.kind,\n label,\n href: entityConfig.routes.list,\n icon: renderIcon(item.icon, 20),\n };\n })\n .filter((item): item is HubPageItemView => {\n return item != null;\n });\n let groupDescription: string | null = null;\n if (group.description != null) {\n groupDescription = resolveLabel(group.description, tApp);\n }\n return {\n id: group.id,\n title: resolveLabel(group.title, tApp),\n description: groupDescription,\n icon: renderIcon(group.icon, 18),\n items,\n };\n })\n .filter((group) => {\n return group.items.length > 0;\n });\n }, [entities, hub.groups, normalizedSearch, permissions, sidebar, tApp]);\n\n let emptyTitle = t('hub.empty.title');\n if (hub.emptyState?.title != null) {\n emptyTitle = resolveLabel(hub.emptyState.title, tApp);\n }\n let emptyDescription = t('hub.empty.description');\n if (hub.emptyState?.description != null) {\n emptyDescription = resolveLabel(hub.emptyState.description, tApp);\n }\n let subtitle = t('hub.subtitle');\n if (description != null) {\n subtitle = description;\n }\n const hasMixedKinds = groups.some((group) => {\n const kinds = new Set(\n group.items.map((item) => {\n return item.kind;\n }),\n );\n return kinds.size > 1;\n });\n\n const templateGroups = useMemo<readonly BackofficeHubTemplateGroup[]>(() => {\n return groups.map((group) => {\n return {\n id: group.id,\n title: group.title,\n description: group.description,\n icon: group.icon,\n items: group.items.map((item) => {\n let metaLabel: string | null = null;\n if (hasMixedKinds) {\n metaLabel = t('hub.itemKinds.entity');\n if (item.kind === 'tool') {\n metaLabel = t('hub.itemKinds.tool');\n }\n }\n return {\n id: item.id,\n kind: item.kind,\n label: item.label,\n href: item.href,\n icon: item.icon,\n metaLabel,\n };\n }),\n };\n });\n }, [groups, hasMixedKinds, t]);\n\n let searchConfig: BackofficeHubTemplateSearch | undefined;\n if (searchEnabled) {\n searchConfig = {\n value: search,\n onChange: setSearch,\n placeholder: searchPlaceholder,\n };\n }\n\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <DetailPageTemplate\n header={{\n title,\n subtitle,\n }}\n >\n <BackofficeHubTemplate\n groups={templateGroups}\n search={searchConfig}\n emptyState={{\n title: emptyTitle,\n description: emptyDescription,\n icon: <SidebarTasksSvg width={28} height={28} aria-hidden=\"true\" />,\n }}\n />\n </DetailPageTemplate>\n </BackofficeRightPageLayout>\n );\n};\n\nexport default BackofficeHubPage;\n"],"mappings":"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"}
1
+ {"version":3,"file":"BackofficeHubPage.js","names":[],"sources":["../../../src/pages/BackofficeHubPage.tsx"],"sourcesContent":["import { useMemo, useState, type JSX, type ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { DetailPageTemplate } from '@plumile/ui/backoffice/templates/detail_page_template/DetailPageTemplate.js';\nimport { SidebarTasksSvg } from '@plumile/ui/icons/SidebarTasksSvg.js';\nimport type { BackofficeEntityManifestMap } from '@plumile/backoffice-core/types.js';\n\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport type { BackofficeIconComponent } from '../provider/types.js';\nimport type { BackofficePreparedHubRoute } from '../router/createBackofficeRoutes.js';\nimport {\n BackofficeHubTemplate,\n type BackofficeHubTemplateGroup,\n type BackofficeHubTemplateSearch,\n} from '../components/backoffice/hub/BackofficeHubTemplate.js';\nimport { BackofficeRightPageLayout } from '../components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js';\nimport { buildHubBreadcrumb } from '../components/backoffice/layout/breadcrumb/buildBreadcrumbs.js';\nimport { useBackofficePermissions } from '../components/backoffice/layout/BackofficePermissionsContext.js';\nimport { resolveLabel } from '../components/backoffice/layout/sidebarUtils.js';\n\nexport type BackofficeHubPageProps = {\n prepared: BackofficePreparedHubRoute;\n};\n\ntype HubPageItemView = {\n id: string;\n kind: 'entity' | 'tool';\n label: string;\n href: string;\n icon: ReactNode;\n};\n\ntype HubPageGroupView = {\n id: string;\n title: string;\n description: string | null;\n icon: ReactNode | undefined;\n items: readonly HubPageItemView[];\n};\n\nconst renderIcon = (\n Icon: BackofficeIconComponent | undefined,\n size: number,\n): ReactNode | undefined => {\n if (Icon == null) {\n return undefined;\n }\n return <Icon width={size} height={size} aria-hidden=\"true\" />;\n};\n\nconst isItemVisible = (input: {\n entity: BackofficeEntityManifestMap[string] | null | undefined;\n kind: 'entity' | 'tool';\n permissions: unknown;\n sidebar: ReturnType<typeof useBackofficeConfig>['sidebar'];\n}): boolean => {\n const { entity, kind, permissions, sidebar } = input;\n if (entity == null) {\n return false;\n }\n if (kind === 'entity' && entity.kind !== 'tool' && !entity.hasList) {\n return false;\n }\n const isVisible = sidebar?.isItemVisible?.(\n {\n kind,\n id: entity.id,\n },\n permissions,\n );\n return isVisible !== false;\n};\n\nexport const BackofficeHubPage = ({\n prepared,\n}: BackofficeHubPageProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { entities, sidebar } = useBackofficeConfig();\n const permissions = useBackofficePermissions();\n const [search, setSearch] = useState('');\n const { hub } = prepared;\n const title = resolveLabel(hub.title, tApp);\n let description: string | undefined;\n if (hub.description != null) {\n description = resolveLabel(hub.description, tApp);\n }\n const breadcrumb = buildHubBreadcrumb({ id: hub.id, title });\n const normalizedSearch = search.trim().toLowerCase();\n const searchEnabled = hub.search?.enabled !== false;\n let searchPlaceholder = t('hub.search.placeholder');\n if (hub.search?.placeholder != null) {\n searchPlaceholder = resolveLabel(hub.search.placeholder, tApp);\n }\n\n const groups = useMemo<readonly HubPageGroupView[]>(() => {\n return hub.groups\n .map((group) => {\n const items = group.items\n .map((item): HubPageItemView | null => {\n const entity = entities[item.id];\n if (entity == null) {\n return null;\n }\n if (\n !isItemVisible({\n entity,\n kind: item.kind,\n permissions,\n sidebar,\n })\n ) {\n return null;\n }\n const entityConfig = entity;\n const label = resolveLabel(entityConfig.label, tApp);\n if (\n normalizedSearch !== '' &&\n !label.toLowerCase().includes(normalizedSearch)\n ) {\n return null;\n }\n return {\n id: item.id,\n kind: item.kind,\n label,\n href: entityConfig.routes.list,\n icon: renderIcon(item.icon, 20),\n };\n })\n .filter((item): item is HubPageItemView => {\n return item != null;\n });\n let groupDescription: string | null = null;\n if (group.description != null) {\n groupDescription = resolveLabel(group.description, tApp);\n }\n return {\n id: group.id,\n title: resolveLabel(group.title, tApp),\n description: groupDescription,\n icon: renderIcon(group.icon, 18),\n items,\n };\n })\n .filter((group) => {\n return group.items.length > 0;\n });\n }, [entities, hub.groups, normalizedSearch, permissions, sidebar, tApp]);\n\n let emptyTitle = t('hub.empty.title');\n if (hub.emptyState?.title != null) {\n emptyTitle = resolveLabel(hub.emptyState.title, tApp);\n }\n let emptyDescription = t('hub.empty.description');\n if (hub.emptyState?.description != null) {\n emptyDescription = resolveLabel(hub.emptyState.description, tApp);\n }\n let subtitle = t('hub.subtitle');\n if (description != null) {\n subtitle = description;\n }\n const hasMixedKinds = groups.some((group) => {\n const kinds = new Set(\n group.items.map((item) => {\n return item.kind;\n }),\n );\n return kinds.size > 1;\n });\n\n const templateGroups = useMemo<readonly BackofficeHubTemplateGroup[]>(() => {\n return groups.map((group) => {\n return {\n id: group.id,\n title: group.title,\n description: group.description,\n icon: group.icon,\n items: group.items.map((item) => {\n let metaLabel: string | null = null;\n if (hasMixedKinds) {\n metaLabel = t('hub.itemKinds.entity');\n if (item.kind === 'tool') {\n metaLabel = t('hub.itemKinds.tool');\n }\n }\n return {\n id: item.id,\n kind: item.kind,\n label: item.label,\n href: item.href,\n icon: item.icon,\n metaLabel,\n };\n }),\n };\n });\n }, [groups, hasMixedKinds, t]);\n\n let searchConfig: BackofficeHubTemplateSearch | undefined;\n if (searchEnabled) {\n searchConfig = {\n value: search,\n onChange: setSearch,\n placeholder: searchPlaceholder,\n };\n }\n\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <DetailPageTemplate\n header={{\n title,\n subtitle,\n }}\n >\n <BackofficeHubTemplate\n groups={templateGroups}\n search={searchConfig}\n emptyState={{\n title: emptyTitle,\n description: emptyDescription,\n icon: <SidebarTasksSvg width={28} height={28} aria-hidden=\"true\" />,\n }}\n />\n </DetailPageTemplate>\n </BackofficeRightPageLayout>\n );\n};\n\nexport default BackofficeHubPage;\n"],"mappings":"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"}
@@ -7,16 +7,21 @@ import { buildSidebarSections as a } from "../components/backoffice/layout/build
7
7
  import ne from "../components/backoffice/layout/mapViewerToSidebarProfileView.js";
8
8
  import { BackofficeContentBoundary as re } from "../components/backoffice/routing/BackofficeContentBoundary.js";
9
9
  import { resetRelayStore as ie } from "../relay/environment.js";
10
- import { useRelayEnvironment as ae } from "../relay/useRelayEnvironment.js";
11
- import oe from "../hooks/useBackofficeSidebarPins.js";
12
- import se from "../hooks/useSidebarGroupCollapse.js";
13
- import { getBackofficeLoginPath as ce } from "../router/backofficeAuthPaths.js";
14
- import { useCallback as le, useContext as ue, useEffect as o, useMemo as s, useState as c } from "react";
15
- import { AdminShellLayout as de, BackofficeSidebarProfileMenu as l, EnvironmentBadge as u, GlobalSearchInput as d, ToastProvider as f } from "@plumile/ui";
16
- import { jsx as p } from "react/jsx-runtime";
17
- import { useTranslation as fe } from "react-i18next";
18
- import { commitMutation as pe, usePreloadedQuery as m } from "react-relay";
19
- import { RoutingContext as me, useLocation as he } from "@plumile/router";
10
+ import { useRelayEnvironment as o } from "../relay/useRelayEnvironment.js";
11
+ import ae from "../hooks/useBackofficeSidebarPins.js";
12
+ import oe from "../hooks/useSidebarGroupCollapse.js";
13
+ import { getBackofficeLoginPath as se } from "../router/backofficeAuthPaths.js";
14
+ import { useCallback as ce, useContext as le, useEffect as s, useMemo as c, useState as l } from "react";
15
+ import { jsx as u } from "react/jsx-runtime";
16
+ import { useTranslation as ue } from "react-i18next";
17
+ import { commitMutation as de, usePreloadedQuery as d } from "react-relay";
18
+ import { ToastProvider as f } from "@plumile/ui/atomic/molecules/toast/ToastProvider.js";
19
+ import fe from "@plumile/router/routing/RoutingContext.js";
20
+ import { GlobalSearchInput as pe } from "@plumile/ui/backoffice/molecules/global_search_input/GlobalSearchInput.js";
21
+ import me from "@plumile/router/routing/useLocation.js";
22
+ import { AdminShellLayout as he } from "@plumile/ui/admin/templates/admin_shell_layout/AdminShellLayout.js";
23
+ import { EnvironmentBadge as p } from "@plumile/ui/backoffice/atoms/environment_badge/EnvironmentBadge.js";
24
+ import { BackofficeSidebarProfileMenu as m } from "@plumile/ui/backoffice/molecules/sidebar_profile_menu/BackofficeSidebarProfileMenu.js";
20
25
  //#region src/pages/BackofficeLayoutPage.tsx
21
26
  var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", ve = (e) => {
22
27
  if (typeof window > "u") return [];
@@ -36,16 +41,16 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
36
41
  if (!(typeof window > "u")) try {
37
42
  window.localStorage.setItem(e, JSON.stringify(t));
38
43
  } catch {}
39
- }, g = ({ children: m, permissions: g, authStatus: _, activeGroupId: v }) => {
40
- let { t: y } = fe(), { t: b } = e(), { pathname: x } = he(), S = ue(me), C = ae(), { auth: w, basePath: T, entities: E, sidebar: D } = t(), [O, ye] = c(""), k = D?.preferences?.storageKey ?? _e, A = D?.preferences?.persistCollapsed === !0, [j, be] = c(() => {
44
+ }, g = ({ children: d, permissions: g, authStatus: _, activeGroupId: v }) => {
45
+ let { t: y } = ue(), { t: b } = e(), { pathname: x } = me(), S = le(fe), C = o(), { auth: w, basePath: T, entities: E, sidebar: D } = t(), [O, ye] = l(""), k = D?.preferences?.storageKey ?? _e, A = D?.preferences?.persistCollapsed === !0, [j, be] = l(() => {
41
46
  if (!A || typeof window > "u") return !1;
42
47
  try {
43
48
  return window.localStorage.getItem(`${k}:collapsed`) === "true";
44
49
  } catch {
45
50
  return !1;
46
51
  }
47
- }), [M, N] = c(!1), [P, xe] = c(null), F = D?.recentItems, I = F?.enabled === !0, L = F?.storageKey ?? ge, R = F?.maxItems ?? 8, [z, Se] = c(() => I ? ve(L) : []);
48
- o(() => {
52
+ }), [M, N] = l(!1), [P, xe] = l(null), F = D?.recentItems, I = F?.enabled === !0, L = F?.storageKey ?? ge, R = F?.maxItems ?? 8, [z, Se] = l(() => I ? ve(L) : []);
53
+ s(() => {
49
54
  if (!(!A || typeof window > "u")) try {
50
55
  window.localStorage.setItem(`${k}:collapsed`, String(j));
51
56
  } catch {}
@@ -54,13 +59,13 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
54
59
  A,
55
60
  k
56
61
  ]);
57
- let B = s(() => i(E, D), [E, D]), Ce = s(() => Object.keys(B), [B]), we = s(() => Object.fromEntries(Object.entries(B).map(([e, t]) => [e, t.behavior?.defaultCollapsed ?? !0])), [B]), Te = s(() => ee(B, E, D, g), [
62
+ let B = c(() => i(E, D), [E, D]), Ce = c(() => Object.keys(B), [B]), we = c(() => Object.fromEntries(Object.entries(B).map(([e, t]) => [e, t.behavior?.defaultCollapsed ?? !0])), [B]), Te = c(() => ee(B, E, D, g), [
58
63
  E,
59
64
  B,
60
65
  g,
61
66
  D
62
- ]), V = s(() => r(x, E), [E, x]);
63
- o(() => {
67
+ ]), V = c(() => r(x, E), [E, x]);
68
+ s(() => {
64
69
  if (!I || V == null) return;
65
70
  let e = E[V];
66
71
  if (e == null || e.kind !== "tool" && !e.hasList) return;
@@ -85,19 +90,19 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
85
90
  L,
86
91
  y
87
92
  ]);
88
- let { pins: H, toggle: U, reorder: W } = oe({
93
+ let { pins: H, toggle: U, reorder: W } = ae({
89
94
  enabled: D?.pinnedItems?.enabled === !0,
90
95
  storageKey: D?.pinnedItems?.storageKey,
91
96
  visibleEntityIds: Te
92
97
  }), G;
93
98
  D?.preferences?.storageKey != null && (G = `${D.preferences.storageKey}:groups`);
94
- let { collapsedByGroupId: K, setCollapsed: q } = se({
99
+ let { collapsedByGroupId: K, setCollapsed: q } = oe({
95
100
  groupIds: Ce,
96
101
  activeGroupId: v,
97
102
  defaultCollapsedByGroupId: we,
98
103
  persist: D?.preferences?.persistGroups === !0,
99
104
  storageKey: G
100
- }), Ee = s(() => a({
105
+ }), Ee = c(() => a({
101
106
  basePath: T,
102
107
  pathname: x,
103
108
  entities: E,
@@ -128,7 +133,7 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
128
133
  b,
129
134
  y,
130
135
  U
131
- ]), De = s(() => a({
136
+ ]), De = c(() => a({
132
137
  basePath: T,
133
138
  pathname: x,
134
139
  entities: E,
@@ -159,12 +164,12 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
159
164
  b,
160
165
  y,
161
166
  U
162
- ]), J = s(() => import.meta.env?.DEV === !0 ? "dev" : "prod", []), Y = le(() => {
167
+ ]), J = c(() => import.meta.env?.DEV === !0 ? "dev" : "prod", []), Y = ce(() => {
163
168
  M || (N(!0), (async () => {
164
169
  try {
165
170
  let e = await w.logout.load();
166
171
  await new Promise((t, n) => {
167
- pe(C, {
172
+ de(C, {
168
173
  mutation: e.logoutMutation,
169
174
  variables: {},
170
175
  onCompleted: () => {
@@ -174,7 +179,7 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
174
179
  n(e);
175
180
  }
176
181
  });
177
- }), localStorage.removeItem("auth_token"), localStorage.removeItem("remember_me"), ie(), S?.history.push({ pathname: ce(T) });
182
+ }), localStorage.removeItem("auth_token"), localStorage.removeItem("remember_me"), ie(), S?.history.push({ pathname: se(T) });
178
183
  } finally {
179
184
  N(!1);
180
185
  }
@@ -185,10 +190,10 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
185
190
  M,
186
191
  C,
187
192
  S
188
- ]), X = _?.me ?? null, Z = s(() => ne({
193
+ ]), X = _?.me ?? null, Z = c(() => ne({
189
194
  viewer: X,
190
195
  unknownUserLabel: b("sidebar.profile.unknownUser")
191
- }), [b, X]), Oe = /* @__PURE__ */ p(l, {
196
+ }), [b, X]), Oe = /* @__PURE__ */ u(m, {
192
197
  collapsed: !1,
193
198
  viewer: Z,
194
199
  labels: {
@@ -198,7 +203,7 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
198
203
  },
199
204
  onSignOut: Y,
200
205
  isSigningOut: M
201
- }), ke = /* @__PURE__ */ p(l, {
206
+ }), ke = /* @__PURE__ */ u(m, {
202
207
  collapsed: !1,
203
208
  viewer: Z,
204
209
  labels: {
@@ -209,17 +214,17 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
209
214
  onSignOut: Y,
210
215
  isSigningOut: M
211
216
  }), Q = null;
212
- P != null && (Q = /* @__PURE__ */ p(re, { children: m }));
213
- let $ = /* @__PURE__ */ p(d, {
217
+ P != null && (Q = /* @__PURE__ */ u(re, { children: d }));
218
+ let $ = /* @__PURE__ */ u(pe, {
214
219
  value: O,
215
220
  onChange: ye,
216
221
  placeholder: b("sidebar.search.placeholder"),
217
222
  ariaLabel: b("sidebar.search.placeholder")
218
223
  });
219
- return /* @__PURE__ */ p(f, { children: /* @__PURE__ */ p(de, {
224
+ return /* @__PURE__ */ u(f, { children: /* @__PURE__ */ u(he, {
220
225
  sidebar: {
221
226
  sections: Ee,
222
- header: /* @__PURE__ */ p(u, { environment: J }),
227
+ header: /* @__PURE__ */ u(p, { environment: J }),
223
228
  search: $,
224
229
  footer: Oe,
225
230
  isCollapsed: j,
@@ -230,17 +235,17 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
230
235
  },
231
236
  mobileSidebar: {
232
237
  sections: De,
233
- header: /* @__PURE__ */ p(u, { environment: J }),
238
+ header: /* @__PURE__ */ u(p, { environment: J }),
234
239
  search: $,
235
240
  footer: ke,
236
241
  isCollapsed: !1,
237
242
  hideCollapseToggle: !0,
238
243
  navigationAriaLabel: b("sidebar.navigationAriaLabel")
239
244
  },
240
- topbar: { breadcrumb: /* @__PURE__ */ p("div", { ref: xe }) },
241
- children: /* @__PURE__ */ p(te, {
245
+ topbar: { breadcrumb: /* @__PURE__ */ u("div", { ref: xe }) },
246
+ children: /* @__PURE__ */ u(te, {
242
247
  permissions: g,
243
- children: /* @__PURE__ */ p(n, {
248
+ children: /* @__PURE__ */ u(n, {
244
249
  value: {
245
250
  target: P,
246
251
  dashboardHref: T,
@@ -250,18 +255,18 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
250
255
  })
251
256
  })
252
257
  }) });
253
- }, _ = ({ children: e, permissionsQuery: t, prepared: n, authStatus: r, activeGroupId: i }) => /* @__PURE__ */ p(g, {
254
- permissions: m(t, n),
258
+ }, _ = ({ children: e, permissionsQuery: t, prepared: n, authStatus: r, activeGroupId: i }) => /* @__PURE__ */ u(g, {
259
+ permissions: d(t, n),
255
260
  authStatus: r,
256
261
  activeGroupId: i,
257
262
  children: e
258
- }), v = ({ children: e, permissionsQuery: t, prepared: n, authStatus: r, activeGroupId: i }) => t != null && n != null ? /* @__PURE__ */ p(_, {
263
+ }), v = ({ children: e, permissionsQuery: t, prepared: n, authStatus: r, activeGroupId: i }) => t != null && n != null ? /* @__PURE__ */ u(_, {
259
264
  permissionsQuery: t,
260
265
  prepared: n,
261
266
  authStatus: r,
262
267
  activeGroupId: i,
263
268
  children: e
264
- }) : /* @__PURE__ */ p(g, {
269
+ }) : /* @__PURE__ */ u(g, {
265
270
  permissions: null,
266
271
  authStatus: r,
267
272
  activeGroupId: i,
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeLayoutPage.js","names":[],"sources":["../../../src/pages/BackofficeLayoutPage.tsx"],"sourcesContent":["import {\n useEffect,\n useMemo,\n type JSX,\n type ReactNode,\n useCallback,\n useContext,\n useState,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n commitMutation,\n usePreloadedQuery,\n type PreloadedQuery,\n} from 'react-relay';\nimport type {\n GraphQLTaggedNode,\n MutationParameters,\n OperationType,\n} from 'relay-runtime';\nimport { RoutingContext, useLocation } from '@plumile/router';\n\nimport {\n AdminShellLayout,\n BackofficeSidebarProfileMenu,\n EnvironmentBadge,\n GlobalSearchInput,\n ToastProvider,\n} from '@plumile/ui';\n\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport type { LogoutResponse, LogoutVariables } from '../hooks/useAuth.js';\nimport { useBackofficeSidebarPins } from '../hooks/useBackofficeSidebarPins.js';\nimport { useSidebarGroupCollapse } from '../hooks/useSidebarGroupCollapse.js';\nimport { buildSidebarSections } from '../components/backoffice/layout/buildSidebarSections.js';\nimport { BackofficeContentBoundary } from '../components/backoffice/routing/BackofficeContentBoundary.js';\nimport {\n resolveActiveEntityId,\n resolveSidebarGroups,\n resolveVisibleEntityIds,\n} from '../components/backoffice/layout/sidebarUtils.js';\nimport { BackofficeTopbarPortalContextProvider } from '../components/backoffice/layout/breadcrumb/BackofficeTopbarPortalContext.js';\nimport { BackofficePermissionsProvider } from '../components/backoffice/layout/BackofficePermissionsContext.js';\nimport {\n mapViewerToSidebarProfileView,\n type BackofficeViewerIdentity,\n} from '../components/backoffice/layout/mapViewerToSidebarProfileView.js';\nimport { resetRelayStore } from '../relay/environment.js';\nimport { useRelayEnvironment } from '../relay/useRelayEnvironment.js';\nimport { getBackofficeLoginPath } from '../router/backofficeAuthPaths.js';\nimport type { BackofficeSidebarRecentItem } from '../provider/types.js';\n\nexport type BackofficeLayoutPageProps = {\n children: ReactNode;\n permissionsQuery?: GraphQLTaggedNode;\n prepared?: PreloadedQuery<OperationType> | null;\n authStatus?: {\n isLoggedIn?: boolean | null;\n me?: BackofficeViewerIdentity | null;\n } | null;\n activeGroupId?: string | null;\n};\n\ntype LayoutShellProps = {\n children: ReactNode;\n permissions: unknown;\n authStatus?: {\n isLoggedIn?: boolean | null;\n me?: BackofficeViewerIdentity | null;\n } | null;\n activeGroupId?: string | null;\n};\n\nconst DEFAULT_RECENT_ITEMS_STORAGE_KEY = 'plumile:backoffice:recent-items';\nconst DEFAULT_SIDEBAR_PREFS_STORAGE_KEY = 'plumile:backoffice:sidebar';\n\nconst readRecentItems = (\n storageKey: string,\n): readonly BackofficeSidebarRecentItem[] => {\n if (typeof window === 'undefined') {\n return [];\n }\n try {\n const raw = window.localStorage.getItem(storageKey);\n if (raw == null) {\n return [];\n }\n const parsed = JSON.parse(raw) as unknown;\n if (!Array.isArray(parsed)) {\n return [];\n }\n return parsed.filter((item): item is BackofficeSidebarRecentItem => {\n if (item == null || typeof item !== 'object') {\n return false;\n }\n const candidate = item as Partial<BackofficeSidebarRecentItem>;\n return (\n (candidate.kind === 'entity' || candidate.kind === 'tool') &&\n typeof candidate.id === 'string' &&\n typeof candidate.label === 'string' &&\n typeof candidate.href === 'string' &&\n typeof candidate.visitedAt === 'number'\n );\n });\n } catch {\n return [];\n }\n};\n\nconst writeRecentItems = (\n storageKey: string,\n items: readonly BackofficeSidebarRecentItem[],\n): void => {\n if (typeof window === 'undefined') {\n return;\n }\n try {\n window.localStorage.setItem(storageKey, JSON.stringify(items));\n } catch {\n // Ignore storage quota / privacy mode failures.\n }\n};\n\nconst BackofficeLayoutShell = ({\n children,\n permissions,\n authStatus,\n activeGroupId,\n}: LayoutShellProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { pathname } = useLocation();\n const routing = useContext(RoutingContext);\n const relayEnvironment = useRelayEnvironment();\n const {\n auth: authConfig,\n basePath,\n entities,\n sidebar,\n } = useBackofficeConfig();\n const [sidebarQuery, setSidebarQuery] = useState('');\n const sidebarPreferencesStorageKey =\n sidebar?.preferences?.storageKey ?? DEFAULT_SIDEBAR_PREFS_STORAGE_KEY;\n const persistSidebarCollapsed =\n sidebar?.preferences?.persistCollapsed === true;\n const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(() => {\n if (!persistSidebarCollapsed || typeof window === 'undefined') {\n return false;\n }\n try {\n return (\n window.localStorage.getItem(\n `${sidebarPreferencesStorageKey}:collapsed`,\n ) === 'true'\n );\n } catch {\n return false;\n }\n });\n const [isSigningOut, setIsSigningOut] = useState(false);\n const [topbarTarget, setTopbarTarget] = useState<HTMLDivElement | null>(null);\n const recentItemsConfig = sidebar?.recentItems;\n const recentItemsEnabled = recentItemsConfig?.enabled === true;\n const recentItemsStorageKey =\n recentItemsConfig?.storageKey ?? DEFAULT_RECENT_ITEMS_STORAGE_KEY;\n const recentItemsMaxItems = recentItemsConfig?.maxItems ?? 8;\n const [recentItems, setRecentItems] = useState<\n readonly BackofficeSidebarRecentItem[]\n >(() => {\n if (!recentItemsEnabled) {\n return [];\n }\n return readRecentItems(recentItemsStorageKey);\n });\n\n useEffect(() => {\n if (!persistSidebarCollapsed || typeof window === 'undefined') {\n return;\n }\n try {\n window.localStorage.setItem(\n `${sidebarPreferencesStorageKey}:collapsed`,\n String(isSidebarCollapsed),\n );\n } catch {\n // Ignore storage quota / privacy mode failures.\n }\n }, [\n isSidebarCollapsed,\n persistSidebarCollapsed,\n sidebarPreferencesStorageKey,\n ]);\n\n const groups = useMemo(() => {\n return resolveSidebarGroups(entities, sidebar);\n }, [entities, sidebar]);\n\n const groupIds = useMemo(() => {\n return Object.keys(groups);\n }, [groups]);\n\n const defaultCollapsedByGroupId = useMemo(() => {\n return Object.fromEntries(\n Object.entries(groups).map(([groupId, group]) => {\n return [groupId, group.behavior?.defaultCollapsed ?? true];\n }),\n );\n }, [groups]);\n\n const visibleEntityIds = useMemo(() => {\n return resolveVisibleEntityIds(groups, entities, sidebar, permissions);\n }, [entities, groups, permissions, sidebar]);\n\n const activeEntityId = useMemo(() => {\n return resolveActiveEntityId(pathname, entities);\n }, [entities, pathname]);\n\n useEffect(() => {\n if (!recentItemsEnabled || activeEntityId == null) {\n return;\n }\n const config = entities[activeEntityId];\n if (config == null) {\n return;\n }\n if (config.kind !== 'tool' && !config.hasList) {\n return;\n }\n const href = config.routes.list;\n let kind: BackofficeSidebarRecentItem['kind'] = 'entity';\n if (config.kind === 'tool') {\n kind = 'tool';\n }\n const item: BackofficeSidebarRecentItem = {\n kind,\n id: activeEntityId,\n label: config.label(tApp),\n href,\n visitedAt: Date.now(),\n };\n setRecentItems((prev) => {\n const next = [\n item,\n ...prev.filter((entry) => {\n return entry.id !== item.id || entry.kind !== item.kind;\n }),\n ].slice(0, recentItemsMaxItems);\n writeRecentItems(recentItemsStorageKey, next);\n return next;\n });\n }, [\n activeEntityId,\n entities,\n recentItemsEnabled,\n recentItemsMaxItems,\n recentItemsStorageKey,\n tApp,\n ]);\n\n const {\n pins,\n toggle: togglePin,\n reorder: reorderPin,\n } = useBackofficeSidebarPins({\n enabled: sidebar?.pinnedItems?.enabled === true,\n storageKey: sidebar?.pinnedItems?.storageKey,\n visibleEntityIds,\n });\n\n let groupCollapseStorageKey: string | undefined;\n if (sidebar?.preferences?.storageKey != null) {\n groupCollapseStorageKey = `${sidebar.preferences.storageKey}:groups`;\n }\n\n const { collapsedByGroupId, setCollapsed } = useSidebarGroupCollapse({\n groupIds,\n activeGroupId,\n defaultCollapsedByGroupId,\n persist: sidebar?.preferences?.persistGroups === true,\n storageKey: groupCollapseStorageKey,\n });\n\n const sections = useMemo(() => {\n return buildSidebarSections({\n basePath,\n pathname,\n entities,\n sidebar,\n permissions,\n searchQuery: sidebarQuery,\n tApp,\n t,\n pinnedEntityIds: pins,\n recentItems,\n onTogglePin: togglePin,\n onReorderPin: reorderPin,\n collapsedByGroupId,\n onGroupCollapsedChange: setCollapsed,\n sidebarCollapsed: false,\n });\n }, [\n basePath,\n collapsedByGroupId,\n entities,\n pathname,\n permissions,\n pins,\n recentItems,\n reorderPin,\n setCollapsed,\n sidebar,\n sidebarQuery,\n t,\n tApp,\n togglePin,\n ]);\n\n const mobileSections = useMemo(() => {\n return buildSidebarSections({\n basePath,\n pathname,\n entities,\n sidebar,\n permissions,\n searchQuery: sidebarQuery,\n tApp,\n t,\n pinnedEntityIds: pins,\n recentItems,\n onTogglePin: togglePin,\n onReorderPin: reorderPin,\n collapsedByGroupId,\n onGroupCollapsedChange: setCollapsed,\n sidebarCollapsed: false,\n });\n }, [\n basePath,\n collapsedByGroupId,\n entities,\n pathname,\n permissions,\n pins,\n recentItems,\n reorderPin,\n setCollapsed,\n sidebar,\n sidebarQuery,\n t,\n tApp,\n togglePin,\n ]);\n\n const environment = useMemo(() => {\n const meta = import.meta as unknown as { env?: Record<string, unknown> };\n if (meta.env?.DEV === true) {\n return 'dev' as const;\n }\n return 'prod' as const;\n }, []);\n\n const handleSignOut = useCallback(() => {\n if (isSigningOut) {\n return;\n }\n\n type LogoutMutation = MutationParameters & {\n response: LogoutResponse;\n variables: LogoutVariables;\n };\n\n setIsSigningOut(true);\n\n const runSignOut = async (): Promise<void> => {\n try {\n const config = await authConfig.logout.load();\n await new Promise<void>((resolve, reject) => {\n commitMutation<LogoutMutation>(relayEnvironment, {\n mutation: config.logoutMutation,\n variables: {},\n onCompleted: () => {\n resolve();\n },\n onError: (error) => {\n reject(error);\n },\n });\n });\n localStorage.removeItem('auth_token');\n localStorage.removeItem('remember_me');\n resetRelayStore();\n routing?.history.push({ pathname: getBackofficeLoginPath(basePath) });\n } finally {\n setIsSigningOut(false);\n }\n };\n\n runSignOut().catch(() => {\n /* noop */\n });\n }, [authConfig.logout, basePath, isSigningOut, relayEnvironment, routing]);\n\n const viewer = authStatus?.me ?? null;\n const sidebarProfile = useMemo(() => {\n return mapViewerToSidebarProfileView({\n viewer,\n unknownUserLabel: t('sidebar.profile.unknownUser'),\n });\n }, [t, viewer]);\n\n const sidebarFooter = (\n <BackofficeSidebarProfileMenu\n collapsed={false}\n viewer={sidebarProfile}\n labels={{\n sectionTitle: t('sidebar.profile.title'),\n menuAriaLabel: t('sidebar.profile.menuAriaLabel'),\n signOut: t('sidebar.profile.actions.signOut'),\n }}\n onSignOut={handleSignOut}\n isSigningOut={isSigningOut}\n />\n );\n\n const mobileSidebarFooter = (\n <BackofficeSidebarProfileMenu\n collapsed={false}\n viewer={sidebarProfile}\n labels={{\n sectionTitle: t('sidebar.profile.title'),\n menuAriaLabel: t('sidebar.profile.menuAriaLabel'),\n signOut: t('sidebar.profile.actions.signOut'),\n }}\n onSignOut={handleSignOut}\n isSigningOut={isSigningOut}\n />\n );\n\n let contentNode: JSX.Element | null = null;\n if (topbarTarget != null) {\n contentNode = (\n <BackofficeContentBoundary>{children}</BackofficeContentBoundary>\n );\n }\n\n const sidebarSearchNode = (\n <GlobalSearchInput\n value={sidebarQuery}\n onChange={setSidebarQuery}\n placeholder={t('sidebar.search.placeholder')}\n ariaLabel={t('sidebar.search.placeholder')}\n />\n );\n\n return (\n <ToastProvider>\n <AdminShellLayout\n sidebar={{\n sections,\n header: <EnvironmentBadge environment={environment} />,\n search: sidebarSearchNode,\n footer: sidebarFooter,\n isCollapsed: isSidebarCollapsed,\n onCollapsedChange: setIsSidebarCollapsed,\n collapseToggleLabel: t('sidebar.actions.collapseSidebar'),\n expandToggleLabel: t('sidebar.actions.expandSidebar'),\n navigationAriaLabel: t('sidebar.navigationAriaLabel'),\n }}\n mobileSidebar={{\n sections: mobileSections,\n header: <EnvironmentBadge environment={environment} />,\n search: sidebarSearchNode,\n footer: mobileSidebarFooter,\n isCollapsed: false,\n hideCollapseToggle: true,\n navigationAriaLabel: t('sidebar.navigationAriaLabel'),\n }}\n topbar={{\n breadcrumb: <div ref={setTopbarTarget} />,\n }}\n >\n <BackofficePermissionsProvider permissions={permissions}>\n <BackofficeTopbarPortalContextProvider\n value={{\n target: topbarTarget,\n dashboardHref: basePath,\n dashboardLabel: t('sidebar.items.dashboard'),\n }}\n >\n {contentNode}\n </BackofficeTopbarPortalContextProvider>\n </BackofficePermissionsProvider>\n </AdminShellLayout>\n </ToastProvider>\n );\n};\n\ntype LayoutWithPermissionsProps = {\n children: ReactNode;\n permissionsQuery: GraphQLTaggedNode;\n prepared: PreloadedQuery<OperationType>;\n authStatus?: {\n isLoggedIn?: boolean | null;\n me?: BackofficeViewerIdentity | null;\n } | null;\n activeGroupId?: string | null;\n};\n\nconst LayoutWithPermissions = ({\n children,\n permissionsQuery,\n prepared,\n authStatus,\n activeGroupId,\n}: LayoutWithPermissionsProps): JSX.Element => {\n const permissions = usePreloadedQuery(permissionsQuery, prepared);\n\n return (\n <BackofficeLayoutShell\n permissions={permissions}\n authStatus={authStatus}\n activeGroupId={activeGroupId}\n >\n {children}\n </BackofficeLayoutShell>\n );\n};\n\nexport const BackofficeLayoutPage = ({\n children,\n permissionsQuery,\n prepared,\n authStatus,\n activeGroupId,\n}: BackofficeLayoutPageProps): JSX.Element => {\n if (permissionsQuery != null && prepared != null) {\n return (\n <LayoutWithPermissions\n permissionsQuery={permissionsQuery}\n prepared={prepared}\n authStatus={authStatus}\n activeGroupId={activeGroupId}\n >\n {children}\n </LayoutWithPermissions>\n );\n }\n\n return (\n <BackofficeLayoutShell\n permissions={null}\n authStatus={authStatus}\n activeGroupId={activeGroupId}\n >\n {children}\n </BackofficeLayoutShell>\n );\n};\n\nexport default BackofficeLayoutPage;\n"],"mappings":"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"}
1
+ {"version":3,"file":"BackofficeLayoutPage.js","names":[],"sources":["../../../src/pages/BackofficeLayoutPage.tsx"],"sourcesContent":["import {\n useEffect,\n useMemo,\n type JSX,\n type ReactNode,\n useCallback,\n useContext,\n useState,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n commitMutation,\n usePreloadedQuery,\n type PreloadedQuery,\n} from 'react-relay';\nimport type {\n GraphQLTaggedNode,\n MutationParameters,\n OperationType,\n} from 'relay-runtime';\nimport RoutingContext from '@plumile/router/routing/RoutingContext.js';\nimport useLocation from '@plumile/router/routing/useLocation.js';\n\nimport { AdminShellLayout } from '@plumile/ui/admin/templates/admin_shell_layout/AdminShellLayout.js';\nimport { ToastProvider } from '@plumile/ui/atomic/molecules/toast/ToastProvider.js';\nimport { EnvironmentBadge } from '@plumile/ui/backoffice/atoms/environment_badge/EnvironmentBadge.js';\nimport { GlobalSearchInput } from '@plumile/ui/backoffice/molecules/global_search_input/GlobalSearchInput.js';\nimport { BackofficeSidebarProfileMenu } from '@plumile/ui/backoffice/molecules/sidebar_profile_menu/BackofficeSidebarProfileMenu.js';\n\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport type { LogoutResponse, LogoutVariables } from '../hooks/useAuth.js';\nimport { useBackofficeSidebarPins } from '../hooks/useBackofficeSidebarPins.js';\nimport { useSidebarGroupCollapse } from '../hooks/useSidebarGroupCollapse.js';\nimport { buildSidebarSections } from '../components/backoffice/layout/buildSidebarSections.js';\nimport { BackofficeContentBoundary } from '../components/backoffice/routing/BackofficeContentBoundary.js';\nimport {\n resolveActiveEntityId,\n resolveSidebarGroups,\n resolveVisibleEntityIds,\n} from '../components/backoffice/layout/sidebarUtils.js';\nimport { BackofficeTopbarPortalContextProvider } from '../components/backoffice/layout/breadcrumb/BackofficeTopbarPortalContext.js';\nimport { BackofficePermissionsProvider } from '../components/backoffice/layout/BackofficePermissionsContext.js';\nimport {\n mapViewerToSidebarProfileView,\n type BackofficeViewerIdentity,\n} from '../components/backoffice/layout/mapViewerToSidebarProfileView.js';\nimport { resetRelayStore } from '../relay/environment.js';\nimport { useRelayEnvironment } from '../relay/useRelayEnvironment.js';\nimport { getBackofficeLoginPath } from '../router/backofficeAuthPaths.js';\nimport type { BackofficeSidebarRecentItem } from '../provider/types.js';\n\nexport type BackofficeLayoutPageProps = {\n children: ReactNode;\n permissionsQuery?: GraphQLTaggedNode;\n prepared?: PreloadedQuery<OperationType> | null;\n authStatus?: {\n isLoggedIn?: boolean | null;\n me?: BackofficeViewerIdentity | null;\n } | null;\n activeGroupId?: string | null;\n};\n\ntype LayoutShellProps = {\n children: ReactNode;\n permissions: unknown;\n authStatus?: {\n isLoggedIn?: boolean | null;\n me?: BackofficeViewerIdentity | null;\n } | null;\n activeGroupId?: string | null;\n};\n\nconst DEFAULT_RECENT_ITEMS_STORAGE_KEY = 'plumile:backoffice:recent-items';\nconst DEFAULT_SIDEBAR_PREFS_STORAGE_KEY = 'plumile:backoffice:sidebar';\n\nconst readRecentItems = (\n storageKey: string,\n): readonly BackofficeSidebarRecentItem[] => {\n if (typeof window === 'undefined') {\n return [];\n }\n try {\n const raw = window.localStorage.getItem(storageKey);\n if (raw == null) {\n return [];\n }\n const parsed = JSON.parse(raw) as unknown;\n if (!Array.isArray(parsed)) {\n return [];\n }\n return parsed.filter((item): item is BackofficeSidebarRecentItem => {\n if (item == null || typeof item !== 'object') {\n return false;\n }\n const candidate = item as Partial<BackofficeSidebarRecentItem>;\n return (\n (candidate.kind === 'entity' || candidate.kind === 'tool') &&\n typeof candidate.id === 'string' &&\n typeof candidate.label === 'string' &&\n typeof candidate.href === 'string' &&\n typeof candidate.visitedAt === 'number'\n );\n });\n } catch {\n return [];\n }\n};\n\nconst writeRecentItems = (\n storageKey: string,\n items: readonly BackofficeSidebarRecentItem[],\n): void => {\n if (typeof window === 'undefined') {\n return;\n }\n try {\n window.localStorage.setItem(storageKey, JSON.stringify(items));\n } catch {\n // Ignore storage quota / privacy mode failures.\n }\n};\n\nconst BackofficeLayoutShell = ({\n children,\n permissions,\n authStatus,\n activeGroupId,\n}: LayoutShellProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { pathname } = useLocation();\n const routing = useContext(RoutingContext);\n const relayEnvironment = useRelayEnvironment();\n const {\n auth: authConfig,\n basePath,\n entities,\n sidebar,\n } = useBackofficeConfig();\n const [sidebarQuery, setSidebarQuery] = useState('');\n const sidebarPreferencesStorageKey =\n sidebar?.preferences?.storageKey ?? DEFAULT_SIDEBAR_PREFS_STORAGE_KEY;\n const persistSidebarCollapsed =\n sidebar?.preferences?.persistCollapsed === true;\n const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(() => {\n if (!persistSidebarCollapsed || typeof window === 'undefined') {\n return false;\n }\n try {\n return (\n window.localStorage.getItem(\n `${sidebarPreferencesStorageKey}:collapsed`,\n ) === 'true'\n );\n } catch {\n return false;\n }\n });\n const [isSigningOut, setIsSigningOut] = useState(false);\n const [topbarTarget, setTopbarTarget] = useState<HTMLDivElement | null>(null);\n const recentItemsConfig = sidebar?.recentItems;\n const recentItemsEnabled = recentItemsConfig?.enabled === true;\n const recentItemsStorageKey =\n recentItemsConfig?.storageKey ?? DEFAULT_RECENT_ITEMS_STORAGE_KEY;\n const recentItemsMaxItems = recentItemsConfig?.maxItems ?? 8;\n const [recentItems, setRecentItems] = useState<\n readonly BackofficeSidebarRecentItem[]\n >(() => {\n if (!recentItemsEnabled) {\n return [];\n }\n return readRecentItems(recentItemsStorageKey);\n });\n\n useEffect(() => {\n if (!persistSidebarCollapsed || typeof window === 'undefined') {\n return;\n }\n try {\n window.localStorage.setItem(\n `${sidebarPreferencesStorageKey}:collapsed`,\n String(isSidebarCollapsed),\n );\n } catch {\n // Ignore storage quota / privacy mode failures.\n }\n }, [\n isSidebarCollapsed,\n persistSidebarCollapsed,\n sidebarPreferencesStorageKey,\n ]);\n\n const groups = useMemo(() => {\n return resolveSidebarGroups(entities, sidebar);\n }, [entities, sidebar]);\n\n const groupIds = useMemo(() => {\n return Object.keys(groups);\n }, [groups]);\n\n const defaultCollapsedByGroupId = useMemo(() => {\n return Object.fromEntries(\n Object.entries(groups).map(([groupId, group]) => {\n return [groupId, group.behavior?.defaultCollapsed ?? true];\n }),\n );\n }, [groups]);\n\n const visibleEntityIds = useMemo(() => {\n return resolveVisibleEntityIds(groups, entities, sidebar, permissions);\n }, [entities, groups, permissions, sidebar]);\n\n const activeEntityId = useMemo(() => {\n return resolveActiveEntityId(pathname, entities);\n }, [entities, pathname]);\n\n useEffect(() => {\n if (!recentItemsEnabled || activeEntityId == null) {\n return;\n }\n const config = entities[activeEntityId];\n if (config == null) {\n return;\n }\n if (config.kind !== 'tool' && !config.hasList) {\n return;\n }\n const href = config.routes.list;\n let kind: BackofficeSidebarRecentItem['kind'] = 'entity';\n if (config.kind === 'tool') {\n kind = 'tool';\n }\n const item: BackofficeSidebarRecentItem = {\n kind,\n id: activeEntityId,\n label: config.label(tApp),\n href,\n visitedAt: Date.now(),\n };\n setRecentItems((prev) => {\n const next = [\n item,\n ...prev.filter((entry) => {\n return entry.id !== item.id || entry.kind !== item.kind;\n }),\n ].slice(0, recentItemsMaxItems);\n writeRecentItems(recentItemsStorageKey, next);\n return next;\n });\n }, [\n activeEntityId,\n entities,\n recentItemsEnabled,\n recentItemsMaxItems,\n recentItemsStorageKey,\n tApp,\n ]);\n\n const {\n pins,\n toggle: togglePin,\n reorder: reorderPin,\n } = useBackofficeSidebarPins({\n enabled: sidebar?.pinnedItems?.enabled === true,\n storageKey: sidebar?.pinnedItems?.storageKey,\n visibleEntityIds,\n });\n\n let groupCollapseStorageKey: string | undefined;\n if (sidebar?.preferences?.storageKey != null) {\n groupCollapseStorageKey = `${sidebar.preferences.storageKey}:groups`;\n }\n\n const { collapsedByGroupId, setCollapsed } = useSidebarGroupCollapse({\n groupIds,\n activeGroupId,\n defaultCollapsedByGroupId,\n persist: sidebar?.preferences?.persistGroups === true,\n storageKey: groupCollapseStorageKey,\n });\n\n const sections = useMemo(() => {\n return buildSidebarSections({\n basePath,\n pathname,\n entities,\n sidebar,\n permissions,\n searchQuery: sidebarQuery,\n tApp,\n t,\n pinnedEntityIds: pins,\n recentItems,\n onTogglePin: togglePin,\n onReorderPin: reorderPin,\n collapsedByGroupId,\n onGroupCollapsedChange: setCollapsed,\n sidebarCollapsed: false,\n });\n }, [\n basePath,\n collapsedByGroupId,\n entities,\n pathname,\n permissions,\n pins,\n recentItems,\n reorderPin,\n setCollapsed,\n sidebar,\n sidebarQuery,\n t,\n tApp,\n togglePin,\n ]);\n\n const mobileSections = useMemo(() => {\n return buildSidebarSections({\n basePath,\n pathname,\n entities,\n sidebar,\n permissions,\n searchQuery: sidebarQuery,\n tApp,\n t,\n pinnedEntityIds: pins,\n recentItems,\n onTogglePin: togglePin,\n onReorderPin: reorderPin,\n collapsedByGroupId,\n onGroupCollapsedChange: setCollapsed,\n sidebarCollapsed: false,\n });\n }, [\n basePath,\n collapsedByGroupId,\n entities,\n pathname,\n permissions,\n pins,\n recentItems,\n reorderPin,\n setCollapsed,\n sidebar,\n sidebarQuery,\n t,\n tApp,\n togglePin,\n ]);\n\n const environment = useMemo(() => {\n const meta = import.meta as unknown as { env?: Record<string, unknown> };\n if (meta.env?.DEV === true) {\n return 'dev' as const;\n }\n return 'prod' as const;\n }, []);\n\n const handleSignOut = useCallback(() => {\n if (isSigningOut) {\n return;\n }\n\n type LogoutMutation = MutationParameters & {\n response: LogoutResponse;\n variables: LogoutVariables;\n };\n\n setIsSigningOut(true);\n\n const runSignOut = async (): Promise<void> => {\n try {\n const config = await authConfig.logout.load();\n await new Promise<void>((resolve, reject) => {\n commitMutation<LogoutMutation>(relayEnvironment, {\n mutation: config.logoutMutation,\n variables: {},\n onCompleted: () => {\n resolve();\n },\n onError: (error) => {\n reject(error);\n },\n });\n });\n localStorage.removeItem('auth_token');\n localStorage.removeItem('remember_me');\n resetRelayStore();\n routing?.history.push({ pathname: getBackofficeLoginPath(basePath) });\n } finally {\n setIsSigningOut(false);\n }\n };\n\n runSignOut().catch(() => {\n /* noop */\n });\n }, [authConfig.logout, basePath, isSigningOut, relayEnvironment, routing]);\n\n const viewer = authStatus?.me ?? null;\n const sidebarProfile = useMemo(() => {\n return mapViewerToSidebarProfileView({\n viewer,\n unknownUserLabel: t('sidebar.profile.unknownUser'),\n });\n }, [t, viewer]);\n\n const sidebarFooter = (\n <BackofficeSidebarProfileMenu\n collapsed={false}\n viewer={sidebarProfile}\n labels={{\n sectionTitle: t('sidebar.profile.title'),\n menuAriaLabel: t('sidebar.profile.menuAriaLabel'),\n signOut: t('sidebar.profile.actions.signOut'),\n }}\n onSignOut={handleSignOut}\n isSigningOut={isSigningOut}\n />\n );\n\n const mobileSidebarFooter = (\n <BackofficeSidebarProfileMenu\n collapsed={false}\n viewer={sidebarProfile}\n labels={{\n sectionTitle: t('sidebar.profile.title'),\n menuAriaLabel: t('sidebar.profile.menuAriaLabel'),\n signOut: t('sidebar.profile.actions.signOut'),\n }}\n onSignOut={handleSignOut}\n isSigningOut={isSigningOut}\n />\n );\n\n let contentNode: JSX.Element | null = null;\n if (topbarTarget != null) {\n contentNode = (\n <BackofficeContentBoundary>{children}</BackofficeContentBoundary>\n );\n }\n\n const sidebarSearchNode = (\n <GlobalSearchInput\n value={sidebarQuery}\n onChange={setSidebarQuery}\n placeholder={t('sidebar.search.placeholder')}\n ariaLabel={t('sidebar.search.placeholder')}\n />\n );\n\n return (\n <ToastProvider>\n <AdminShellLayout\n sidebar={{\n sections,\n header: <EnvironmentBadge environment={environment} />,\n search: sidebarSearchNode,\n footer: sidebarFooter,\n isCollapsed: isSidebarCollapsed,\n onCollapsedChange: setIsSidebarCollapsed,\n collapseToggleLabel: t('sidebar.actions.collapseSidebar'),\n expandToggleLabel: t('sidebar.actions.expandSidebar'),\n navigationAriaLabel: t('sidebar.navigationAriaLabel'),\n }}\n mobileSidebar={{\n sections: mobileSections,\n header: <EnvironmentBadge environment={environment} />,\n search: sidebarSearchNode,\n footer: mobileSidebarFooter,\n isCollapsed: false,\n hideCollapseToggle: true,\n navigationAriaLabel: t('sidebar.navigationAriaLabel'),\n }}\n topbar={{\n breadcrumb: <div ref={setTopbarTarget} />,\n }}\n >\n <BackofficePermissionsProvider permissions={permissions}>\n <BackofficeTopbarPortalContextProvider\n value={{\n target: topbarTarget,\n dashboardHref: basePath,\n dashboardLabel: t('sidebar.items.dashboard'),\n }}\n >\n {contentNode}\n </BackofficeTopbarPortalContextProvider>\n </BackofficePermissionsProvider>\n </AdminShellLayout>\n </ToastProvider>\n );\n};\n\ntype LayoutWithPermissionsProps = {\n children: ReactNode;\n permissionsQuery: GraphQLTaggedNode;\n prepared: PreloadedQuery<OperationType>;\n authStatus?: {\n isLoggedIn?: boolean | null;\n me?: BackofficeViewerIdentity | null;\n } | null;\n activeGroupId?: string | null;\n};\n\nconst LayoutWithPermissions = ({\n children,\n permissionsQuery,\n prepared,\n authStatus,\n activeGroupId,\n}: LayoutWithPermissionsProps): JSX.Element => {\n const permissions = usePreloadedQuery(permissionsQuery, prepared);\n\n return (\n <BackofficeLayoutShell\n permissions={permissions}\n authStatus={authStatus}\n activeGroupId={activeGroupId}\n >\n {children}\n </BackofficeLayoutShell>\n );\n};\n\nexport const BackofficeLayoutPage = ({\n children,\n permissionsQuery,\n prepared,\n authStatus,\n activeGroupId,\n}: BackofficeLayoutPageProps): JSX.Element => {\n if (permissionsQuery != null && prepared != null) {\n return (\n <LayoutWithPermissions\n permissionsQuery={permissionsQuery}\n prepared={prepared}\n authStatus={authStatus}\n activeGroupId={activeGroupId}\n >\n {children}\n </LayoutWithPermissions>\n );\n }\n\n return (\n <BackofficeLayoutShell\n permissions={null}\n authStatus={authStatus}\n activeGroupId={activeGroupId}\n >\n {children}\n </BackofficeLayoutShell>\n );\n};\n\nexport default BackofficeLayoutPage;\n"],"mappings":"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"}
@@ -8,7 +8,7 @@ import { getBackofficePasswordResetPath as o } from "../router/backofficeAuthPat
8
8
  import { useCallback as s, useContext as c, useRef as l } from "react";
9
9
  import { jsx as u } from "react/jsx-runtime";
10
10
  import * as d from "react-relay";
11
- import { RoutingContext as f } from "@plumile/router";
11
+ import f from "@plumile/router/routing/RoutingContext.js";
12
12
  //#region src/pages/BackofficeLoginPage.tsx
13
13
  var { usePreloadedQuery: p } = d, m = ({ prepared: d }) => {
14
14
  let m = c(f), { auth: h, basePath: g } = n(), _ = a(), v = i(), y = r(), b = l(!1);
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeLoginPage.js","names":[],"sources":["../../../src/pages/BackofficeLoginPage.tsx"],"sourcesContent":["import { useCallback, useContext, useRef, type JSX } from 'react';\nimport * as ReactRelay from 'react-relay';\nimport type { PreloadedQuery } from 'react-relay';\nimport type { OperationType } from 'relay-runtime';\nimport { useRelayEnvironment } from '../relay/useRelayEnvironment.js';\nimport { RoutingContext } from '@plumile/router';\n\nimport type { OidcProviderKind } from '../modules/sharedSchemaTypes.js';\nimport { LoginFlow } from '../auth/login/LoginFlow.js';\nimport { synchronizeAuthStatusQuery } from '../auth/login/synchronizeAuthStatusQuery.js';\nimport { useBackofficeAuth } from '../hooks/useBackofficeAuth.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { useBackofficeAuthLoginConfig } from '../provider/useBackofficeLazyValue.js';\nimport { getBackofficePasswordResetPath } from '../router/backofficeAuthPaths.js';\n\nconst { usePreloadedQuery } = ReactRelay;\n\nexport type BackofficeLoginPageProps = {\n prepared: { query: PreloadedQuery<OperationType> };\n};\n\nexport const BackofficeLoginPage = ({\n prepared,\n}: BackofficeLoginPageProps): JSX.Element => {\n const routerContext = useContext(RoutingContext);\n const { auth: authConfig, basePath } = useBackofficeConfig();\n const auth = useBackofficeAuthLoginConfig();\n const authState = useBackofficeAuth();\n const relayEnvironment = useRelayEnvironment();\n const isPostLoginSyncInFlightRef = useRef(false);\n\n const data = usePreloadedQuery(auth.loginQuery, prepared.query);\n const oidcProviders =\n (data as { oidcProviders?: readonly OidcProviderKind[] }).oidcProviders ??\n [];\n\n const handleLoginSuccess = useCallback((): void => {\n if (isPostLoginSyncInFlightRef.current) {\n return;\n }\n\n isPostLoginSyncInFlightRef.current = true;\n const runPostLoginSync = async (): Promise<void> => {\n try {\n const sessionAuth = await authConfig.session.load();\n if (sessionAuth.authStatusQuery == null) {\n routerContext?.history.push({\n pathname: basePath,\n });\n return;\n }\n\n await authConfig.lifecycle?.onLoginSuccess?.();\n\n const isLoggedIn = await synchronizeAuthStatusQuery<OperationType>(\n relayEnvironment,\n sessionAuth.authStatusQuery,\n );\n if (!isLoggedIn) {\n return;\n }\n routerContext?.history.push({\n pathname: basePath,\n });\n } catch {\n // Keep user on login page if post-login auth sync fails.\n } finally {\n isPostLoginSyncInFlightRef.current = false;\n }\n };\n\n runPostLoginSync().catch(() => {});\n }, [\n authConfig.lifecycle,\n authConfig.session,\n basePath,\n relayEnvironment,\n routerContext?.history,\n ]);\n\n const handleForgotPassword = useCallback(() => {\n routerContext?.history.push({\n pathname: getBackofficePasswordResetPath(basePath),\n });\n }, [basePath, routerContext?.history]);\n\n return (\n <LoginFlow\n auth={authState}\n oidcProviders={oidcProviders}\n onLoginSuccess={handleLoginSuccess}\n onForgotPassword={handleForgotPassword}\n />\n );\n};\n\nexport default BackofficeLoginPage;\n"],"mappings":";;;;;;;;;;;;AAeA,IAAM,EAAE,mBAAA,MAAsB,GAMjB,KAAuB,EAClC,kBAC2C;CAC3C,IAAM,IAAgB,EAAW,EAAe,EAC1C,EAAE,MAAM,GAAY,gBAAa,GAAqB,EACtD,IAAO,GAA8B,EACrC,IAAY,GAAmB,EAC/B,IAAmB,GAAqB,EACxC,IAA6B,EAAO,GAAM;CAyDhD,OACE,kBAAC,GAAD;EACE,MAAM;EACS,eA1DN,EAAkB,EAAK,YAAY,EAAS,MAEtD,CAAyD,iBAC1D,EAAE;EAwDA,gBAtDuB,QAAwB;GAC7C,EAA2B,YAI/B,EAA2B,UAAU,KA8BrC,YA7BoD;IAClD,IAAI;KACF,IAAM,IAAc,MAAM,EAAW,QAAQ,MAAM;KACnD,IAAI,EAAY,mBAAmB,MAAM;MACvC,GAAe,QAAQ,KAAK,EAC1B,UAAU,GACX,CAAC;MACF;;KASF,IANA,MAAM,EAAW,WAAW,kBAAkB,EAM1C,CAAC,MAJoB,EACvB,GACA,EAAY,gBACb,EAEC;KAEF,GAAe,QAAQ,KAAK,EAC1B,UAAU,GACX,CAAC;YACI,WAEE;KACR,EAA2B,UAAU;;OAIvB,CAAC,YAAY,GAAG;KACjC;GACD,EAAW;GACX,EAAW;GACX;GACA;GACA,GAAe;GAChB,CAYmB;EAChB,kBAXyB,QAAkB;GAC7C,GAAe,QAAQ,KAAK,EAC1B,UAAU,EAA+B,EAAS,EACnD,CAAC;KACD,CAAC,GAAU,GAAe,QAAQ,CAOf;EAClB,CAAA"}
1
+ {"version":3,"file":"BackofficeLoginPage.js","names":[],"sources":["../../../src/pages/BackofficeLoginPage.tsx"],"sourcesContent":["import { useCallback, useContext, useRef, type JSX } from 'react';\nimport * as ReactRelay from 'react-relay';\nimport type { PreloadedQuery } from 'react-relay';\nimport type { OperationType } from 'relay-runtime';\nimport { useRelayEnvironment } from '../relay/useRelayEnvironment.js';\nimport RoutingContext from '@plumile/router/routing/RoutingContext.js';\n\nimport type { OidcProviderKind } from '../modules/sharedSchemaTypes.js';\nimport { LoginFlow } from '../auth/login/LoginFlow.js';\nimport { synchronizeAuthStatusQuery } from '../auth/login/synchronizeAuthStatusQuery.js';\nimport { useBackofficeAuth } from '../hooks/useBackofficeAuth.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { useBackofficeAuthLoginConfig } from '../provider/useBackofficeLazyValue.js';\nimport { getBackofficePasswordResetPath } from '../router/backofficeAuthPaths.js';\n\nconst { usePreloadedQuery } = ReactRelay;\n\nexport type BackofficeLoginPageProps = {\n prepared: { query: PreloadedQuery<OperationType> };\n};\n\nexport const BackofficeLoginPage = ({\n prepared,\n}: BackofficeLoginPageProps): JSX.Element => {\n const routerContext = useContext(RoutingContext);\n const { auth: authConfig, basePath } = useBackofficeConfig();\n const auth = useBackofficeAuthLoginConfig();\n const authState = useBackofficeAuth();\n const relayEnvironment = useRelayEnvironment();\n const isPostLoginSyncInFlightRef = useRef(false);\n\n const data = usePreloadedQuery(auth.loginQuery, prepared.query);\n const oidcProviders =\n (data as { oidcProviders?: readonly OidcProviderKind[] }).oidcProviders ??\n [];\n\n const handleLoginSuccess = useCallback((): void => {\n if (isPostLoginSyncInFlightRef.current) {\n return;\n }\n\n isPostLoginSyncInFlightRef.current = true;\n const runPostLoginSync = async (): Promise<void> => {\n try {\n const sessionAuth = await authConfig.session.load();\n if (sessionAuth.authStatusQuery == null) {\n routerContext?.history.push({\n pathname: basePath,\n });\n return;\n }\n\n await authConfig.lifecycle?.onLoginSuccess?.();\n\n const isLoggedIn = await synchronizeAuthStatusQuery<OperationType>(\n relayEnvironment,\n sessionAuth.authStatusQuery,\n );\n if (!isLoggedIn) {\n return;\n }\n routerContext?.history.push({\n pathname: basePath,\n });\n } catch {\n // Keep user on login page if post-login auth sync fails.\n } finally {\n isPostLoginSyncInFlightRef.current = false;\n }\n };\n\n runPostLoginSync().catch(() => {});\n }, [\n authConfig.lifecycle,\n authConfig.session,\n basePath,\n relayEnvironment,\n routerContext?.history,\n ]);\n\n const handleForgotPassword = useCallback(() => {\n routerContext?.history.push({\n pathname: getBackofficePasswordResetPath(basePath),\n });\n }, [basePath, routerContext?.history]);\n\n return (\n <LoginFlow\n auth={authState}\n oidcProviders={oidcProviders}\n onLoginSuccess={handleLoginSuccess}\n onForgotPassword={handleForgotPassword}\n />\n );\n};\n\nexport default BackofficeLoginPage;\n"],"mappings":";;;;;;;;;;;;AAeA,IAAM,EAAE,mBAAA,MAAsB,GAMjB,KAAuB,EAClC,kBAC2C;CAC3C,IAAM,IAAgB,EAAW,EAAe,EAC1C,EAAE,MAAM,GAAY,gBAAa,GAAqB,EACtD,IAAO,GAA8B,EACrC,IAAY,GAAmB,EAC/B,IAAmB,GAAqB,EACxC,IAA6B,EAAO,GAAM;CAyDhD,OACE,kBAAC,GAAD;EACE,MAAM;EACS,eA1DN,EAAkB,EAAK,YAAY,EAAS,MAEtD,CAAyD,iBAC1D,EAAE;EAwDA,gBAtDuB,QAAwB;GAC7C,EAA2B,YAI/B,EAA2B,UAAU,KA8BrC,YA7BoD;IAClD,IAAI;KACF,IAAM,IAAc,MAAM,EAAW,QAAQ,MAAM;KACnD,IAAI,EAAY,mBAAmB,MAAM;MACvC,GAAe,QAAQ,KAAK,EAC1B,UAAU,GACX,CAAC;MACF;;KASF,IANA,MAAM,EAAW,WAAW,kBAAkB,EAM1C,CAAC,MAJoB,EACvB,GACA,EAAY,gBACb,EAEC;KAEF,GAAe,QAAQ,KAAK,EAC1B,UAAU,GACX,CAAC;YACI,WAEE;KACR,EAA2B,UAAU;;OAIvB,CAAC,YAAY,GAAG;KACjC;GACD,EAAW;GACX,EAAW;GACX;GACA;GACA,GAAe;GAChB,CAYmB;EAChB,kBAXyB,QAAkB;GAC7C,GAAe,QAAQ,KAAK,EAC1B,UAAU,EAA+B,EAAS,EACnD,CAAC;KACD,CAAC,GAAU,GAAe,QAAQ,CAOf;EAClB,CAAA"}
@@ -7,7 +7,7 @@ import { getBackofficeLoginPath as o } from "../router/backofficeAuthPaths.js";
7
7
  import { useCallback as s, useContext as c } from "react";
8
8
  import { jsx as l } from "react/jsx-runtime";
9
9
  import * as u from "react-relay";
10
- import { RoutingContext as d } from "@plumile/router";
10
+ import d from "@plumile/router/routing/RoutingContext.js";
11
11
  //#region src/pages/BackofficePasswordResetCompletePage.tsx
12
12
  var { useMutation: f } = u, p = () => {
13
13
  let u = c(d), { basePath: p } = i(), m = a(), { t: h } = e(), [g] = f(m.completePasswordResetMutation);
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficePasswordResetCompletePage.js","names":[],"sources":["../../../src/pages/BackofficePasswordResetCompletePage.tsx"],"sourcesContent":["import { useCallback, useContext, type JSX } from 'react';\nimport * as ReactRelay from 'react-relay';\nimport type { MutationParameters } from 'relay-runtime';\nimport { RoutingContext } from '@plumile/router';\n\nimport { PasswordResetCompleteScreen } from '../auth/pages/PasswordResetCompleteScreen.js';\nimport {\n type MutationPayloadBase,\n requireField,\n resolveMutationOutcome,\n} from '../relay/mutationResult.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { useBackofficeAuthPasswordResetCompleteConfig } from '../provider/useBackofficeLazyValue.js';\nimport { getBackofficeLoginPath } from '../router/backofficeAuthPaths.js';\n\nconst { useMutation } = ReactRelay;\n\ntype CompletePasswordResetErrorReason =\n | 'INVALID_TOKEN'\n | 'TOKEN_EXPIRED'\n | 'PASSWORD_POLICY_VIOLATION'\n | 'INTERNAL_ERROR';\n\ntype CompletePasswordResetMutationPayload =\n MutationPayloadBase<CompletePasswordResetErrorReason> & {\n success?: boolean | null;\n };\n\nexport const BackofficePasswordResetCompletePage = (): JSX.Element => {\n const routerContext = useContext(RoutingContext);\n const { basePath } = useBackofficeConfig();\n const auth = useBackofficeAuthPasswordResetCompleteConfig();\n const { t } = useBackofficeReactTranslation();\n type CompletePasswordResetMutation = MutationParameters & {\n response: {\n completePasswordReset?: CompletePasswordResetMutationPayload | null;\n };\n variables: { input: { newPassword: string; token: string } };\n };\n const [commitReset] = useMutation<CompletePasswordResetMutation>(\n auth.completePasswordResetMutation,\n );\n\n const handleBackToLogin = useCallback(() => {\n routerContext?.history.push({ pathname: getBackofficeLoginPath(basePath) });\n }, [basePath, routerContext?.history]);\n\n const handleCompleteReset = useCallback(\n async (input: { newPassword: string; token: string }): Promise<boolean> => {\n const invalidMessage = t('auth.passwordResetComplete.errors.invalid');\n const defaultErrorMessage = invalidMessage;\n\n return new Promise((resolve, reject) => {\n commitReset({\n variables: {\n input,\n },\n onCompleted: (response) => {\n const outcome = resolveMutationOutcome(\n response.completePasswordReset ?? null,\n {\n defaultErrorMessage,\n mapReason: (reason) => {\n switch (reason) {\n case 'INVALID_TOKEN':\n return invalidMessage;\n case 'TOKEN_EXPIRED':\n return t('auth.passwordResetComplete.errors.expired');\n case 'PASSWORD_POLICY_VIOLATION':\n return t(\n 'auth.passwordResetComplete.errors.policyViolation',\n );\n case 'INTERNAL_ERROR':\n return invalidMessage;\n default:\n return null;\n }\n },\n },\n );\n if (!outcome.ok) {\n reject(new Error(outcome.message));\n return;\n }\n\n const successResult = requireField(\n outcome.payload.success ?? null,\n defaultErrorMessage,\n );\n if (!successResult.ok) {\n reject(new Error(successResult.message));\n return;\n }\n resolve(successResult.value);\n },\n onError: () => {\n reject(new Error(defaultErrorMessage));\n },\n });\n });\n },\n [commitReset, t],\n );\n\n return (\n <PasswordResetCompleteScreen\n onBackToLogin={handleBackToLogin}\n onCompletePasswordReset={handleCompleteReset}\n />\n );\n};\n\nexport default BackofficePasswordResetCompletePage;\n"],"mappings":";;;;;;;;;;;AAgBA,IAAM,EAAE,mBAAgB,GAaX,UAAyD;CACpE,IAAM,IAAgB,EAAW,EAAe,EAC1C,EAAE,gBAAa,GAAqB,EACpC,IAAO,GAA8C,EACrD,EAAE,SAAM,GAA+B,EAOvC,CAAC,KAAe,EACpB,EAAK,8BACN;CA+DD,OACE,kBAAC,GAAD;EACE,eA/DsB,QAAkB;GAC1C,GAAe,QAAQ,KAAK,EAAE,UAAU,EAAuB,EAAS,EAAE,CAAC;KAC1E,CAAC,GAAU,GAAe,QAAQ,CA6DlB;EACf,yBA5DwB,EAC1B,OAAO,MAAoE;GACzE,IAAM,IAAiB,EAAE,4CAA4C,EAC/D,IAAsB;GAE5B,OAAO,IAAI,SAAS,GAAS,MAAW;IACtC,EAAY;KACV,WAAW,EACT,UACD;KACD,cAAc,MAAa;MACzB,IAAM,IAAU,EACd,EAAS,yBAAyB,MAClC;OACE;OACA,YAAY,MAAW;QACrB,QAAQ,GAAR;SACE,KAAK,iBACH,OAAO;SACT,KAAK,iBACH,OAAO,EAAE,4CAA4C;SACvD,KAAK,6BACH,OAAO,EACL,oDACD;SACH,KAAK,kBACH,OAAO;SACT,SACE,OAAO;;;OAGd,CACF;MACD,IAAI,CAAC,EAAQ,IAAI;OACf,EAAW,MAAM,EAAQ,QAAQ,CAAC;OAClC;;MAGF,IAAM,IAAgB,EACpB,EAAQ,QAAQ,WAAW,MAC3B,EACD;MACD,IAAI,CAAC,EAAc,IAAI;OACrB,EAAW,MAAM,EAAc,QAAQ,CAAC;OACxC;;MAEF,EAAQ,EAAc,MAAM;;KAE9B,eAAe;MACb,EAAW,MAAM,EAAoB,CAAC;;KAEzC,CAAC;KACF;KAEJ,CAAC,GAAa,EAAE,CAMW;EACzB,CAAA"}
1
+ {"version":3,"file":"BackofficePasswordResetCompletePage.js","names":[],"sources":["../../../src/pages/BackofficePasswordResetCompletePage.tsx"],"sourcesContent":["import { useCallback, useContext, type JSX } from 'react';\nimport * as ReactRelay from 'react-relay';\nimport type { MutationParameters } from 'relay-runtime';\nimport RoutingContext from '@plumile/router/routing/RoutingContext.js';\n\nimport { PasswordResetCompleteScreen } from '../auth/pages/PasswordResetCompleteScreen.js';\nimport {\n type MutationPayloadBase,\n requireField,\n resolveMutationOutcome,\n} from '../relay/mutationResult.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { useBackofficeAuthPasswordResetCompleteConfig } from '../provider/useBackofficeLazyValue.js';\nimport { getBackofficeLoginPath } from '../router/backofficeAuthPaths.js';\n\nconst { useMutation } = ReactRelay;\n\ntype CompletePasswordResetErrorReason =\n | 'INVALID_TOKEN'\n | 'TOKEN_EXPIRED'\n | 'PASSWORD_POLICY_VIOLATION'\n | 'INTERNAL_ERROR';\n\ntype CompletePasswordResetMutationPayload =\n MutationPayloadBase<CompletePasswordResetErrorReason> & {\n success?: boolean | null;\n };\n\nexport const BackofficePasswordResetCompletePage = (): JSX.Element => {\n const routerContext = useContext(RoutingContext);\n const { basePath } = useBackofficeConfig();\n const auth = useBackofficeAuthPasswordResetCompleteConfig();\n const { t } = useBackofficeReactTranslation();\n type CompletePasswordResetMutation = MutationParameters & {\n response: {\n completePasswordReset?: CompletePasswordResetMutationPayload | null;\n };\n variables: { input: { newPassword: string; token: string } };\n };\n const [commitReset] = useMutation<CompletePasswordResetMutation>(\n auth.completePasswordResetMutation,\n );\n\n const handleBackToLogin = useCallback(() => {\n routerContext?.history.push({ pathname: getBackofficeLoginPath(basePath) });\n }, [basePath, routerContext?.history]);\n\n const handleCompleteReset = useCallback(\n async (input: { newPassword: string; token: string }): Promise<boolean> => {\n const invalidMessage = t('auth.passwordResetComplete.errors.invalid');\n const defaultErrorMessage = invalidMessage;\n\n return new Promise((resolve, reject) => {\n commitReset({\n variables: {\n input,\n },\n onCompleted: (response) => {\n const outcome = resolveMutationOutcome(\n response.completePasswordReset ?? null,\n {\n defaultErrorMessage,\n mapReason: (reason) => {\n switch (reason) {\n case 'INVALID_TOKEN':\n return invalidMessage;\n case 'TOKEN_EXPIRED':\n return t('auth.passwordResetComplete.errors.expired');\n case 'PASSWORD_POLICY_VIOLATION':\n return t(\n 'auth.passwordResetComplete.errors.policyViolation',\n );\n case 'INTERNAL_ERROR':\n return invalidMessage;\n default:\n return null;\n }\n },\n },\n );\n if (!outcome.ok) {\n reject(new Error(outcome.message));\n return;\n }\n\n const successResult = requireField(\n outcome.payload.success ?? null,\n defaultErrorMessage,\n );\n if (!successResult.ok) {\n reject(new Error(successResult.message));\n return;\n }\n resolve(successResult.value);\n },\n onError: () => {\n reject(new Error(defaultErrorMessage));\n },\n });\n });\n },\n [commitReset, t],\n );\n\n return (\n <PasswordResetCompleteScreen\n onBackToLogin={handleBackToLogin}\n onCompletePasswordReset={handleCompleteReset}\n />\n );\n};\n\nexport default BackofficePasswordResetCompletePage;\n"],"mappings":";;;;;;;;;;;AAgBA,IAAM,EAAE,mBAAgB,GAaX,UAAyD;CACpE,IAAM,IAAgB,EAAW,EAAe,EAC1C,EAAE,gBAAa,GAAqB,EACpC,IAAO,GAA8C,EACrD,EAAE,SAAM,GAA+B,EAOvC,CAAC,KAAe,EACpB,EAAK,8BACN;CA+DD,OACE,kBAAC,GAAD;EACE,eA/DsB,QAAkB;GAC1C,GAAe,QAAQ,KAAK,EAAE,UAAU,EAAuB,EAAS,EAAE,CAAC;KAC1E,CAAC,GAAU,GAAe,QAAQ,CA6DlB;EACf,yBA5DwB,EAC1B,OAAO,MAAoE;GACzE,IAAM,IAAiB,EAAE,4CAA4C,EAC/D,IAAsB;GAE5B,OAAO,IAAI,SAAS,GAAS,MAAW;IACtC,EAAY;KACV,WAAW,EACT,UACD;KACD,cAAc,MAAa;MACzB,IAAM,IAAU,EACd,EAAS,yBAAyB,MAClC;OACE;OACA,YAAY,MAAW;QACrB,QAAQ,GAAR;SACE,KAAK,iBACH,OAAO;SACT,KAAK,iBACH,OAAO,EAAE,4CAA4C;SACvD,KAAK,6BACH,OAAO,EACL,oDACD;SACH,KAAK,kBACH,OAAO;SACT,SACE,OAAO;;;OAGd,CACF;MACD,IAAI,CAAC,EAAQ,IAAI;OACf,EAAW,MAAM,EAAQ,QAAQ,CAAC;OAClC;;MAGF,IAAM,IAAgB,EACpB,EAAQ,QAAQ,WAAW,MAC3B,EACD;MACD,IAAI,CAAC,EAAc,IAAI;OACrB,EAAW,MAAM,EAAc,QAAQ,CAAC;OACxC;;MAEF,EAAQ,EAAc,MAAM;;KAE9B,eAAe;MACb,EAAW,MAAM,EAAoB,CAAC;;KAEzC,CAAC;KACF;KAEJ,CAAC,GAAa,EAAE,CAMW;EACzB,CAAA"}
@@ -7,7 +7,7 @@ import { getBackofficeLoginPath as o } from "../router/backofficeAuthPaths.js";
7
7
  import { useCallback as s, useContext as c } from "react";
8
8
  import { jsx as l } from "react/jsx-runtime";
9
9
  import * as u from "react-relay";
10
- import { RoutingContext as d } from "@plumile/router";
10
+ import d from "@plumile/router/routing/RoutingContext.js";
11
11
  //#region src/pages/BackofficeVerifyEmailPage.tsx
12
12
  var { useMutation: f } = u, p = () => {
13
13
  let u = c(d), { basePath: p } = i(), m = a(), { t: h } = e(), [g] = f(m.verifyEmailMutation);
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeVerifyEmailPage.js","names":[],"sources":["../../../src/pages/BackofficeVerifyEmailPage.tsx"],"sourcesContent":["import { useCallback, useContext, type JSX } from 'react';\nimport * as ReactRelay from 'react-relay';\nimport type { MutationParameters } from 'relay-runtime';\nimport { RoutingContext } from '@plumile/router';\n\nimport { VerifyEmailScreen } from '../auth/pages/VerifyEmailScreen.js';\nimport {\n type MutationPayloadBase,\n requireField,\n resolveMutationOutcome,\n} from '../relay/mutationResult.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { useBackofficeAuthVerifyEmailConfig } from '../provider/useBackofficeLazyValue.js';\nimport { getBackofficeLoginPath } from '../router/backofficeAuthPaths.js';\n\nconst { useMutation } = ReactRelay;\n\ntype VerifyEmailErrorReason =\n | 'INVALID_TOKEN'\n | 'TOKEN_EXPIRED'\n | 'ALREADY_VERIFIED'\n | 'INTERNAL_ERROR';\n\ntype VerifyEmailMutationPayload =\n MutationPayloadBase<VerifyEmailErrorReason> & {\n success?: boolean | null;\n };\n\nexport const BackofficeVerifyEmailPage = (): JSX.Element => {\n const routerContext = useContext(RoutingContext);\n const { basePath } = useBackofficeConfig();\n const auth = useBackofficeAuthVerifyEmailConfig();\n const { t } = useBackofficeReactTranslation();\n type VerifyEmailMutation = MutationParameters & {\n response: { verifyEmail?: VerifyEmailMutationPayload | null };\n variables: { input: { token: string } };\n };\n const [commitVerify] = useMutation<VerifyEmailMutation>(\n auth.verifyEmailMutation,\n );\n\n const handleBackToLogin = useCallback(() => {\n routerContext?.history.push({ pathname: getBackofficeLoginPath(basePath) });\n }, [basePath, routerContext?.history]);\n\n const handleVerifyEmail = useCallback(\n async (input: { token: string }): Promise<boolean> => {\n const invalidMessage = t('auth.verifyEmail.errors.invalid');\n const defaultErrorMessage = invalidMessage;\n\n return new Promise((resolve, reject) => {\n commitVerify({\n variables: {\n input,\n },\n onCompleted: (response) => {\n const outcome = resolveMutationOutcome(\n response.verifyEmail ?? null,\n {\n defaultErrorMessage,\n mapReason: (reason) => {\n switch (reason) {\n case 'INVALID_TOKEN':\n return invalidMessage;\n case 'TOKEN_EXPIRED':\n return t('auth.verifyEmail.errors.expired');\n case 'ALREADY_VERIFIED':\n return t('auth.verifyEmail.errors.alreadyVerified');\n case 'INTERNAL_ERROR':\n return invalidMessage;\n default:\n return null;\n }\n },\n },\n );\n if (!outcome.ok) {\n reject(new Error(outcome.message));\n return;\n }\n\n const successResult = requireField(\n outcome.payload.success ?? null,\n defaultErrorMessage,\n );\n if (!successResult.ok) {\n reject(new Error(successResult.message));\n return;\n }\n resolve(successResult.value);\n },\n onError: () => {\n reject(new Error(defaultErrorMessage));\n },\n });\n });\n },\n [commitVerify, t],\n );\n\n return (\n <VerifyEmailScreen\n onBackToLogin={handleBackToLogin}\n onVerifyEmail={handleVerifyEmail}\n />\n );\n};\n\nexport default BackofficeVerifyEmailPage;\n"],"mappings":";;;;;;;;;;;AAgBA,IAAM,EAAE,mBAAgB,GAaX,UAA+C;CAC1D,IAAM,IAAgB,EAAW,EAAe,EAC1C,EAAE,gBAAa,GAAqB,EACpC,IAAO,GAAoC,EAC3C,EAAE,SAAM,GAA+B,EAKvC,CAAC,KAAgB,EACrB,EAAK,oBACN;CA6DD,OACE,kBAAC,GAAD;EACE,eA7DsB,QAAkB;GAC1C,GAAe,QAAQ,KAAK,EAAE,UAAU,EAAuB,EAAS,EAAE,CAAC;KAC1E,CAAC,GAAU,GAAe,QAAQ,CA2DlB;EACf,eA1DsB,EACxB,OAAO,MAA+C;GACpD,IAAM,IAAiB,EAAE,kCAAkC,EACrD,IAAsB;GAE5B,OAAO,IAAI,SAAS,GAAS,MAAW;IACtC,EAAa;KACX,WAAW,EACT,UACD;KACD,cAAc,MAAa;MACzB,IAAM,IAAU,EACd,EAAS,eAAe,MACxB;OACE;OACA,YAAY,MAAW;QACrB,QAAQ,GAAR;SACE,KAAK,iBACH,OAAO;SACT,KAAK,iBACH,OAAO,EAAE,kCAAkC;SAC7C,KAAK,oBACH,OAAO,EAAE,0CAA0C;SACrD,KAAK,kBACH,OAAO;SACT,SACE,OAAO;;;OAGd,CACF;MACD,IAAI,CAAC,EAAQ,IAAI;OACf,EAAW,MAAM,EAAQ,QAAQ,CAAC;OAClC;;MAGF,IAAM,IAAgB,EACpB,EAAQ,QAAQ,WAAW,MAC3B,EACD;MACD,IAAI,CAAC,EAAc,IAAI;OACrB,EAAW,MAAM,EAAc,QAAQ,CAAC;OACxC;;MAEF,EAAQ,EAAc,MAAM;;KAE9B,eAAe;MACb,EAAW,MAAM,EAAoB,CAAC;;KAEzC,CAAC;KACF;KAEJ,CAAC,GAAc,EAAE,CAMA;EACf,CAAA"}
1
+ {"version":3,"file":"BackofficeVerifyEmailPage.js","names":[],"sources":["../../../src/pages/BackofficeVerifyEmailPage.tsx"],"sourcesContent":["import { useCallback, useContext, type JSX } from 'react';\nimport * as ReactRelay from 'react-relay';\nimport type { MutationParameters } from 'relay-runtime';\nimport RoutingContext from '@plumile/router/routing/RoutingContext.js';\n\nimport { VerifyEmailScreen } from '../auth/pages/VerifyEmailScreen.js';\nimport {\n type MutationPayloadBase,\n requireField,\n resolveMutationOutcome,\n} from '../relay/mutationResult.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { useBackofficeAuthVerifyEmailConfig } from '../provider/useBackofficeLazyValue.js';\nimport { getBackofficeLoginPath } from '../router/backofficeAuthPaths.js';\n\nconst { useMutation } = ReactRelay;\n\ntype VerifyEmailErrorReason =\n | 'INVALID_TOKEN'\n | 'TOKEN_EXPIRED'\n | 'ALREADY_VERIFIED'\n | 'INTERNAL_ERROR';\n\ntype VerifyEmailMutationPayload =\n MutationPayloadBase<VerifyEmailErrorReason> & {\n success?: boolean | null;\n };\n\nexport const BackofficeVerifyEmailPage = (): JSX.Element => {\n const routerContext = useContext(RoutingContext);\n const { basePath } = useBackofficeConfig();\n const auth = useBackofficeAuthVerifyEmailConfig();\n const { t } = useBackofficeReactTranslation();\n type VerifyEmailMutation = MutationParameters & {\n response: { verifyEmail?: VerifyEmailMutationPayload | null };\n variables: { input: { token: string } };\n };\n const [commitVerify] = useMutation<VerifyEmailMutation>(\n auth.verifyEmailMutation,\n );\n\n const handleBackToLogin = useCallback(() => {\n routerContext?.history.push({ pathname: getBackofficeLoginPath(basePath) });\n }, [basePath, routerContext?.history]);\n\n const handleVerifyEmail = useCallback(\n async (input: { token: string }): Promise<boolean> => {\n const invalidMessage = t('auth.verifyEmail.errors.invalid');\n const defaultErrorMessage = invalidMessage;\n\n return new Promise((resolve, reject) => {\n commitVerify({\n variables: {\n input,\n },\n onCompleted: (response) => {\n const outcome = resolveMutationOutcome(\n response.verifyEmail ?? null,\n {\n defaultErrorMessage,\n mapReason: (reason) => {\n switch (reason) {\n case 'INVALID_TOKEN':\n return invalidMessage;\n case 'TOKEN_EXPIRED':\n return t('auth.verifyEmail.errors.expired');\n case 'ALREADY_VERIFIED':\n return t('auth.verifyEmail.errors.alreadyVerified');\n case 'INTERNAL_ERROR':\n return invalidMessage;\n default:\n return null;\n }\n },\n },\n );\n if (!outcome.ok) {\n reject(new Error(outcome.message));\n return;\n }\n\n const successResult = requireField(\n outcome.payload.success ?? null,\n defaultErrorMessage,\n );\n if (!successResult.ok) {\n reject(new Error(successResult.message));\n return;\n }\n resolve(successResult.value);\n },\n onError: () => {\n reject(new Error(defaultErrorMessage));\n },\n });\n });\n },\n [commitVerify, t],\n );\n\n return (\n <VerifyEmailScreen\n onBackToLogin={handleBackToLogin}\n onVerifyEmail={handleVerifyEmail}\n />\n );\n};\n\nexport default BackofficeVerifyEmailPage;\n"],"mappings":";;;;;;;;;;;AAgBA,IAAM,EAAE,mBAAgB,GAaX,UAA+C;CAC1D,IAAM,IAAgB,EAAW,EAAe,EAC1C,EAAE,gBAAa,GAAqB,EACpC,IAAO,GAAoC,EAC3C,EAAE,SAAM,GAA+B,EAKvC,CAAC,KAAgB,EACrB,EAAK,oBACN;CA6DD,OACE,kBAAC,GAAD;EACE,eA7DsB,QAAkB;GAC1C,GAAe,QAAQ,KAAK,EAAE,UAAU,EAAuB,EAAS,EAAE,CAAC;KAC1E,CAAC,GAAU,GAAe,QAAQ,CA2DlB;EACf,eA1DsB,EACxB,OAAO,MAA+C;GACpD,IAAM,IAAiB,EAAE,kCAAkC,EACrD,IAAsB;GAE5B,OAAO,IAAI,SAAS,GAAS,MAAW;IACtC,EAAa;KACX,WAAW,EACT,UACD;KACD,cAAc,MAAa;MACzB,IAAM,IAAU,EACd,EAAS,eAAe,MACxB;OACE;OACA,YAAY,MAAW;QACrB,QAAQ,GAAR;SACE,KAAK,iBACH,OAAO;SACT,KAAK,iBACH,OAAO,EAAE,kCAAkC;SAC7C,KAAK,oBACH,OAAO,EAAE,0CAA0C;SACrD,KAAK,kBACH,OAAO;SACT,SACE,OAAO;;;OAGd,CACF;MACD,IAAI,CAAC,EAAQ,IAAI;OACf,EAAW,MAAM,EAAQ,QAAQ,CAAC;OAClC;;MAGF,IAAM,IAAgB,EACpB,EAAQ,QAAQ,WAAW,MAC3B,EACD;MACD,IAAI,CAAC,EAAc,IAAI;OACrB,EAAW,MAAM,EAAc,QAAQ,CAAC;OACxC;;MAEF,EAAQ,EAAc,MAAM;;KAE9B,eAAe;MACb,EAAW,MAAM,EAAoB,CAAC;;KAEzC,CAAC;KACF;KAEJ,CAAC,GAAc,EAAE,CAMA;EACf,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"backofficeDashboardPage.css.js","names":[],"sources":["../../../src/pages/backofficeDashboardPage.css.ts"],"sourcesContent":["import { sprinkles } from '@plumile/ui';\n\nexport const tileBody = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n});\n\nexport const loadingBody = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n color: 'textMuted',\n fontSize: 'sm',\n});\n\nexport const tileCount = sprinkles({\n fontSize: '3xl',\n fontWeight: 'bold',\n lineHeight: 1,\n});\n"],"mappings":""}
1
+ {"version":3,"file":"backofficeDashboardPage.css.js","names":[],"sources":["../../../src/pages/backofficeDashboardPage.css.ts"],"sourcesContent":["import { sprinkles } from '@plumile/ui/theme/sprinkles.css.js';\n\nexport const tileBody = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n});\n\nexport const loadingBody = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n color: 'textMuted',\n fontSize: 'sm',\n});\n\nexport const tileCount = sprinkles({\n fontSize: '3xl',\n fontWeight: 'bold',\n lineHeight: 1,\n});\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"backofficeEntityDetailPage.css.js","names":[],"sources":["../../../src/pages/backofficeEntityDetailPage.css.ts"],"sourcesContent":["import { style } from '@vanilla-extract/css';\nimport { sprinkles, vars } from '@plumile/ui';\n\nexport const headerActions = sprinkles({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: 2,\n flexWrap: 'wrap',\n minWidth: 0,\n});\n\nexport const headerActionGroup = sprinkles({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: 2,\n flexWrap: 'wrap',\n});\n\nexport const headerRelationGroup = style([\n sprinkles({\n display: 'flex',\n alignItems: 'center',\n }),\n {\n '@media': {\n 'screen and (min-width: 768px)': {\n paddingLeft: vars.spacing[2],\n borderLeft: `1px solid ${vars.colors.borderSubtle}`,\n },\n },\n },\n]);\n\nexport const headerBlock = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 3,\n});\n\nexport const headerMeta = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n flexWrap: 'wrap',\n});\n\nexport const headerMetaList = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n});\n"],"mappings":""}
1
+ {"version":3,"file":"backofficeEntityDetailPage.css.js","names":[],"sources":["../../../src/pages/backofficeEntityDetailPage.css.ts"],"sourcesContent":["import { style } from '@vanilla-extract/css';\nimport { sprinkles } from '@plumile/ui/theme/sprinkles.css.js';\nimport { vars } from '@plumile/ui/theme/themeContract.js';\n\nexport const headerActions = sprinkles({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: 2,\n flexWrap: 'wrap',\n minWidth: 0,\n});\n\nexport const headerActionGroup = sprinkles({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: 2,\n flexWrap: 'wrap',\n});\n\nexport const headerRelationGroup = style([\n sprinkles({\n display: 'flex',\n alignItems: 'center',\n }),\n {\n '@media': {\n 'screen and (min-width: 768px)': {\n paddingLeft: vars.spacing[2],\n borderLeft: `1px solid ${vars.colors.borderSubtle}`,\n },\n },\n },\n]);\n\nexport const headerBlock = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 3,\n});\n\nexport const headerMeta = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n flexWrap: 'wrap',\n});\n\nexport const headerMetaList = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n});\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"backofficeEntityListPage.css.js","names":[],"sources":["../../../src/pages/backofficeEntityListPage.css.ts"],"sourcesContent":["import { style } from '@vanilla-extract/css';\nimport { sprinkles } from '@plumile/ui';\n\nexport const headerActions = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n flexWrap: 'wrap',\n});\n\nexport const actionsColumnCell = style({\n justifyContent: 'flex-end',\n});\n\nexport const actionTrigger = style({\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '2rem',\n height: '2rem',\n flexShrink: 0,\n});\n"],"mappings":""}
1
+ {"version":3,"file":"backofficeEntityListPage.css.js","names":[],"sources":["../../../src/pages/backofficeEntityListPage.css.ts"],"sourcesContent":["import { style } from '@vanilla-extract/css';\nimport { sprinkles } from '@plumile/ui/theme/sprinkles.css.js';\n\nexport const headerActions = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n flexWrap: 'wrap',\n});\n\nexport const actionsColumnCell = style({\n justifyContent: 'flex-end',\n});\n\nexport const actionTrigger = style({\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '2rem',\n height: '2rem',\n flexShrink: 0,\n});\n"],"mappings":""}
@@ -1,22 +1,23 @@
1
1
  import { card as e, group as t, link as n } from "./dashboardMetricGroup.css.js";
2
- import { MetricCard as r, MetricTileGroup as i } from "@plumile/ui";
3
- import { Fragment as a, jsx as o } from "react/jsx-runtime";
4
- import { Link as s } from "@plumile/router";
2
+ import { Fragment as r, jsx as i } from "react/jsx-runtime";
3
+ import a from "@plumile/router/routing/Link.js";
4
+ import { MetricCard as o } from "@plumile/ui/components/dashboard/metric_card/MetricCard.js";
5
+ import { MetricTileGroup as s } from "@plumile/ui/components/dashboard/metric_tile_group/MetricTileGroup.js";
5
6
  //#region src/pages/dashboard/DashboardMetricGroup.tsx
6
- var c = ({ metrics: c, emptyState: l = null }) => c.length === 0 ? /* @__PURE__ */ o(a, { children: l }) : /* @__PURE__ */ o(i, {
7
+ var c = ({ metrics: c, emptyState: l = null }) => c.length === 0 ? /* @__PURE__ */ i(r, { children: l }) : /* @__PURE__ */ i(s, {
7
8
  className: t,
8
- children: c.map((t, i) => {
9
- let a = `${t.id}-${i}`, c = /* @__PURE__ */ o(r, {
9
+ children: c.map((t, r) => {
10
+ let s = `${t.id}-${r}`, c = /* @__PURE__ */ i(o, {
10
11
  className: e,
11
12
  label: t.label,
12
13
  value: t.value,
13
14
  hint: t.hint
14
- }, a);
15
- return t.href == null ? c : /* @__PURE__ */ o(s, {
15
+ }, s);
16
+ return t.href == null ? c : /* @__PURE__ */ i(a, {
16
17
  to: t.href,
17
18
  className: n,
18
19
  children: c
19
- }, a);
20
+ }, s);
20
21
  })
21
22
  });
22
23
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardMetricGroup.js","names":[],"sources":["../../../../src/pages/dashboard/DashboardMetricGroup.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\nimport { Link } from '@plumile/router';\nimport { MetricCard, MetricTileGroup } from '@plumile/ui';\n\nimport * as styles from './dashboardMetricGroup.css.js';\n\nexport type DashboardMetricItem = {\n id: string;\n label: ReactNode;\n value: ReactNode;\n hint?: ReactNode;\n href?: string;\n};\n\nexport type DashboardMetricGroupProps = {\n metrics: readonly DashboardMetricItem[];\n emptyState?: ReactNode;\n};\n\nexport const DashboardMetricGroup = ({\n metrics,\n emptyState = null,\n}: DashboardMetricGroupProps): JSX.Element => {\n if (metrics.length === 0) {\n return <>{emptyState}</>;\n }\n\n return (\n <MetricTileGroup className={styles.group}>\n {metrics.map((metric, index) => {\n const key = `${metric.id}-${index}`;\n const card = (\n <MetricCard\n key={key}\n className={styles.card}\n label={metric.label}\n value={metric.value}\n hint={metric.hint}\n />\n );\n\n if (metric.href == null) {\n return card;\n }\n\n return (\n <Link key={key} to={metric.href} className={styles.link}>\n {card}\n </Link>\n );\n })}\n </MetricTileGroup>\n );\n};\n"],"mappings":";;;;;AAmBA,IAAa,KAAwB,EACnC,YACA,gBAAa,WAET,EAAQ,WAAW,IACd,kBAAA,GAAA,EAAA,UAAG,GAAc,CAAA,GAIxB,kBAAC,GAAD;CAAiB,WAAW;WACzB,EAAQ,KAAK,GAAQ,MAAU;EAC9B,IAAM,IAAM,GAAG,EAAO,GAAG,GAAG,KACtB,IACJ,kBAAC,GAAD;GAEE,WAAW;GACX,OAAO,EAAO;GACd,OAAO,EAAO;GACd,MAAM,EAAO;GACb,EALK,EAKL;EAOJ,OAJI,EAAO,QAAQ,OACV,IAIP,kBAAC,GAAD;GAAgB,IAAI,EAAO;GAAM,WAAW;aACzC;GACI,EAFI,EAEJ;GAET;CACc,CAAA"}
1
+ {"version":3,"file":"DashboardMetricGroup.js","names":[],"sources":["../../../../src/pages/dashboard/DashboardMetricGroup.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\nimport Link from '@plumile/router/routing/Link.js';\nimport { MetricCard } from '@plumile/ui/components/dashboard/metric_card/MetricCard.js';\nimport { MetricTileGroup } from '@plumile/ui/components/dashboard/metric_tile_group/MetricTileGroup.js';\n\nimport * as styles from './dashboardMetricGroup.css.js';\n\nexport type DashboardMetricItem = {\n id: string;\n label: ReactNode;\n value: ReactNode;\n hint?: ReactNode;\n href?: string;\n};\n\nexport type DashboardMetricGroupProps = {\n metrics: readonly DashboardMetricItem[];\n emptyState?: ReactNode;\n};\n\nexport const DashboardMetricGroup = ({\n metrics,\n emptyState = null,\n}: DashboardMetricGroupProps): JSX.Element => {\n if (metrics.length === 0) {\n return <>{emptyState}</>;\n }\n\n return (\n <MetricTileGroup className={styles.group}>\n {metrics.map((metric, index) => {\n const key = `${metric.id}-${index}`;\n const card = (\n <MetricCard\n key={key}\n className={styles.card}\n label={metric.label}\n value={metric.value}\n hint={metric.hint}\n />\n );\n\n if (metric.href == null) {\n return card;\n }\n\n return (\n <Link key={key} to={metric.href} className={styles.link}>\n {card}\n </Link>\n );\n })}\n </MetricTileGroup>\n );\n};\n"],"mappings":";;;;;;AAoBA,IAAa,KAAwB,EACnC,YACA,gBAAa,WAET,EAAQ,WAAW,IACd,kBAAA,GAAA,EAAA,UAAG,GAAc,CAAA,GAIxB,kBAAC,GAAD;CAAiB,WAAW;WACzB,EAAQ,KAAK,GAAQ,MAAU;EAC9B,IAAM,IAAM,GAAG,EAAO,GAAG,GAAG,KACtB,IACJ,kBAAC,GAAD;GAEE,WAAW;GACX,OAAO,EAAO;GACd,OAAO,EAAO;GACd,MAAM,EAAO;GACb,EALK,EAKL;EAOJ,OAJI,EAAO,QAAQ,OACV,IAIP,kBAAC,GAAD;GAAgB,IAAI,EAAO;GAAM,WAAW;aACzC;GACI,EAFI,EAEJ;GAET;CACc,CAAA"}