@plumile/backoffice-react 0.1.200 → 0.1.205

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 (202) hide show
  1. package/README.md +4 -4
  2. package/lib/esm/auth/login/LoginFlow.js.map +1 -1
  3. package/lib/esm/auth/pages/AcceptInvitationScreen.js.map +1 -1
  4. package/lib/esm/auth/pages/PasswordResetCompleteScreen.js.map +1 -1
  5. package/lib/esm/auth/pages/PasswordResetRequestScreen.js.map +1 -1
  6. package/lib/esm/components/backoffice/actions/BackofficeEntityActionFormDialog.js.map +1 -1
  7. package/lib/esm/components/backoffice/detail/BackofficeEntitySummaryHeader.js +28 -28
  8. package/lib/esm/components/backoffice/detail/BackofficeEntitySummaryHeader.js.map +1 -1
  9. package/lib/esm/components/backoffice/layout/breadcrumb/buildBreadcrumbs.js.map +1 -1
  10. package/lib/esm/components/backoffice/layout/sidebarUtils.js.map +1 -1
  11. package/lib/esm/components/backoffice/pickers/EntityIdPickerDialog.js +1 -1
  12. package/lib/esm/components/backoffice/pickers/EntityIdPickerDialog.js.map +1 -1
  13. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js +183 -183
  14. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js.map +1 -1
  15. package/lib/esm/hooks/useAuth.js +56 -56
  16. package/lib/esm/hooks/useAuth.js.map +1 -1
  17. package/lib/esm/hooks/useConditionalSubscription.js +18 -18
  18. package/lib/esm/hooks/useConditionalSubscription.js.map +1 -1
  19. package/lib/esm/index.js +49 -57
  20. package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js +1 -1
  21. package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js.map +1 -1
  22. package/lib/esm/pages/BackofficeEntityDetailPage.helpers.js.map +1 -1
  23. package/lib/esm/pages/BackofficeEntityDetailPage.js +172 -172
  24. package/lib/esm/pages/BackofficeEntityDetailPage.js.map +1 -1
  25. package/lib/esm/pages/BackofficeEntityListDataPage.js +1 -1
  26. package/lib/esm/pages/BackofficeEntityListDataPage.js.map +1 -1
  27. package/lib/esm/pages/BackofficeEntityListPage.helpers.js.map +1 -1
  28. package/lib/esm/pages/BackofficeLayoutPage.js +19 -19
  29. package/lib/esm/pages/BackofficeLayoutPage.js.map +1 -1
  30. package/lib/esm/provider/BackofficeProvider.js +33 -33
  31. package/lib/esm/provider/entityRegistry.js +39 -36
  32. package/lib/esm/provider/entityRegistry.js.map +1 -1
  33. package/lib/esm/provider/useBackofficeAuthRouteGate.js +7 -7
  34. package/lib/esm/provider/useBackofficeAuthRouteGate.js.map +1 -1
  35. package/lib/esm/relay/createInlineReader.js.map +1 -1
  36. package/lib/esm/relay/typedRelayHooks.js +11 -2
  37. package/lib/esm/relay/typedRelayHooks.js.map +1 -1
  38. package/lib/esm/router/createBackofficeRoutes.js +26 -28
  39. package/lib/esm/router/createBackofficeRoutes.js.map +1 -1
  40. package/lib/esm/storybook/relay/RelayStory.js +32 -32
  41. package/lib/esm/storybook/relay/RelayStory.js.map +1 -1
  42. package/lib/esm/storybook/relay/mockResolvers.js.map +1 -1
  43. package/lib/esm/style.css +1 -1
  44. package/lib/types/components/backoffice/actions/BackofficeEntityActionFormDialog.d.ts +2 -2
  45. package/lib/types/components/backoffice/actions/BackofficeEntityActionFormDialog.d.ts.map +1 -1
  46. package/lib/types/components/backoffice/detail/BackofficeEntitySummaryHeader.d.ts +1 -1
  47. package/lib/types/components/backoffice/detail/BackofficeEntitySummaryHeader.d.ts.map +1 -1
  48. package/lib/types/components/backoffice/layout/sidebarUtils.d.ts.map +1 -1
  49. package/lib/types/components/backoffice/pickers/EntityIdPickerDialog.d.ts.map +1 -1
  50. package/lib/types/hooks/useAuth.d.ts.map +1 -1
  51. package/lib/types/hooks/useConditionalSubscription.d.ts.map +1 -1
  52. package/lib/types/i18n/locales/en/backofficeReact.d.ts +5 -0
  53. package/lib/types/i18n/locales/fr/backofficeReact.d.ts +5 -0
  54. package/lib/types/index.d.ts +2 -9
  55. package/lib/types/index.d.ts.map +1 -1
  56. package/lib/types/pages/BackofficeEntityDetailPage.d.ts.map +1 -1
  57. package/lib/types/pages/BackofficeEntityDetailPage.helpers.d.ts +3 -3
  58. package/lib/types/pages/BackofficeEntityDetailPage.helpers.d.ts.map +1 -1
  59. package/lib/types/pages/BackofficeEntityListPage.helpers.d.ts +2 -2
  60. package/lib/types/pages/BackofficeEntityListPage.helpers.d.ts.map +1 -1
  61. package/lib/types/pages/BackofficeLayoutPage.d.ts.map +1 -1
  62. package/lib/types/provider/entityRegistry.d.ts.map +1 -1
  63. package/lib/types/provider/types.d.ts +1 -1
  64. package/lib/types/provider/types.d.ts.map +1 -1
  65. package/lib/types/provider/useBackofficeAuthRouteGate.d.ts.map +1 -1
  66. package/lib/types/relay/createInlineReader.d.ts +4 -1
  67. package/lib/types/relay/createInlineReader.d.ts.map +1 -1
  68. package/lib/types/relay/typedRelayHooks.d.ts +15 -5
  69. package/lib/types/relay/typedRelayHooks.d.ts.map +1 -1
  70. package/lib/types/router/createBackofficeRoutes.d.ts +4 -4
  71. package/lib/types/router/createBackofficeRoutes.d.ts.map +1 -1
  72. package/lib/types/storybook/relay/RelayStory.d.ts +1 -1
  73. package/lib/types/storybook/relay/RelayStory.d.ts.map +1 -1
  74. package/lib/types/storybook/relay/mockResolvers.d.ts +9 -1
  75. package/lib/types/storybook/relay/mockResolvers.d.ts.map +1 -1
  76. package/package.json +12 -15
  77. package/lib/esm/_virtual/_rolldown/runtime.js +0 -7
  78. package/lib/esm/components/backoffice/detail/BackofficeDetailFlagTag.js +0 -13
  79. package/lib/esm/components/backoffice/detail/BackofficeDetailFlagTag.js.map +0 -1
  80. package/lib/esm/components/backoffice/detail/BackofficeDetailTaggedValue.js +0 -12
  81. package/lib/esm/components/backoffice/detail/BackofficeDetailTaggedValue.js.map +0 -1
  82. package/lib/esm/components/backoffice/detail/BackofficeEnumLabel.js +0 -16
  83. package/lib/esm/components/backoffice/detail/BackofficeEnumLabel.js.map +0 -1
  84. package/lib/esm/components/backoffice/detail/BackofficeReferenceValue.js +0 -17
  85. package/lib/esm/components/backoffice/detail/BackofficeReferenceValue.js.map +0 -1
  86. package/lib/esm/components/backoffice/detail/BackofficeStatusGroup.js +0 -8
  87. package/lib/esm/components/backoffice/detail/BackofficeStatusGroup.js.map +0 -1
  88. package/lib/esm/components/backoffice/detail/BackofficeStatusMetaBadge.js +0 -16
  89. package/lib/esm/components/backoffice/detail/BackofficeStatusMetaBadge.js.map +0 -1
  90. package/lib/esm/components/backoffice/detail/backofficeDetailRelationLink.css.js +0 -6
  91. package/lib/esm/components/backoffice/detail/backofficeDetailRelationLink.css.js.map +0 -1
  92. package/lib/esm/components/backoffice/refs/backofficeEntityIdRef.css.js +0 -6
  93. package/lib/esm/components/backoffice/refs/backofficeEntityIdRef.css.js.map +0 -1
  94. package/lib/esm/components/backoffice/routing/BackofficeRoutePendingBar.js +0 -12
  95. package/lib/esm/components/backoffice/routing/BackofficeRoutePendingBar.js.map +0 -1
  96. package/lib/esm/components/backoffice/routing/backofficeRoutePendingBar.css.js +0 -7
  97. package/lib/esm/components/backoffice/routing/backofficeRoutePendingBar.css.js.map +0 -1
  98. package/lib/esm/modules/base64.js +0 -21
  99. package/lib/esm/modules/base64.js.map +0 -1
  100. package/lib/esm/node_modules/@babel/runtime/helpers/arrayLikeToArray.js +0 -15
  101. package/lib/esm/node_modules/@babel/runtime/helpers/arrayLikeToArray.js.map +0 -1
  102. package/lib/esm/node_modules/@babel/runtime/helpers/arrayWithoutHoles.js +0 -15
  103. package/lib/esm/node_modules/@babel/runtime/helpers/arrayWithoutHoles.js.map +0 -1
  104. package/lib/esm/node_modules/@babel/runtime/helpers/defineProperty.js +0 -20
  105. package/lib/esm/node_modules/@babel/runtime/helpers/defineProperty.js.map +0 -1
  106. package/lib/esm/node_modules/@babel/runtime/helpers/interopRequireDefault.js +0 -13
  107. package/lib/esm/node_modules/@babel/runtime/helpers/interopRequireDefault.js.map +0 -1
  108. package/lib/esm/node_modules/@babel/runtime/helpers/iterableToArray.js +0 -13
  109. package/lib/esm/node_modules/@babel/runtime/helpers/iterableToArray.js.map +0 -1
  110. package/lib/esm/node_modules/@babel/runtime/helpers/nonIterableSpread.js +0 -13
  111. package/lib/esm/node_modules/@babel/runtime/helpers/nonIterableSpread.js.map +0 -1
  112. package/lib/esm/node_modules/@babel/runtime/helpers/objectSpread2.js +0 -33
  113. package/lib/esm/node_modules/@babel/runtime/helpers/objectSpread2.js.map +0 -1
  114. package/lib/esm/node_modules/@babel/runtime/helpers/objectWithoutPropertiesLoose.js +0 -19
  115. package/lib/esm/node_modules/@babel/runtime/helpers/objectWithoutPropertiesLoose.js.map +0 -1
  116. package/lib/esm/node_modules/@babel/runtime/helpers/toConsumableArray.js +0 -18
  117. package/lib/esm/node_modules/@babel/runtime/helpers/toConsumableArray.js.map +0 -1
  118. package/lib/esm/node_modules/@babel/runtime/helpers/toPrimitive.js +0 -22
  119. package/lib/esm/node_modules/@babel/runtime/helpers/toPrimitive.js.map +0 -1
  120. package/lib/esm/node_modules/@babel/runtime/helpers/toPropertyKey.js +0 -17
  121. package/lib/esm/node_modules/@babel/runtime/helpers/toPropertyKey.js.map +0 -1
  122. package/lib/esm/node_modules/@babel/runtime/helpers/typeof.js +0 -18
  123. package/lib/esm/node_modules/@babel/runtime/helpers/typeof.js.map +0 -1
  124. package/lib/esm/node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js +0 -19
  125. package/lib/esm/node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js.map +0 -1
  126. package/lib/esm/node_modules/fbjs/lib/areEqual.js +0 -42
  127. package/lib/esm/node_modules/fbjs/lib/areEqual.js.map +0 -1
  128. package/lib/esm/node_modules/invariant/browser.js +0 -30
  129. package/lib/esm/node_modules/invariant/browser.js.map +0 -1
  130. package/lib/esm/node_modules/relay-test-utils/index.js +0 -11
  131. package/lib/esm/node_modules/relay-test-utils/index.js.map +0 -1
  132. package/lib/esm/node_modules/relay-test-utils/lib/RelayMockPayloadGenerator.js +0 -288
  133. package/lib/esm/node_modules/relay-test-utils/lib/RelayMockPayloadGenerator.js.map +0 -1
  134. package/lib/esm/node_modules/relay-test-utils/lib/RelayModernMockEnvironment.js +0 -183
  135. package/lib/esm/node_modules/relay-test-utils/lib/RelayModernMockEnvironment.js.map +0 -1
  136. package/lib/esm/node_modules/relay-test-utils/lib/RelayResolverTestUtils.js +0 -19
  137. package/lib/esm/node_modules/relay-test-utils/lib/RelayResolverTestUtils.js.map +0 -1
  138. package/lib/esm/node_modules/relay-test-utils/lib/index.js +0 -21
  139. package/lib/esm/node_modules/relay-test-utils/lib/index.js.map +0 -1
  140. package/lib/esm/node_modules/relay-test-utils/lib/unwrapContainer.js +0 -16
  141. package/lib/esm/node_modules/relay-test-utils/lib/unwrapContainer.js.map +0 -1
  142. package/lib/esm/relay/RelayProvider.js +0 -2
  143. package/lib/esm/relay/envHelpers.js +0 -55
  144. package/lib/esm/relay/envHelpers.js.map +0 -1
  145. package/lib/esm/relay/environment.js +0 -2
  146. package/lib/esm/relay/shortAccessTokenEnvironment.js +0 -2
  147. package/lib/esm/relay/useRelayOperationActivity.js +0 -2
  148. package/lib/esm/storybook/relay/relay-test-utils.d.js +0 -0
  149. package/lib/types/auth/AuthFlows.stories.d.ts +0 -19
  150. package/lib/types/auth/AuthFlows.stories.d.ts.map +0 -1
  151. package/lib/types/components/backoffice/billing/BackofficeBillingUsageChart.stories.d.ts +0 -41
  152. package/lib/types/components/backoffice/billing/BackofficeBillingUsageChart.stories.d.ts.map +0 -1
  153. package/lib/types/components/backoffice/detail/BackofficeDetailFlagTag.d.ts +0 -11
  154. package/lib/types/components/backoffice/detail/BackofficeDetailFlagTag.d.ts.map +0 -1
  155. package/lib/types/components/backoffice/detail/BackofficeDetailPrimitives.stories.d.ts +0 -17
  156. package/lib/types/components/backoffice/detail/BackofficeDetailPrimitives.stories.d.ts.map +0 -1
  157. package/lib/types/components/backoffice/detail/BackofficeDetailTaggedValue.d.ts +0 -13
  158. package/lib/types/components/backoffice/detail/BackofficeDetailTaggedValue.d.ts.map +0 -1
  159. package/lib/types/components/backoffice/detail/BackofficeEnumLabel.d.ts +0 -9
  160. package/lib/types/components/backoffice/detail/BackofficeEnumLabel.d.ts.map +0 -1
  161. package/lib/types/components/backoffice/detail/BackofficeReferenceValue.d.ts +0 -10
  162. package/lib/types/components/backoffice/detail/BackofficeReferenceValue.d.ts.map +0 -1
  163. package/lib/types/components/backoffice/detail/BackofficeStatusGroup.d.ts +0 -8
  164. package/lib/types/components/backoffice/detail/BackofficeStatusGroup.d.ts.map +0 -1
  165. package/lib/types/components/backoffice/detail/BackofficeStatusMetaBadge.d.ts +0 -11
  166. package/lib/types/components/backoffice/detail/BackofficeStatusMetaBadge.d.ts.map +0 -1
  167. package/lib/types/components/backoffice/detail/backofficeDetailRelationLink.css.d.ts +0 -6
  168. package/lib/types/components/backoffice/detail/backofficeDetailRelationLink.css.d.ts.map +0 -1
  169. package/lib/types/components/backoffice/errors/BackofficeErrorBoundary.stories.d.ts +0 -12
  170. package/lib/types/components/backoffice/errors/BackofficeErrorBoundary.stories.d.ts.map +0 -1
  171. package/lib/types/components/backoffice/filters/EntityIdFilterField.stories.d.ts +0 -12
  172. package/lib/types/components/backoffice/filters/EntityIdFilterField.stories.d.ts.map +0 -1
  173. package/lib/types/components/backoffice/hub/BackofficeHubTemplate.stories.d.ts +0 -49
  174. package/lib/types/components/backoffice/hub/BackofficeHubTemplate.stories.d.ts.map +0 -1
  175. package/lib/types/components/backoffice/overview/BackofficeOverviewLayout.stories.d.ts +0 -11
  176. package/lib/types/components/backoffice/overview/BackofficeOverviewLayout.stories.d.ts.map +0 -1
  177. package/lib/types/components/backoffice/pickers/EntityIdPickerDialog.stories.d.ts +0 -12
  178. package/lib/types/components/backoffice/pickers/EntityIdPickerDialog.stories.d.ts.map +0 -1
  179. package/lib/types/components/backoffice/refs/backofficeEntityIdRef.css.d.ts +0 -2
  180. package/lib/types/components/backoffice/refs/backofficeEntityIdRef.css.d.ts.map +0 -1
  181. package/lib/types/components/backoffice/routing/BackofficeRoutePendingBar.d.ts +0 -4
  182. package/lib/types/components/backoffice/routing/BackofficeRoutePendingBar.d.ts.map +0 -1
  183. package/lib/types/components/backoffice/routing/backofficeRoutePendingBar.css.d.ts +0 -3
  184. package/lib/types/components/backoffice/routing/backofficeRoutePendingBar.css.d.ts.map +0 -1
  185. package/lib/types/components/backoffice/scaffolds/BackofficeTabbedDetailShell.stories.d.ts +0 -11
  186. package/lib/types/components/backoffice/scaffolds/BackofficeTabbedDetailShell.stories.d.ts.map +0 -1
  187. package/lib/types/components/backoffice/tools/BackofficeTools.stories.d.ts +0 -17
  188. package/lib/types/components/backoffice/tools/BackofficeTools.stories.d.ts.map +0 -1
  189. package/lib/types/modules/base64.d.ts +0 -3
  190. package/lib/types/modules/base64.d.ts.map +0 -1
  191. package/lib/types/pages/BackofficeDashboardPage.stories.d.ts +0 -9
  192. package/lib/types/pages/BackofficeDashboardPage.stories.d.ts.map +0 -1
  193. package/lib/types/relay/RelayProvider.d.ts +0 -2
  194. package/lib/types/relay/RelayProvider.d.ts.map +0 -1
  195. package/lib/types/relay/envHelpers.d.ts +0 -25
  196. package/lib/types/relay/envHelpers.d.ts.map +0 -1
  197. package/lib/types/relay/environment.d.ts +0 -2
  198. package/lib/types/relay/environment.d.ts.map +0 -1
  199. package/lib/types/relay/shortAccessTokenEnvironment.d.ts +0 -5
  200. package/lib/types/relay/shortAccessTokenEnvironment.d.ts.map +0 -1
  201. package/lib/types/relay/useRelayOperationActivity.d.ts +0 -2
  202. package/lib/types/relay/useRelayOperationActivity.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"buildBreadcrumbs.js","names":[],"sources":["../../../../../../src/components/backoffice/layout/breadcrumb/buildBreadcrumbs.ts"],"sourcesContent":["import type { TFunction } from 'i18next';\n\nimport type {\n BackofficeEntityManifestMap,\n BackofficeManifestToolId,\n BackofficeResolvedDetailLayoutFacetConfig,\n BackofficeResolvedDetailPageFacetConfig,\n BackofficeRuntimeResolvedListFacetConfig,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\n\nimport type { BackofficeTopbarBreadcrumbItem } from './types.js';\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nexport const resolveEntityTitleFromDetailHeader = <\n LayoutView extends object,\n>(input: {\n layoutView: LayoutView;\n detailHeader: BackofficeResolvedDetailLayoutFacetConfig['header'];\n tApp: TFunction;\n}): string => {\n const titleValue = input.detailHeader.titleValue?.(\n input.layoutView,\n input.tApp,\n );\n const maybeId = (input.layoutView as { id?: unknown }).id;\n let normalizedId: string | null = null;\n if (typeof maybeId === 'string' && maybeId.trim() !== '') {\n normalizedId = maybeId.trim();\n }\n if (\n typeof titleValue === 'string' &&\n titleValue.trim() !== '' &&\n titleValue.trim() !== normalizedId\n ) {\n return titleValue;\n }\n\n const title = resolveLabel(input.detailHeader.title, input.tApp);\n if (title.trim() !== '') {\n return title;\n }\n\n return '';\n};\n\nexport const buildDashboardBreadcrumb = (\n t: TFunction,\n): readonly BackofficeTopbarBreadcrumbItem[] => {\n return [\n {\n kind: 'current',\n target: { kind: 'dashboard' },\n label: t('sidebar.items.dashboard'),\n },\n ];\n};\n\nexport const buildHubBreadcrumb = <\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n>(input: {\n id: string;\n title: string;\n}): readonly BackofficeTopbarBreadcrumbItem<TManifest>[] => {\n return [\n {\n kind: 'current',\n target: { kind: 'hub', hubId: input.id },\n label: input.title,\n },\n ];\n};\n\nexport const buildEntityListBreadcrumb = (\n config: BackofficeRuntimeResolvedListFacetConfig,\n tApp: TFunction,\n): readonly BackofficeTopbarBreadcrumbItem[] => {\n return [\n {\n kind: 'current',\n target: {\n kind: 'entity-list',\n entityId: config.id,\n },\n label: resolveLabel(config.label, tApp),\n },\n ];\n};\n\nexport const buildEntityDetailBreadcrumb = (input: {\n config:\n | BackofficeResolvedDetailLayoutFacetConfig\n | BackofficeResolvedDetailPageFacetConfig;\n tApp: TFunction;\n entityId: string;\n layoutView: unknown;\n pageLabel: string;\n pageId?: string;\n}): readonly BackofficeTopbarBreadcrumbItem[] => {\n const listLabel = resolveLabel(input.config.label, input.tApp);\n const entityTitle = resolveEntityTitleFromDetailHeader({\n layoutView: input.layoutView as object,\n detailHeader: input.config.header,\n tApp: input.tApp,\n });\n const currentTarget = {\n kind: 'entity-detail-page',\n entityId: input.config.id,\n id: input.entityId,\n pageId: input.pageId ?? input.pageLabel,\n } as unknown as BackofficeTopbarBreadcrumbItem['target'];\n\n return [\n {\n kind: 'link',\n target: {\n kind: 'entity-list',\n entityId: input.config.id,\n },\n label: listLabel,\n },\n {\n kind: 'link',\n target: {\n kind: 'entity-detail',\n entityId: input.config.id,\n id: input.entityId,\n },\n label: entityTitle,\n },\n {\n kind: 'current',\n target: currentTarget,\n label: input.pageLabel,\n },\n ];\n};\n\nexport const buildToolBreadcrumb = <\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n>(input: {\n id?: BackofficeManifestToolId<TManifest> | string;\n title: string;\n}): readonly BackofficeTopbarBreadcrumbItem<TManifest>[] => {\n let target: BackofficeTopbarBreadcrumbItem<TManifest>['target'] = {\n kind: 'href',\n href: `/tools/${input.title}`,\n };\n if (input.id != null) {\n target = {\n kind: 'tool',\n toolId: input.id as BackofficeManifestToolId<TManifest>,\n };\n }\n return [\n {\n kind: 'current',\n target,\n label: input.title,\n },\n ];\n};\n"],"mappings":";AAaA,IAAM,KAAgB,GAAkB,MAC/B,EAAM,CAAI,GAGN,KAEX,MAIY;CACZ,IAAM,IAAa,EAAM,aAAa,aACpC,EAAM,YACN,EAAM,IACR,GACM,IAAW,EAAM,WAAgC,IACnD,IAA8B;CAIlC,IAHI,OAAO,KAAY,YAAY,EAAQ,KAAK,MAAM,OACpD,IAAe,EAAQ,KAAK,IAG5B,OAAO,KAAe,YACtB,EAAW,KAAK,MAAM,MACtB,EAAW,KAAK,MAAM,GAEtB,OAAO;CAGT,IAAM,IAAQ,EAAa,EAAM,aAAa,OAAO,EAAM,IAAI;CAK/D,OAJI,EAAM,KAAK,MAAM,KAId,KAHE;AAIX,GAEa,KACX,MAEO,CACL;CACE,MAAM;CACN,QAAQ,EAAE,MAAM,YAAY;CAC5B,OAAO,EAAE,yBAAyB;AACpC,CACF,GAGW,KAEX,MAIO,CACL;CACE,MAAM;CACN,QAAQ;EAAE,MAAM;EAAO,OAAO,EAAM;CAAG;CACvC,OAAO,EAAM;AACf,CACF,GAGW,KACX,GACA,MAEO,CACL;CACE,MAAM;CACN,QAAQ;EACN,MAAM;EACN,UAAU,EAAO;CACnB;CACA,OAAO,EAAa,EAAO,OAAO,CAAI;AACxC,CACF,GAGW,KAA+B,MASK;CAC/C,IAAM,IAAY,EAAa,EAAM,OAAO,OAAO,EAAM,IAAI,GACvD,IAAc,EAAmC;EACrD,YAAY,EAAM;EAClB,cAAc,EAAM,OAAO;EAC3B,MAAM,EAAM;CACd,CAAC,GACK,IAAgB;EACpB,MAAM;EACN,UAAU,EAAM,OAAO;EACvB,IAAI,EAAM;EACV,QAAQ,EAAM,UAAU,EAAM;CAChC;CAEA,OAAO;EACL;GACE,MAAM;GACN,QAAQ;IACN,MAAM;IACN,UAAU,EAAM,OAAO;GACzB;GACA,OAAO;EACT;EACA;GACE,MAAM;GACN,QAAQ;IACN,MAAM;IACN,UAAU,EAAM,OAAO;IACvB,IAAI,EAAM;GACZ;GACA,OAAO;EACT;EACA;GACE,MAAM;GACN,QAAQ;GACR,OAAO,EAAM;EACf;CACF;AACF,GAEa,KAEX,MAG0D;CAC1D,IAAI,IAA8D;EAChE,MAAM;EACN,MAAM,UAAU,EAAM;CACxB;CAOA,OANI,EAAM,MAAM,SACd,IAAS;EACP,MAAM;EACN,QAAQ,EAAM;CAChB,IAEK,CACL;EACE,MAAM;EACN;EACA,OAAO,EAAM;CACf,CACF;AACF"}
1
+ {"version":3,"file":"buildBreadcrumbs.js","names":[],"sources":["../../../../../../src/components/backoffice/layout/breadcrumb/buildBreadcrumbs.ts"],"sourcesContent":["import type { TFunction } from 'i18next';\n\nimport type {\n BackofficeEntityManifestMap,\n BackofficeManifestToolId,\n BackofficeResolvedDetailLayoutFacetConfig,\n BackofficeResolvedDetailPageFacetConfig,\n BackofficeRuntimeResolvedListFacetConfig,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\n\nimport type { BackofficeTopbarBreadcrumbItem } from './types.js';\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nexport const resolveEntityTitleFromDetailHeader = <\n LayoutView extends object,\n>(input: {\n layoutView: LayoutView;\n detailHeader: BackofficeResolvedDetailLayoutFacetConfig['header'];\n tApp: TFunction;\n}): string => {\n const titleValue = input.detailHeader.titleValue?.(\n input.layoutView,\n input.tApp,\n );\n const maybeId = (input.layoutView as { id?: unknown }).id;\n let normalizedId: string | null = null;\n if (typeof maybeId === 'string' && maybeId.trim() !== '') {\n normalizedId = maybeId.trim();\n }\n if (\n typeof titleValue === 'string' &&\n titleValue.trim() !== '' &&\n titleValue.trim() !== normalizedId\n ) {\n return titleValue;\n }\n\n const title = resolveLabel(input.detailHeader.title, input.tApp);\n if (title.trim() !== '') {\n return title;\n }\n\n return '';\n};\n\nexport const buildDashboardBreadcrumb = (\n t: TFunction,\n): readonly BackofficeTopbarBreadcrumbItem[] => {\n return [\n {\n kind: 'current',\n target: { kind: 'dashboard' },\n label: t('sidebar.items.dashboard'),\n },\n ];\n};\n\nexport const buildHubBreadcrumb = <\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n>(input: {\n id: string;\n title: string;\n}): readonly BackofficeTopbarBreadcrumbItem<TManifest>[] => {\n return [\n {\n kind: 'current',\n target: { kind: 'hub', hubId: input.id },\n label: input.title,\n },\n ];\n};\n\nexport const buildEntityListBreadcrumb = (\n config: BackofficeRuntimeResolvedListFacetConfig,\n tApp: TFunction,\n): readonly BackofficeTopbarBreadcrumbItem[] => {\n return [\n {\n kind: 'current',\n target: {\n kind: 'entity-list',\n entityId: config.id,\n },\n label: resolveLabel(config.label, tApp),\n },\n ];\n};\n\nexport const buildEntityDetailBreadcrumb = (input: {\n config:\n | BackofficeResolvedDetailLayoutFacetConfig\n | BackofficeResolvedDetailPageFacetConfig;\n tApp: TFunction;\n entityId: string;\n layoutView: unknown;\n pageLabel: string;\n pageId?: string;\n}): readonly BackofficeTopbarBreadcrumbItem[] => {\n const listLabel = resolveLabel(input.config.label, input.tApp);\n const entityTitle = resolveEntityTitleFromDetailHeader({\n layoutView: input.layoutView as object,\n detailHeader: input.config.header,\n tApp: input.tApp,\n });\n const currentTarget: BackofficeTopbarBreadcrumbItem['target'] = {\n kind: 'entity-detail-page',\n entityId: input.config.id,\n id: input.entityId,\n pageId: input.pageId ?? input.pageLabel,\n };\n\n return [\n {\n kind: 'link',\n target: {\n kind: 'entity-list',\n entityId: input.config.id,\n },\n label: listLabel,\n },\n {\n kind: 'link',\n target: {\n kind: 'entity-detail',\n entityId: input.config.id,\n id: input.entityId,\n },\n label: entityTitle,\n },\n {\n kind: 'current',\n target: currentTarget,\n label: input.pageLabel,\n },\n ];\n};\n\nexport const buildToolBreadcrumb = <\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n>(input: {\n id?: BackofficeManifestToolId<TManifest> | string;\n title: string;\n}): readonly BackofficeTopbarBreadcrumbItem<TManifest>[] => {\n let target: BackofficeTopbarBreadcrumbItem<TManifest>['target'] = {\n kind: 'href',\n href: `/tools/${input.title}`,\n };\n if (input.id != null) {\n target = {\n kind: 'tool',\n toolId: input.id as BackofficeManifestToolId<TManifest>,\n };\n }\n return [\n {\n kind: 'current',\n target,\n label: input.title,\n },\n ];\n};\n"],"mappings":";AAaA,IAAM,KAAgB,GAAkB,MAC/B,EAAM,CAAI,GAGN,KAEX,MAIY;CACZ,IAAM,IAAa,EAAM,aAAa,aACpC,EAAM,YACN,EAAM,IACR,GACM,IAAW,EAAM,WAAgC,IACnD,IAA8B;CAIlC,IAHI,OAAO,KAAY,YAAY,EAAQ,KAAK,MAAM,OACpD,IAAe,EAAQ,KAAK,IAG5B,OAAO,KAAe,YACtB,EAAW,KAAK,MAAM,MACtB,EAAW,KAAK,MAAM,GAEtB,OAAO;CAGT,IAAM,IAAQ,EAAa,EAAM,aAAa,OAAO,EAAM,IAAI;CAK/D,OAJI,EAAM,KAAK,MAAM,KAId,KAHE;AAIX,GAEa,KACX,MAEO,CACL;CACE,MAAM;CACN,QAAQ,EAAE,MAAM,YAAY;CAC5B,OAAO,EAAE,yBAAyB;AACpC,CACF,GAGW,KAEX,MAIO,CACL;CACE,MAAM;CACN,QAAQ;EAAE,MAAM;EAAO,OAAO,EAAM;CAAG;CACvC,OAAO,EAAM;AACf,CACF,GAGW,KACX,GACA,MAEO,CACL;CACE,MAAM;CACN,QAAQ;EACN,MAAM;EACN,UAAU,EAAO;CACnB;CACA,OAAO,EAAa,EAAO,OAAO,CAAI;AACxC,CACF,GAGW,KAA+B,MASK;CAC/C,IAAM,IAAY,EAAa,EAAM,OAAO,OAAO,EAAM,IAAI,GACvD,IAAc,EAAmC;EACrD,YAAY,EAAM;EAClB,cAAc,EAAM,OAAO;EAC3B,MAAM,EAAM;CACd,CAAC,GACK,IAA0D;EAC9D,MAAM;EACN,UAAU,EAAM,OAAO;EACvB,IAAI,EAAM;EACV,QAAQ,EAAM,UAAU,EAAM;CAChC;CAEA,OAAO;EACL;GACE,MAAM;GACN,QAAQ;IACN,MAAM;IACN,UAAU,EAAM,OAAO;GACzB;GACA,OAAO;EACT;EACA;GACE,MAAM;GACN,QAAQ;IACN,MAAM;IACN,UAAU,EAAM,OAAO;IACvB,IAAI,EAAM;GACZ;GACA,OAAO;EACT;EACA;GACE,MAAM;GACN,QAAQ;GACR,OAAO,EAAM;EACf;CACF;AACF,GAEa,KAEX,MAG0D;CAC1D,IAAI,IAA8D;EAChE,MAAM;EACN,MAAM,UAAU,EAAM;CACxB;CAOA,OANI,EAAM,MAAM,SACd,IAAS;EACP,MAAM;EACN,QAAQ,EAAM;CAChB,IAEK,CACL;EACE,MAAM;EACN;EACA,OAAO,EAAM;CACf,CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"sidebarUtils.js","names":[],"sources":["../../../../../src/components/backoffice/layout/sidebarUtils.ts"],"sourcesContent":["import type { TFunction } from 'i18next';\n\nimport type {\n BackofficeEntityManifestMap,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport type {\n BackofficeSidebarConfig,\n BackofficeIconComponent,\n BackofficeSidebarGroupConfig,\n BackofficeSidebarItemDescriptor,\n BackofficeSidebarItemConfig,\n BackofficeSidebarHubConfig,\n BackofficeSidebarHubGroupConfig,\n BackofficeResolvedSidebarHubConfig,\n} from '../../../provider/types.js';\n\nexport const resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nexport const isActivePath = (pathname: string, href: string): boolean => {\n if (pathname === href) {\n return true;\n }\n if (href !== '/' && pathname.startsWith(`${href}/`)) {\n return true;\n }\n return false;\n};\n\nexport const joinBackofficePath = (\n basePath: string,\n pathSegment: string,\n): string => {\n const normalizedBasePath = basePath.replace(/\\/+$/g, '');\n const normalizedPathSegment = pathSegment.replace(/^\\/+/g, '');\n if (normalizedBasePath === '') {\n return `/${normalizedPathSegment}`;\n }\n return `${normalizedBasePath}/${normalizedPathSegment}`;\n};\n\nexport const buildDefaultGroups = (\n entities: BackofficeEntityManifestMap,\n): Record<string, BackofficeSidebarGroupConfig> => {\n const entityIds = Object.keys(entities);\n\n return {\n main: {\n entities: entityIds,\n },\n };\n};\n\nexport const resolveSidebarGroups = (\n entities: BackofficeEntityManifestMap,\n sidebar: BackofficeSidebarConfig | undefined,\n): Record<string, BackofficeSidebarGroupConfig> => {\n return sidebar?.groups ?? buildDefaultGroups(entities);\n};\n\nexport type EntityGroupLookup = Map<\n string,\n {\n groupId: string;\n groupIcon?: BackofficeIconComponent;\n itemIcon?: BackofficeIconComponent;\n }\n>;\n\nexport const resolveItemDescriptor = (\n item: BackofficeSidebarItemConfig,\n): BackofficeSidebarItemDescriptor => {\n if (item.kind === 'dashboard') {\n return { kind: 'dashboard', id: item.id ?? 'dashboard' };\n }\n return { kind: item.kind, id: item.id };\n};\n\nexport const resolveGroupItems = <\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n>(\n group: BackofficeSidebarGroupConfig<TManifest>,\n): readonly BackofficeSidebarItemConfig<TManifest>[] => {\n if (group.items != null) {\n return group.items;\n }\n return (group.entities?.map((entityId) => {\n return { kind: 'entity', id: entityId } as const;\n }) ?? []) as unknown as readonly BackofficeSidebarItemConfig<TManifest>[];\n};\n\nexport type BackofficeResolvedSidebarHubConfigFor<\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n> = BackofficeSidebarHubConfig<TManifest> & {\n groups: readonly BackofficeSidebarHubGroupConfig<TManifest>[];\n};\n\nexport const resolveSidebarHubFor = <\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n>(\n item: BackofficeSidebarHubConfig<TManifest>,\n sidebar: BackofficeSidebarConfig<TManifest> | undefined,\n): BackofficeResolvedSidebarHubConfigFor<TManifest> => {\n const registeredHub = sidebar?.hubs?.[item.id];\n return {\n ...registeredHub,\n ...item,\n groups: item.groups ?? registeredHub?.groups ?? [],\n };\n};\n\nexport const resolveSidebarHub = (\n item: BackofficeSidebarHubConfig,\n sidebar: BackofficeSidebarConfig | undefined,\n): BackofficeResolvedSidebarHubConfig => {\n return resolveSidebarHubFor(item, sidebar);\n};\n\nexport const resolveHubEntityIds = (\n hub: BackofficeResolvedSidebarHubConfig,\n): readonly string[] => {\n const output: string[] = [];\n const seen = new Set<string>();\n hub.groups.forEach((group) => {\n group.items.forEach((item) => {\n if (seen.has(item.id)) {\n return;\n }\n seen.add(item.id);\n output.push(item.id);\n });\n });\n return output;\n};\n\nexport type ResolvedSidebarHubEntry = {\n groupId: string | null;\n hub: BackofficeResolvedSidebarHubConfig;\n icon?: BackofficeIconComponent;\n};\n\nexport const resolveSidebarHubEntries = (\n groups: Record<string, BackofficeSidebarGroupConfig>,\n sidebar: BackofficeSidebarConfig | undefined,\n): readonly ResolvedSidebarHubEntry[] => {\n const output: ResolvedSidebarHubEntry[] = [];\n const seen = new Set<string>();\n\n Object.entries(groups).forEach(([groupId, group]) => {\n resolveGroupItems(group).forEach((item) => {\n if (item.kind !== 'hub' || seen.has(item.id)) {\n return;\n }\n seen.add(item.id);\n output.push({\n groupId,\n hub: resolveSidebarHub(item, sidebar),\n icon: item.icon ?? group.icon,\n });\n });\n });\n\n Object.values(sidebar?.hubs ?? {}).forEach((hub) => {\n if (seen.has(hub.id)) {\n return;\n }\n seen.add(hub.id);\n output.push({\n groupId: null,\n hub: resolveSidebarHub(hub, sidebar),\n icon: hub.icon,\n });\n });\n\n return output;\n};\n\nexport const resolveGroupEntityIds = (\n group: BackofficeSidebarGroupConfig,\n sidebar?: BackofficeSidebarConfig,\n): readonly string[] => {\n return resolveGroupItems(group).flatMap((item) => {\n if (item.kind === 'entity' || item.kind === 'tool') {\n return [item.id];\n }\n if (item.kind === 'hub') {\n return resolveHubEntityIds(resolveSidebarHub(item, sidebar));\n }\n return [];\n });\n};\n\nexport const buildEntityGroupLookup = (\n groups: Record<string, BackofficeSidebarGroupConfig>,\n sidebar?: BackofficeSidebarConfig,\n): EntityGroupLookup => {\n const lookup: EntityGroupLookup = new Map();\n\n Object.entries(groups).forEach(([groupId, group]) => {\n resolveGroupItems(group).forEach((item) => {\n if (item.kind === 'dashboard') {\n return;\n }\n\n if (item.kind === 'hub') {\n const hub = resolveSidebarHub(item, sidebar);\n resolveHubEntityIds(hub).forEach((entityId) => {\n if (!lookup.has(entityId)) {\n lookup.set(entityId, {\n groupId,\n groupIcon: group.icon,\n itemIcon: item.icon ?? hub.icon,\n });\n }\n });\n return;\n }\n\n if (!lookup.has(item.id)) {\n lookup.set(item.id, {\n groupId,\n groupIcon: group.icon,\n itemIcon: item.icon,\n });\n }\n });\n });\n\n return lookup;\n};\n\nconst isEntityVisible = (\n entityId: string,\n entities: BackofficeEntityManifestMap,\n sidebar: BackofficeSidebarConfig | undefined,\n permissions: unknown,\n): boolean => {\n const config = entities[entityId];\n if (config == null) {\n return false;\n }\n\n let descriptor: BackofficeSidebarItemDescriptor = {\n kind: 'entity',\n id: entityId,\n };\n if (config.kind === 'tool') {\n descriptor = { kind: 'tool', id: entityId };\n }\n\n if (sidebar?.isItemVisible != null) {\n return sidebar.isItemVisible(descriptor, permissions);\n }\n\n if (config.kind === 'tool') {\n return true;\n }\n return config.hasList;\n};\n\nexport const resolveVisibleEntityIds = (\n groups: Record<string, BackofficeSidebarGroupConfig>,\n entities: BackofficeEntityManifestMap,\n sidebar: BackofficeSidebarConfig | undefined,\n permissions: unknown,\n): string[] => {\n const output: string[] = [];\n const seen = new Set<string>();\n\n Object.entries(groups).forEach(([, group]) => {\n if (group.isVisible != null && !group.isVisible(permissions)) {\n return;\n }\n resolveGroupEntityIds(group, sidebar).forEach((entityId) => {\n if (seen.has(entityId)) {\n return;\n }\n if (!isEntityVisible(entityId, entities, sidebar, permissions)) {\n return;\n }\n seen.add(entityId);\n output.push(entityId);\n });\n });\n\n return output;\n};\n\nexport const resolveActiveEntityId = (\n pathname: string,\n entities: BackofficeEntityManifestMap,\n): string | null => {\n const entries = Object.entries(entities);\n for (const [entityId, config] of entries) {\n if (config.kind === 'tool') {\n if (isActivePath(pathname, config.routes.list)) {\n return entityId;\n }\n } else if (config.hasList && isActivePath(pathname, config.routes.list)) {\n return entityId;\n }\n }\n return null;\n};\n\nexport const resolveActiveGroupId = (\n groups: Record<string, BackofficeSidebarGroupConfig>,\n activeEntityId: string | null,\n entities: BackofficeEntityManifestMap,\n sidebar: BackofficeSidebarConfig | undefined,\n permissions: unknown,\n): string | null => {\n if (activeEntityId == null) {\n return null;\n }\n\n if (!isEntityVisible(activeEntityId, entities, sidebar, permissions)) {\n return null;\n }\n\n for (const [groupId, group] of Object.entries(groups)) {\n const isVisible = group.isVisible == null || group.isVisible(permissions);\n if (\n isVisible &&\n resolveGroupEntityIds(group, sidebar).includes(activeEntityId)\n ) {\n return groupId;\n }\n }\n\n return null;\n};\n"],"mappings":";AAiBA,IAAa,KAAgB,GAAkB,MACtC,EAAM,CAAI,GAGN,KAAgB,GAAkB,MAI7C,GAHI,MAAa,KAGb,MAAS,OAAO,EAAS,WAAW,GAAG,EAAK,EAAE,IAMvC,KACX,GACA,MACW;CACX,IAAM,IAAqB,EAAS,QAAQ,SAAS,EAAE,GACjD,IAAwB,EAAY,QAAQ,SAAS,EAAE;CAI7D,OAHI,MAAuB,KAClB,IAAI,MAEN,GAAG,EAAmB,GAAG;AAClC,GAEa,KACX,OAIO,EACL,MAAM,EACJ,UAJc,OAAO,KAAK,CAIhB,EACZ,EACF,IAGW,KACX,GACA,MAEO,GAAS,UAAU,EAAmB,CAAQ,GAY1C,KACX,MAEI,EAAK,SAAS,cACT;CAAE,MAAM;CAAa,IAAI,EAAK,MAAM;AAAY,IAElD;CAAE,MAAM,EAAK;CAAM,IAAI,EAAK;AAAG,GAG3B,KAGX,MAEI,EAAM,SAAS,OAGX,EAAM,UAAU,KAAK,OACpB;CAAE,MAAM;CAAU,IAAI;AAAS,EACvC,KAAK,CAAC,IAJE,EAAM,OAaJ,KAGX,GACA,MACqD;CACrD,IAAM,IAAgB,GAAS,OAAO,EAAK;CAC3C,OAAO;EACL,GAAG;EACH,GAAG;EACH,QAAQ,EAAK,UAAU,GAAe,UAAU,CAAC;CACnD;AACF,GAEa,KACX,GACA,MAEO,EAAqB,GAAM,CAAO,GAG9B,KACX,MACsB;CACtB,IAAM,IAAmB,CAAC,GACpB,oBAAO,IAAI,IAAY;CAU7B,OATA,EAAI,OAAO,SAAS,MAAU;EAC5B,EAAM,MAAM,SAAS,MAAS;GACxB,EAAK,IAAI,EAAK,EAAE,MAGpB,EAAK,IAAI,EAAK,EAAE,GAChB,EAAO,KAAK,EAAK,EAAE;EACrB,CAAC;CACH,CAAC,GACM;AACT,GAQa,KACX,GACA,MACuC;CACvC,IAAM,IAAoC,CAAC,GACrC,oBAAO,IAAI,IAAY;CA4B7B,OA1BA,OAAO,QAAQ,CAAM,CAAC,CAAC,SAAS,CAAC,GAAS,OAAW;EACnD,EAAkB,CAAK,CAAC,CAAC,SAAS,MAAS;GACrC,EAAK,SAAS,SAAS,EAAK,IAAI,EAAK,EAAE,MAG3C,EAAK,IAAI,EAAK,EAAE,GAChB,EAAO,KAAK;IACV;IACA,KAAK,EAAkB,GAAM,CAAO;IACpC,MAAM,EAAK,QAAQ,EAAM;GAC3B,CAAC;EACH,CAAC;CACH,CAAC,GAED,OAAO,OAAO,GAAS,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,MAAQ;EAC9C,EAAK,IAAI,EAAI,EAAE,MAGnB,EAAK,IAAI,EAAI,EAAE,GACf,EAAO,KAAK;GACV,SAAS;GACT,KAAK,EAAkB,GAAK,CAAO;GACnC,MAAM,EAAI;EACZ,CAAC;CACH,CAAC,GAEM;AACT,GAEa,KACX,GACA,MAEO,EAAkB,CAAK,CAAC,CAAC,SAAS,MACnC,EAAK,SAAS,YAAY,EAAK,SAAS,SACnC,CAAC,EAAK,EAAE,IAEb,EAAK,SAAS,QACT,EAAoB,EAAkB,GAAM,CAAO,CAAC,IAEtD,CAAC,CACT,GAGU,KACX,GACA,MACsB;CACtB,IAAM,oBAA4B,IAAI,IAAI;CAgC1C,OA9BA,OAAO,QAAQ,CAAM,CAAC,CAAC,SAAS,CAAC,GAAS,OAAW;EACnD,EAAkB,CAAK,CAAC,CAAC,SAAS,MAAS;GACrC,MAAK,SAAS,aAIlB;QAAI,EAAK,SAAS,OAAO;KACvB,IAAM,IAAM,EAAkB,GAAM,CAAO;KAC3C,EAAoB,CAAG,CAAC,CAAC,SAAS,MAAa;MAC7C,AAAK,EAAO,IAAI,CAAQ,KACtB,EAAO,IAAI,GAAU;OACnB;OACA,WAAW,EAAM;OACjB,UAAU,EAAK,QAAQ,EAAI;MAC7B,CAAC;KAEL,CAAC;KACD;IACF;IAEA,AAAK,EAAO,IAAI,EAAK,EAAE,KACrB,EAAO,IAAI,EAAK,IAAI;KAClB;KACA,WAAW,EAAM;KACjB,UAAU,EAAK;IACjB,CAAC;GAPH;EASF,CAAC;CACH,CAAC,GAEM;AACT,GAEM,KACJ,GACA,GACA,GACA,MACY;CACZ,IAAM,IAAS,EAAS;CACxB,IAAI,KAAU,MACZ,OAAO;CAGT,IAAI,IAA8C;EAChD,MAAM;EACN,IAAI;CACN;CAYA,OAXI,EAAO,SAAS,WAClB,IAAa;EAAE,MAAM;EAAQ,IAAI;CAAS,IAGxC,GAAS,iBAAiB,OAI1B,EAAO,SAAS,UAGb,EAAO,UANL,EAAQ,cAAc,GAAY,CAAW;AAOxD,GAEa,KACX,GACA,GACA,GACA,MACa;CACb,IAAM,IAAmB,CAAC,GACpB,oBAAO,IAAI,IAAY;CAkB7B,OAhBA,OAAO,QAAQ,CAAM,CAAC,CAAC,SAAS,GAAG,OAAW;EACxC,EAAM,aAAa,QAAQ,CAAC,EAAM,UAAU,CAAW,KAG3D,EAAsB,GAAO,CAAO,CAAC,CAAC,SAAS,MAAa;GACtD,EAAK,IAAI,CAAQ,KAGhB,EAAgB,GAAU,GAAU,GAAS,CAAW,MAG7D,EAAK,IAAI,CAAQ,GACjB,EAAO,KAAK,CAAQ;EACtB,CAAC;CACH,CAAC,GAEM;AACT,GAEa,KACX,GACA,MACkB;CAClB,IAAM,IAAU,OAAO,QAAQ,CAAQ;CACvC,KAAK,IAAM,CAAC,GAAU,MAAW,GAC/B,IAAI,EAAO,SAAS,QACd;MAAA,EAAa,GAAU,EAAO,OAAO,IAAI,GAC3C,OAAO;CAAA,OAEJ,IAAI,EAAO,WAAW,EAAa,GAAU,EAAO,OAAO,IAAI,GACpE,OAAO;CAGX,OAAO;AACT,GAEa,KACX,GACA,GACA,GACA,GACA,MACkB;CAKlB,IAJI,KAAkB,QAIlB,CAAC,EAAgB,GAAgB,GAAU,GAAS,CAAW,GACjE,OAAO;CAGT,KAAK,IAAM,CAAC,GAAS,MAAU,OAAO,QAAQ,CAAM,GAElD,KADkB,EAAM,aAAa,QAAQ,EAAM,UAAU,CAAW,MAGtE,EAAsB,GAAO,CAAO,CAAC,CAAC,SAAS,CAAc,GAE7D,OAAO;CAIX,OAAO;AACT"}
1
+ {"version":3,"file":"sidebarUtils.js","names":[],"sources":["../../../../../src/components/backoffice/layout/sidebarUtils.ts"],"sourcesContent":["import type { TFunction } from 'i18next';\n\nimport type {\n BackofficeEntityManifestMap,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport type {\n BackofficeSidebarConfig,\n BackofficeIconComponent,\n BackofficeSidebarGroupConfig,\n BackofficeSidebarItemDescriptor,\n BackofficeSidebarItemConfig,\n BackofficeSidebarHubConfig,\n BackofficeSidebarHubGroupConfig,\n BackofficeResolvedSidebarHubConfig,\n} from '../../../provider/types.js';\n\nexport const resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nexport const isActivePath = (pathname: string, href: string): boolean => {\n if (pathname === href) {\n return true;\n }\n if (href !== '/' && pathname.startsWith(`${href}/`)) {\n return true;\n }\n return false;\n};\n\nexport const joinBackofficePath = (\n basePath: string,\n pathSegment: string,\n): string => {\n const normalizedBasePath = basePath.replace(/\\/+$/g, '');\n const normalizedPathSegment = pathSegment.replace(/^\\/+/g, '');\n if (normalizedBasePath === '') {\n return `/${normalizedPathSegment}`;\n }\n return `${normalizedBasePath}/${normalizedPathSegment}`;\n};\n\nexport const buildDefaultGroups = (\n entities: BackofficeEntityManifestMap,\n): Record<string, BackofficeSidebarGroupConfig> => {\n const entityIds = Object.keys(entities);\n\n return {\n main: {\n entities: entityIds,\n },\n };\n};\n\nexport const resolveSidebarGroups = (\n entities: BackofficeEntityManifestMap,\n sidebar: BackofficeSidebarConfig | undefined,\n): Record<string, BackofficeSidebarGroupConfig> => {\n return sidebar?.groups ?? buildDefaultGroups(entities);\n};\n\nexport type EntityGroupLookup = Map<\n string,\n {\n groupId: string;\n groupIcon?: BackofficeIconComponent;\n itemIcon?: BackofficeIconComponent;\n }\n>;\n\nexport const resolveItemDescriptor = (\n item: BackofficeSidebarItemConfig,\n): BackofficeSidebarItemDescriptor => {\n if (item.kind === 'dashboard') {\n return { kind: 'dashboard', id: item.id ?? 'dashboard' };\n }\n return { kind: item.kind, id: item.id };\n};\n\nexport const resolveGroupItems = <\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n>(\n group: BackofficeSidebarGroupConfig<TManifest>,\n): readonly BackofficeSidebarItemConfig<TManifest>[] => {\n if (group.items != null) {\n return group.items;\n }\n return (\n group.entities?.map((entityId) => {\n return { kind: 'entity', id: entityId } as const;\n }) ?? []\n );\n};\n\nexport type BackofficeResolvedSidebarHubConfigFor<\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n> = BackofficeSidebarHubConfig<TManifest> & {\n groups: readonly BackofficeSidebarHubGroupConfig<TManifest>[];\n};\n\nexport const resolveSidebarHubFor = <\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n>(\n item: BackofficeSidebarHubConfig<TManifest>,\n sidebar: BackofficeSidebarConfig<TManifest> | undefined,\n): BackofficeResolvedSidebarHubConfigFor<TManifest> => {\n const registeredHub = sidebar?.hubs?.[item.id];\n return {\n ...registeredHub,\n ...item,\n groups: item.groups ?? registeredHub?.groups ?? [],\n };\n};\n\nexport const resolveSidebarHub = (\n item: BackofficeSidebarHubConfig,\n sidebar: BackofficeSidebarConfig | undefined,\n): BackofficeResolvedSidebarHubConfig => {\n return resolveSidebarHubFor(item, sidebar);\n};\n\nexport const resolveHubEntityIds = (\n hub: BackofficeResolvedSidebarHubConfig,\n): readonly string[] => {\n const output: string[] = [];\n const seen = new Set<string>();\n hub.groups.forEach((group) => {\n group.items.forEach((item) => {\n if (seen.has(item.id)) {\n return;\n }\n seen.add(item.id);\n output.push(item.id);\n });\n });\n return output;\n};\n\nexport type ResolvedSidebarHubEntry = {\n groupId: string | null;\n hub: BackofficeResolvedSidebarHubConfig;\n icon?: BackofficeIconComponent;\n};\n\nexport const resolveSidebarHubEntries = (\n groups: Record<string, BackofficeSidebarGroupConfig>,\n sidebar: BackofficeSidebarConfig | undefined,\n): readonly ResolvedSidebarHubEntry[] => {\n const output: ResolvedSidebarHubEntry[] = [];\n const seen = new Set<string>();\n\n Object.entries(groups).forEach(([groupId, group]) => {\n resolveGroupItems(group).forEach((item) => {\n if (item.kind !== 'hub' || seen.has(item.id)) {\n return;\n }\n seen.add(item.id);\n output.push({\n groupId,\n hub: resolveSidebarHub(item, sidebar),\n icon: item.icon ?? group.icon,\n });\n });\n });\n\n Object.values(sidebar?.hubs ?? {}).forEach((hub) => {\n if (seen.has(hub.id)) {\n return;\n }\n seen.add(hub.id);\n output.push({\n groupId: null,\n hub: resolveSidebarHub(hub, sidebar),\n icon: hub.icon,\n });\n });\n\n return output;\n};\n\nexport const resolveGroupEntityIds = (\n group: BackofficeSidebarGroupConfig,\n sidebar?: BackofficeSidebarConfig,\n): readonly string[] => {\n return resolveGroupItems(group).flatMap((item) => {\n if (item.kind === 'entity' || item.kind === 'tool') {\n return [item.id];\n }\n if (item.kind === 'hub') {\n return resolveHubEntityIds(resolveSidebarHub(item, sidebar));\n }\n return [];\n });\n};\n\nexport const buildEntityGroupLookup = (\n groups: Record<string, BackofficeSidebarGroupConfig>,\n sidebar?: BackofficeSidebarConfig,\n): EntityGroupLookup => {\n const lookup: EntityGroupLookup = new Map();\n\n Object.entries(groups).forEach(([groupId, group]) => {\n resolveGroupItems(group).forEach((item) => {\n if (item.kind === 'dashboard') {\n return;\n }\n\n if (item.kind === 'hub') {\n const hub = resolveSidebarHub(item, sidebar);\n resolveHubEntityIds(hub).forEach((entityId) => {\n if (!lookup.has(entityId)) {\n lookup.set(entityId, {\n groupId,\n groupIcon: group.icon,\n itemIcon: item.icon ?? hub.icon,\n });\n }\n });\n return;\n }\n\n if (!lookup.has(item.id)) {\n lookup.set(item.id, {\n groupId,\n groupIcon: group.icon,\n itemIcon: item.icon,\n });\n }\n });\n });\n\n return lookup;\n};\n\nconst isEntityVisible = (\n entityId: string,\n entities: BackofficeEntityManifestMap,\n sidebar: BackofficeSidebarConfig | undefined,\n permissions: unknown,\n): boolean => {\n const config = entities[entityId];\n if (config == null) {\n return false;\n }\n\n let descriptor: BackofficeSidebarItemDescriptor = {\n kind: 'entity',\n id: entityId,\n };\n if (config.kind === 'tool') {\n descriptor = { kind: 'tool', id: entityId };\n }\n\n if (sidebar?.isItemVisible != null) {\n return sidebar.isItemVisible(descriptor, permissions);\n }\n\n if (config.kind === 'tool') {\n return true;\n }\n return config.hasList;\n};\n\nexport const resolveVisibleEntityIds = (\n groups: Record<string, BackofficeSidebarGroupConfig>,\n entities: BackofficeEntityManifestMap,\n sidebar: BackofficeSidebarConfig | undefined,\n permissions: unknown,\n): string[] => {\n const output: string[] = [];\n const seen = new Set<string>();\n\n Object.entries(groups).forEach(([, group]) => {\n if (group.isVisible != null && !group.isVisible(permissions)) {\n return;\n }\n resolveGroupEntityIds(group, sidebar).forEach((entityId) => {\n if (seen.has(entityId)) {\n return;\n }\n if (!isEntityVisible(entityId, entities, sidebar, permissions)) {\n return;\n }\n seen.add(entityId);\n output.push(entityId);\n });\n });\n\n return output;\n};\n\nexport const resolveActiveEntityId = (\n pathname: string,\n entities: BackofficeEntityManifestMap,\n): string | null => {\n const entries = Object.entries(entities);\n for (const [entityId, config] of entries) {\n if (config.kind === 'tool') {\n if (isActivePath(pathname, config.routes.list)) {\n return entityId;\n }\n } else if (config.hasList && isActivePath(pathname, config.routes.list)) {\n return entityId;\n }\n }\n return null;\n};\n\nexport const resolveActiveGroupId = (\n groups: Record<string, BackofficeSidebarGroupConfig>,\n activeEntityId: string | null,\n entities: BackofficeEntityManifestMap,\n sidebar: BackofficeSidebarConfig | undefined,\n permissions: unknown,\n): string | null => {\n if (activeEntityId == null) {\n return null;\n }\n\n if (!isEntityVisible(activeEntityId, entities, sidebar, permissions)) {\n return null;\n }\n\n for (const [groupId, group] of Object.entries(groups)) {\n const isVisible = group.isVisible == null || group.isVisible(permissions);\n if (\n isVisible &&\n resolveGroupEntityIds(group, sidebar).includes(activeEntityId)\n ) {\n return groupId;\n }\n }\n\n return null;\n};\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { useBackofficeReactTranslation as e } from "../../../i18n/useBackofficeReactTranslation.js";
2
2
  import { BackofficeErrorBoundary as t } from "../errors/BackofficeErrorBoundary.js";
3
3
  import { useBackofficePickerEntityLoader as n } from "../../../provider/useBackofficeEntityLoader.js";
4
- import { useBackofficeFragment as r } from "../../../relay/typedRelayHooks.js";
4
+ import { useBackofficeRuntimeFragment as r } from "../../../relay/typedRelayHooks.js";
5
5
  import { loadingLabel as i, loadingState as a } from "./entityIdPickerDialog.css.js";
6
6
  import { Suspense as o, useCallback as s, useEffect as c, useMemo as l, useState as u } from "react";
7
7
  import { InlineBanner as d } from "@plumile/ui/components/feedback/InlineBanner.js";
@@ -1 +1 @@
1
- {"version":3,"file":"EntityIdPickerDialog.js","names":[],"sources":["../../../../../src/components/backoffice/pickers/EntityIdPickerDialog.tsx"],"sourcesContent":["import {\n Suspense,\n useCallback,\n useEffect,\n useMemo,\n useState,\n type JSX,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\n\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { Modal } from '@plumile/ui/atomic/atoms/modal/Modal.js';\nimport { Spinner } from '@plumile/ui/backoffice/atoms/spinner/Spinner.js';\nimport { BackofficeEmptyState } from '@plumile/ui/backoffice/molecules/backoffice_empty_state/BackofficeEmptyState.js';\nimport {\n BackofficePickerList,\n BackofficePickerShell,\n type BackofficePickerItem,\n} from '@plumile/ui/backoffice/molecules/backoffice_picker/BackofficePicker.js';\nimport { InlineBanner } from '@plumile/ui/components/feedback/InlineBanner.js';\nimport type {\n BackofficePickerScope,\n BackofficeRuntimeEntityPickerConfig,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\n\nimport { BackofficeErrorBoundary } from '../errors/BackofficeErrorBoundary.js';\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficePickerEntityLoader } from '../../../provider/useBackofficeEntityLoader.js';\nimport { useBackofficeFragment } from '../../../relay/typedRelayHooks.js';\n\nimport * as styles from './entityIdPickerDialog.css.js';\n\nconst { useLazyLoadQuery } = ReactRelay;\n\nexport type EntityIdPickerDialogProps = {\n isOpen: boolean;\n entity: string;\n title: string;\n scope?: BackofficePickerScope<Record<string, string>>;\n onClose: () => void;\n onSelectId: (id: string) => void;\n};\n\nconst PICKER_FETCH_POLICY = 'store-and-network' as const;\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\ntype PickerBodyProps = {\n config: BackofficeRuntimeEntityPickerConfig;\n search: string;\n scope?: BackofficePickerScope<Record<string, string>>;\n fetchKey: number;\n onSelectId: (id: string) => void;\n};\n\ntype RuntimePickerRow = {\n title: string;\n subtitle?: string | null | undefined;\n};\n\nconst PickerBody = ({\n config,\n search,\n scope,\n fetchKey,\n onSelectId,\n}: PickerBodyProps): JSX.Element => {\n const variables = useMemo(() => {\n const trimmed = search.trim();\n return config.buildQueryVariables({ search: trimmed, scope });\n }, [config, scope, search]);\n\n const queryData = useLazyLoadQuery(config.query, variables, {\n fetchPolicy: PICKER_FETCH_POLICY,\n fetchKey,\n });\n\n const fragmentData = useBackofficeFragment<unknown, unknown>(\n config.fragment,\n queryData,\n );\n\n const connection = config.getConnection(fragmentData);\n\n const items = useMemo<readonly BackofficePickerItem[]>(() => {\n return connection.edges.map((edge) => {\n const row = config.toRow(edge.node) as RuntimePickerRow;\n const id = config.getRowId(row);\n return {\n id,\n title: row.title,\n subtitle: row.subtitle,\n };\n });\n }, [config, connection.edges]);\n\n return (\n <BackofficePickerList\n items={items}\n onSelectItem={(item) => {\n onSelectId(item.id);\n }}\n />\n );\n};\n\nconst buildFooter = (onClose: () => void, closeLabel: string): JSX.Element => {\n return (\n <>\n <Button type=\"button\" variant=\"secondary\" onClick={onClose}>\n {closeLabel}\n </Button>\n </>\n );\n};\n\nconst PickerUnavailable = ({ message }: { message: string }) => {\n return (\n <InlineBanner tone=\"warning\" title={message}>\n {null}\n </InlineBanner>\n );\n};\n\nconst PickerLoading = ({ label }: { label: string }): JSX.Element => {\n return (\n <div className={styles.loadingState} role=\"status\" aria-live=\"polite\">\n <Spinner size={18} ariaLabel={label} />\n <span className={styles.loadingLabel}>{label}</span>\n </div>\n );\n};\n\nexport const EntityIdPickerDialog = ({\n isOpen,\n entity,\n title,\n scope,\n onClose,\n onSelectId,\n}: EntityIdPickerDialogProps): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const [search, setSearch] = useState('');\n const [fetchKey, setFetchKey] = useState(0);\n const entityState = useBackofficePickerEntityLoader(entity, {\n enabled: isOpen,\n });\n\n let pickerConfig: BackofficeRuntimeEntityPickerConfig | undefined;\n if (entityState.status === 'loaded') {\n pickerConfig = entityState.module.config.picker as\n BackofficeRuntimeEntityPickerConfig | undefined;\n }\n\n useEffect(() => {\n if (isOpen) {\n setSearch('');\n setFetchKey((value) => {\n return value + 1;\n });\n }\n }, [isOpen]);\n\n const footer = useMemo(() => {\n return buildFooter(onClose, t('common.actions.close'));\n }, [onClose, t]);\n\n const handleSearchChange = useCallback((next: string) => {\n setSearch(next);\n setFetchKey((value) => {\n return value + 1;\n });\n }, []);\n\n const handleSelectId = useCallback(\n (id: string) => {\n onSelectId(id);\n onClose();\n },\n [onClose, onSelectId],\n );\n\n if (!isOpen) {\n return null;\n }\n\n let resolvedSearchPlaceholder: string | undefined;\n if (pickerConfig?.searchPlaceholder != null) {\n resolvedSearchPlaceholder = resolveLabel(\n pickerConfig.searchPlaceholder,\n tApp,\n );\n }\n\n const trimmedSearch = search.trim();\n const isSearchRequired = pickerConfig?.searchRequired === true;\n\n let pickerNode: JSX.Element;\n if (entityState.status === 'loading') {\n pickerNode = <PickerLoading label={t('common.loading')} />;\n } else if (pickerConfig != null) {\n if (isSearchRequired && trimmedSearch === '') {\n pickerNode = <BackofficeEmptyState title={t('picker.searchRequired')} />;\n } else {\n pickerNode = (\n <PickerBody\n config={pickerConfig}\n search={search}\n scope={scope}\n fetchKey={fetchKey}\n onSelectId={handleSelectId}\n />\n );\n }\n } else {\n pickerNode = (\n <PickerUnavailable message={t('picker.unavailable', { entity })} />\n );\n }\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n footer={footer}\n initialFocus=\"first-form-control\"\n >\n <BackofficePickerShell\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={resolvedSearchPlaceholder}\n searchAriaLabel={resolvedSearchPlaceholder}\n searchName=\"backoffice-entity-picker-search\"\n searchEnabled={pickerConfig?.searchEnabled ?? true}\n >\n <BackofficeErrorBoundary\n fallback={(args: { error: unknown; reset: () => void }) => {\n const { reset } = args;\n return (\n <InlineBanner\n tone=\"danger\"\n title={t('picker.errors.loadFailed')}\n actions={\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n reset();\n setFetchKey((value) => {\n return value + 1;\n });\n }}\n >\n {t('common.actions.retry')}\n </Button>\n }\n >\n {null}\n </InlineBanner>\n );\n }}\n >\n <Suspense fallback={<PickerLoading label={t('common.loading')} />}>\n {pickerNode}\n </Suspense>\n </BackofficeErrorBoundary>\n </BackofficePickerShell>\n </Modal>\n );\n};\n\nexport type { BackofficePickerScope } from '@plumile/backoffice-core/types.js';\n\nexport default EntityIdPickerDialog;\n"],"mappings":";;;;;;;;;;;;;;;;AAmCA,IAAM,EAAE,kBAAA,MAAqB,GAWvB,IAAsB,qBAEtB,KAAgB,GAAkB,MAC/B,EAAM,CAAI,GAgBb,KAAc,EAClB,WACA,WACA,UACA,aACA,oBACkC;CAClC,IAAM,IAAY,QAAc;EAC9B,IAAM,IAAU,EAAO,KAAK;EAC5B,OAAO,EAAO,oBAAoB;GAAE,QAAQ;GAAS;EAAM,CAAC;CAC9D,GAAG;EAAC;EAAQ;EAAO;CAAM,CAAC,GAEpB,IAAY,EAAiB,EAAO,OAAO,GAAW;EAC1D,aAAa;EACb;CACF,CAAC,GAEK,IAAe,EACnB,EAAO,UACP,CACF,GAEM,IAAa,EAAO,cAAc,CAAY,GAE9C,IAAQ,QACL,EAAW,MAAM,KAAK,MAAS;EACpC,IAAM,IAAM,EAAO,MAAM,EAAK,IAAI;EAElC,OAAO;GACL,IAFS,EAAO,SAAS,CAEzB;GACA,OAAO,EAAI;GACX,UAAU,EAAI;EAChB;CACF,CAAC,GACA,CAAC,GAAQ,EAAW,KAAK,CAAC;CAE7B,OACE,kBAAC,GAAD;EACS;EACP,eAAe,MAAS;GACtB,EAAW,EAAK,EAAE;EACpB;CACD,CAAA;AAEL,GAEM,KAAe,GAAqB,MAEtC,kBAAA,GAAA,EAAA,UACE,kBAAC,GAAD;CAAQ,MAAK;CAAS,SAAQ;CAAY,SAAS;CAChD,UAAA;AACK,CAAA,EACR,CAAA,GAIA,KAAqB,EAAE,iBAEzB,kBAAC,GAAD;CAAc,MAAK;CAAU,OAAO;CACjC,UAAA;AACW,CAAA,GAIZ,KAAiB,EAAE,eAErB,kBAAC,OAAD;CAAK,WAAW;CAAqB,MAAK;CAAS,aAAU;CAA7D,UAAA,CACE,kBAAC,GAAD;EAAS,MAAM;EAAI,WAAW;CAAQ,CAAA,GACtC,kBAAC,QAAD;EAAM,WAAW;EAAsB,UAAA;CAAY,CAAA,CAChD;IAII,KAAwB,EACnC,WACA,WACA,UACA,UACA,YACA,oBACmD;CACnD,IAAM,EAAE,GAAG,MAAS,EAAe,GAC7B,EAAE,SAAM,EAA8B,GACtC,CAAC,GAAQ,KAAa,EAAS,EAAE,GACjC,CAAC,GAAU,KAAe,EAAS,CAAC,GACpC,IAAc,EAAgC,GAAQ,EAC1D,SAAS,EACX,CAAC,GAEG;CAMJ,AALI,EAAY,WAAW,aACzB,IAAe,EAAY,OAAO,OAAO,SAI3C,QAAgB;EACd,AAAI,MACF,EAAU,EAAE,GACZ,GAAa,MACJ,IAAQ,CAChB;CAEL,GAAG,CAAC,CAAM,CAAC;CAEX,IAAM,IAAS,QACN,EAAY,GAAS,EAAE,sBAAsB,CAAC,GACpD,CAAC,GAAS,CAAC,CAAC,GAET,IAAqB,GAAa,MAAiB;EAEvD,AADA,EAAU,CAAI,GACd,GAAa,MACJ,IAAQ,CAChB;CACH,GAAG,CAAC,CAAC,GAEC,IAAiB,GACpB,MAAe;EAEd,AADA,EAAW,CAAE,GACb,EAAQ;CACV,GACA,CAAC,GAAS,CAAU,CACtB;CAEA,IAAI,CAAC,GACH,OAAO;CAGT,IAAI;CACJ,AAAI,GAAc,qBAAqB,SACrC,IAA4B,EAC1B,EAAa,mBACb,CACF;CAGF,IAAM,IAAgB,EAAO,KAAK,GAC5B,IAAmB,GAAc,mBAAmB,IAEtD;CAuBJ,OAtBA,AAMI,IANA,EAAY,WAAW,YACZ,kBAAC,GAAD,EAAe,OAAO,EAAE,gBAAgB,EAAI,CAAA,IAChD,KAAgB,OAgBvB,kBAAC,GAAD,EAAmB,SAAS,EAAE,sBAAsB,EAAE,UAAO,CAAC,EAAI,CAAA,IAfhE,KAAoB,MAAkB,KAC3B,kBAAC,GAAD,EAAsB,OAAO,EAAE,uBAAuB,EAAI,CAAA,IAGrE,kBAAC,GAAD;EACE,QAAQ;EACA;EACD;EACG;EACV,YAAY;CACb,CAAA,GAUL,kBAAC,GAAD;EACU;EACC;EACF;EACC;EACR,cAAa;EAEb,UAAA,kBAAC,GAAD;GACE,aAAa;GACb,gBAAgB;GAChB,mBAAmB;GACnB,iBAAiB;GACjB,YAAW;GACX,eAAe,GAAc,iBAAiB;GAE9C,UAAA,kBAAC,GAAD;IACE,WAAW,MAAgD;KACzD,IAAM,EAAE,aAAU;KAClB,OACE,kBAAC,GAAD;MACE,MAAK;MACL,OAAO,EAAE,0BAA0B;MACnC,SACE,kBAAC,GAAD;OACE,MAAK;OACL,SAAQ;OACR,eAAe;QAEb,AADA,EAAM,GACN,GAAa,MACJ,IAAQ,CAChB;OACH;OAEC,UAAA,EAAE,sBAAsB;MACnB,CAAA;MAGT,UAAA;KACW,CAAA;IAElB;IAEA,UAAA,kBAAC,GAAD;KAAU,UAAU,kBAAC,GAAD,EAAe,OAAO,EAAE,gBAAgB,EAAI,CAAA;KAC7D,UAAA;IACO,CAAA;GACa,CAAA;EACJ,CAAA;CAClB,CAAA;AAEX"}
1
+ {"version":3,"file":"EntityIdPickerDialog.js","names":[],"sources":["../../../../../src/components/backoffice/pickers/EntityIdPickerDialog.tsx"],"sourcesContent":["import {\n Suspense,\n useCallback,\n useEffect,\n useMemo,\n useState,\n type JSX,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\n\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { Modal } from '@plumile/ui/atomic/atoms/modal/Modal.js';\nimport { Spinner } from '@plumile/ui/backoffice/atoms/spinner/Spinner.js';\nimport { BackofficeEmptyState } from '@plumile/ui/backoffice/molecules/backoffice_empty_state/BackofficeEmptyState.js';\nimport {\n BackofficePickerList,\n BackofficePickerShell,\n type BackofficePickerItem,\n} from '@plumile/ui/backoffice/molecules/backoffice_picker/BackofficePicker.js';\nimport { InlineBanner } from '@plumile/ui/components/feedback/InlineBanner.js';\nimport type {\n BackofficePickerScope,\n BackofficeRuntimeEntityPickerConfig,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\n\nimport { BackofficeErrorBoundary } from '../errors/BackofficeErrorBoundary.js';\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficePickerEntityLoader } from '../../../provider/useBackofficeEntityLoader.js';\nimport { useBackofficeRuntimeFragment } from '../../../relay/typedRelayHooks.js';\n\nimport * as styles from './entityIdPickerDialog.css.js';\n\nconst { useLazyLoadQuery } = ReactRelay;\n\nexport type EntityIdPickerDialogProps = {\n isOpen: boolean;\n entity: string;\n title: string;\n scope?: BackofficePickerScope<Record<string, string>>;\n onClose: () => void;\n onSelectId: (id: string) => void;\n};\n\nconst PICKER_FETCH_POLICY = 'store-and-network' as const;\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\ntype PickerBodyProps = {\n config: BackofficeRuntimeEntityPickerConfig;\n search: string;\n scope?: BackofficePickerScope<Record<string, string>>;\n fetchKey: number;\n onSelectId: (id: string) => void;\n};\n\ntype RuntimePickerRow = {\n title: string;\n subtitle?: string | null | undefined;\n};\n\nconst PickerBody = ({\n config,\n search,\n scope,\n fetchKey,\n onSelectId,\n}: PickerBodyProps): JSX.Element => {\n const variables = useMemo(() => {\n const trimmed = search.trim();\n return config.buildQueryVariables({ search: trimmed, scope });\n }, [config, scope, search]);\n\n const queryData = useLazyLoadQuery(config.query, variables, {\n fetchPolicy: PICKER_FETCH_POLICY,\n fetchKey,\n });\n\n const fragmentData = useBackofficeRuntimeFragment(config.fragment, queryData);\n\n const connection = config.getConnection(fragmentData);\n\n const items = useMemo<readonly BackofficePickerItem[]>(() => {\n return connection.edges.map((edge) => {\n const row = config.toRow(edge.node) as RuntimePickerRow;\n const id = config.getRowId(row);\n return {\n id,\n title: row.title,\n subtitle: row.subtitle,\n };\n });\n }, [config, connection.edges]);\n\n return (\n <BackofficePickerList\n items={items}\n onSelectItem={(item) => {\n onSelectId(item.id);\n }}\n />\n );\n};\n\nconst buildFooter = (onClose: () => void, closeLabel: string): JSX.Element => {\n return (\n <>\n <Button type=\"button\" variant=\"secondary\" onClick={onClose}>\n {closeLabel}\n </Button>\n </>\n );\n};\n\nconst PickerUnavailable = ({ message }: { message: string }) => {\n return (\n <InlineBanner tone=\"warning\" title={message}>\n {null}\n </InlineBanner>\n );\n};\n\nconst PickerLoading = ({ label }: { label: string }): JSX.Element => {\n return (\n <div className={styles.loadingState} role=\"status\" aria-live=\"polite\">\n <Spinner size={18} ariaLabel={label} />\n <span className={styles.loadingLabel}>{label}</span>\n </div>\n );\n};\n\nexport const EntityIdPickerDialog = ({\n isOpen,\n entity,\n title,\n scope,\n onClose,\n onSelectId,\n}: EntityIdPickerDialogProps): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const [search, setSearch] = useState('');\n const [fetchKey, setFetchKey] = useState(0);\n const entityState = useBackofficePickerEntityLoader(entity, {\n enabled: isOpen,\n });\n\n let pickerConfig: BackofficeRuntimeEntityPickerConfig | undefined;\n if (entityState.status === 'loaded') {\n pickerConfig = entityState.module.config.picker as\n BackofficeRuntimeEntityPickerConfig | undefined;\n }\n\n useEffect(() => {\n if (isOpen) {\n setSearch('');\n setFetchKey((value) => {\n return value + 1;\n });\n }\n }, [isOpen]);\n\n const footer = useMemo(() => {\n return buildFooter(onClose, t('common.actions.close'));\n }, [onClose, t]);\n\n const handleSearchChange = useCallback((next: string) => {\n setSearch(next);\n setFetchKey((value) => {\n return value + 1;\n });\n }, []);\n\n const handleSelectId = useCallback(\n (id: string) => {\n onSelectId(id);\n onClose();\n },\n [onClose, onSelectId],\n );\n\n if (!isOpen) {\n return null;\n }\n\n let resolvedSearchPlaceholder: string | undefined;\n if (pickerConfig?.searchPlaceholder != null) {\n resolvedSearchPlaceholder = resolveLabel(\n pickerConfig.searchPlaceholder,\n tApp,\n );\n }\n\n const trimmedSearch = search.trim();\n const isSearchRequired = pickerConfig?.searchRequired === true;\n\n let pickerNode: JSX.Element;\n if (entityState.status === 'loading') {\n pickerNode = <PickerLoading label={t('common.loading')} />;\n } else if (pickerConfig != null) {\n if (isSearchRequired && trimmedSearch === '') {\n pickerNode = <BackofficeEmptyState title={t('picker.searchRequired')} />;\n } else {\n pickerNode = (\n <PickerBody\n config={pickerConfig}\n search={search}\n scope={scope}\n fetchKey={fetchKey}\n onSelectId={handleSelectId}\n />\n );\n }\n } else {\n pickerNode = (\n <PickerUnavailable message={t('picker.unavailable', { entity })} />\n );\n }\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n footer={footer}\n initialFocus=\"first-form-control\"\n >\n <BackofficePickerShell\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={resolvedSearchPlaceholder}\n searchAriaLabel={resolvedSearchPlaceholder}\n searchName=\"backoffice-entity-picker-search\"\n searchEnabled={pickerConfig?.searchEnabled ?? true}\n >\n <BackofficeErrorBoundary\n fallback={(args: { error: unknown; reset: () => void }) => {\n const { reset } = args;\n return (\n <InlineBanner\n tone=\"danger\"\n title={t('picker.errors.loadFailed')}\n actions={\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n reset();\n setFetchKey((value) => {\n return value + 1;\n });\n }}\n >\n {t('common.actions.retry')}\n </Button>\n }\n >\n {null}\n </InlineBanner>\n );\n }}\n >\n <Suspense fallback={<PickerLoading label={t('common.loading')} />}>\n {pickerNode}\n </Suspense>\n </BackofficeErrorBoundary>\n </BackofficePickerShell>\n </Modal>\n );\n};\n\nexport type { BackofficePickerScope } from '@plumile/backoffice-core/types.js';\n\nexport default EntityIdPickerDialog;\n"],"mappings":"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"}