@plumile/backoffice-react 0.1.143 → 0.1.145

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 (230) hide show
  1. package/lib/esm/auth/AuthRefreshNotice.js.map +1 -1
  2. package/lib/esm/auth/TotpQrCode.js.map +1 -1
  3. package/lib/esm/auth/authRefreshNotice.css.js +1 -1
  4. package/lib/esm/auth/login/AuthPanel.js.map +1 -1
  5. package/lib/esm/auth/login/EmailCapturePanel.js.map +1 -1
  6. package/lib/esm/auth/login/LoginFlow.js.map +1 -1
  7. package/lib/esm/auth/login/MethodChooser.js.map +1 -1
  8. package/lib/esm/auth/login/MfaChallengeForm.js.map +1 -1
  9. package/lib/esm/auth/login/OidcButtons.js.map +1 -1
  10. package/lib/esm/auth/login/PasskeyLoginForm.js.map +1 -1
  11. package/lib/esm/auth/login/PasswordLoginPanel.js.map +1 -1
  12. package/lib/esm/auth/login/loginPage.css.js +1 -1
  13. package/lib/esm/auth/login/loginPage.css.js.map +1 -1
  14. package/lib/esm/auth/login/synchronizeAuthStatusQuery.js.map +1 -1
  15. package/lib/esm/auth/pages/AcceptInvitationScreen.js.map +1 -1
  16. package/lib/esm/auth/pages/PasswordResetCompleteScreen.js.map +1 -1
  17. package/lib/esm/auth/pages/PasswordResetRequestScreen.js.map +1 -1
  18. package/lib/esm/auth/pages/VerifyEmailScreen.js.map +1 -1
  19. package/lib/esm/components/backoffice/actions/BackofficeEntityActionFormDialog.js +14 -14
  20. package/lib/esm/components/backoffice/actions/BackofficeEntityActionFormDialog.js.map +1 -1
  21. package/lib/esm/components/backoffice/actions/LazyBackofficeEntityActionFormDialog.js.map +1 -1
  22. package/lib/esm/components/backoffice/actions/backofficeEntityActionFormDialog.css.js +1 -1
  23. package/lib/esm/components/backoffice/actions/toastViewAction.js.map +1 -1
  24. package/lib/esm/components/backoffice/billing/BackofficeBillingUsageChart.js +1 -1
  25. package/lib/esm/components/backoffice/billing/BackofficeBillingUsageChart.js.map +1 -1
  26. package/lib/esm/components/backoffice/billing/backofficeBillingUsageChart.css.js +1 -1
  27. package/lib/esm/components/backoffice/columns/buildDataTableColumns.js.map +1 -1
  28. package/lib/esm/components/backoffice/detail/BackofficeDetailBadgeRow.js.map +1 -1
  29. package/lib/esm/components/backoffice/detail/BackofficeDetailErrorList.js.map +1 -1
  30. package/lib/esm/components/backoffice/detail/BackofficeDetailFlagTag.js.map +1 -1
  31. package/lib/esm/components/backoffice/detail/BackofficeDetailRelationLink.js.map +1 -1
  32. package/lib/esm/components/backoffice/detail/BackofficeDetailRelationList.js.map +1 -1
  33. package/lib/esm/components/backoffice/detail/BackofficeDetailRelationListBlock.js.map +1 -1
  34. package/lib/esm/components/backoffice/detail/BackofficeDetailTaggedValue.js.map +1 -1
  35. package/lib/esm/components/backoffice/detail/BackofficeEntitySummaryHeader.js +6 -6
  36. package/lib/esm/components/backoffice/detail/BackofficeEntitySummaryHeader.js.map +1 -1
  37. package/lib/esm/components/backoffice/detail/BackofficeEnumLabel.js.map +1 -1
  38. package/lib/esm/components/backoffice/detail/BackofficeLifecycleTimelineSection.js.map +1 -1
  39. package/lib/esm/components/backoffice/detail/BackofficeReferenceValue.js.map +1 -1
  40. package/lib/esm/components/backoffice/detail/BackofficeRelationsSummaryGrid.js +1 -1
  41. package/lib/esm/components/backoffice/detail/BackofficeRelationsSummaryGrid.js.map +1 -1
  42. package/lib/esm/components/backoffice/detail/BackofficeStatusGroup.js.map +1 -1
  43. package/lib/esm/components/backoffice/detail/BackofficeStatusMetaBadge.js.map +1 -1
  44. package/lib/esm/components/backoffice/detail/BackofficeTokenUsageBreakdown.js.map +1 -1
  45. package/lib/esm/components/backoffice/detail/BackofficeUsageCostBreakdown.js +13 -13
  46. package/lib/esm/components/backoffice/detail/BackofficeUsageCostBreakdown.js.map +1 -1
  47. package/lib/esm/components/backoffice/detail/backofficeDetailBadgeRow.css.js +1 -1
  48. package/lib/esm/components/backoffice/detail/backofficeDetailErrorList.css.js +1 -1
  49. package/lib/esm/components/backoffice/detail/backofficeDetailLayout.css.js +1 -1
  50. package/lib/esm/components/backoffice/detail/backofficeDetailRelationLink.css.js +2 -1
  51. package/lib/esm/components/backoffice/detail/backofficeDetailRelationList.css.js +1 -1
  52. package/lib/esm/components/backoffice/detail/backofficeEntitySummaryHeader.css.js +1 -1
  53. package/lib/esm/components/backoffice/detail/backofficeRelationsSummaryGrid.css.js +1 -1
  54. package/lib/esm/components/backoffice/detail/backofficeUsageCostBreakdown.css.js +1 -1
  55. package/lib/esm/components/backoffice/detail/createBackofficeEntityLinkProps.js.map +1 -1
  56. package/lib/esm/components/backoffice/detail/detailPayloadUtils.js.map +1 -1
  57. package/lib/esm/components/backoffice/errors/BackofficeErrorBoundary.js.map +1 -1
  58. package/lib/esm/components/backoffice/filters/BackofficeFilterAction.js.map +1 -1
  59. package/lib/esm/components/backoffice/filters/DeferredFilterSearchInput.js.map +1 -1
  60. package/lib/esm/components/backoffice/filters/EntityFilterValue.js.map +1 -1
  61. package/lib/esm/components/backoffice/filters/EntityIdFilterField.js +1 -1
  62. package/lib/esm/components/backoffice/filters/EntityIdFilterField.js.map +1 -1
  63. package/lib/esm/components/backoffice/filters/backofficeFilterAction.css.js +1 -1
  64. package/lib/esm/components/backoffice/filters/backofficeFilterAction.css.js.map +1 -1
  65. package/lib/esm/components/backoffice/filters/deferredFilterSearchInput.css.js +1 -1
  66. package/lib/esm/components/backoffice/filters/entityIdFilterField.css.js +1 -1
  67. package/lib/esm/components/backoffice/hub/BackofficeHubTemplate.js +5 -5
  68. package/lib/esm/components/backoffice/hub/BackofficeHubTemplate.js.map +1 -1
  69. package/lib/esm/components/backoffice/hub/backofficeHubTemplate.css.js +1 -1
  70. package/lib/esm/components/backoffice/layout/BackofficePermissionsContext.js.map +1 -1
  71. package/lib/esm/components/backoffice/layout/backofficeSidebarActions.css.js +1 -1
  72. package/lib/esm/components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js.map +1 -1
  73. package/lib/esm/components/backoffice/layout/breadcrumb/BackofficeTopbarBreadcrumb.js +2 -2
  74. package/lib/esm/components/backoffice/layout/breadcrumb/BackofficeTopbarBreadcrumb.js.map +1 -1
  75. package/lib/esm/components/backoffice/layout/breadcrumb/BackofficeTopbarPortal.js.map +1 -1
  76. package/lib/esm/components/backoffice/layout/breadcrumb/BackofficeTopbarPortalContext.js.map +1 -1
  77. package/lib/esm/components/backoffice/layout/breadcrumb/assertValidBreadcrumb.js.map +1 -1
  78. package/lib/esm/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.js +1 -2
  79. package/lib/esm/components/backoffice/layout/breadcrumb/buildBreadcrumbs.js.map +1 -1
  80. package/lib/esm/components/backoffice/layout/buildSidebarSections.js.map +1 -1
  81. package/lib/esm/components/backoffice/layout/mapViewerToSidebarProfileView.js.map +1 -1
  82. package/lib/esm/components/backoffice/layout/sidebarUtils.js.map +1 -1
  83. package/lib/esm/components/backoffice/links/BackofficeInlineLink.js.map +1 -1
  84. package/lib/esm/components/backoffice/links/BackofficeLink.js.map +1 -1
  85. package/lib/esm/components/backoffice/links/BackofficeLinkContent.js +1 -1
  86. package/lib/esm/components/backoffice/links/BackofficeLinkContent.js.map +1 -1
  87. package/lib/esm/components/backoffice/links/BackofficeLinkLabel.js.map +1 -1
  88. package/lib/esm/components/backoffice/links/backofficeLink.css.js +1 -1
  89. package/lib/esm/components/backoffice/links/resolveBackofficeLink.js.map +1 -1
  90. package/lib/esm/components/backoffice/links/resolveBackofficeTargetIcon.js.map +1 -1
  91. package/lib/esm/components/backoffice/links/useBackofficeLink.js.map +1 -1
  92. package/lib/esm/components/backoffice/list/RowFlagsCell.css.js +1 -1
  93. package/lib/esm/components/backoffice/list/RowFlagsCell.js.map +1 -1
  94. package/lib/esm/components/backoffice/overview/BackofficeOverviewLayout.js.map +1 -1
  95. package/lib/esm/components/backoffice/overview/backofficeOverviewLayout.css.js +1 -1
  96. package/lib/esm/components/backoffice/overview/backofficeOverviewLayout.css.js.map +1 -1
  97. package/lib/esm/components/backoffice/pickers/EntityIdPickerDialog.js.map +1 -1
  98. package/lib/esm/components/backoffice/pickers/entityIdPickerDialog.css.js +1 -1
  99. package/lib/esm/components/backoffice/refs/BackofficeEntityIdRef.js.map +1 -1
  100. package/lib/esm/components/backoffice/refs/BackofficeEntityLink.js.map +1 -1
  101. package/lib/esm/components/backoffice/refs/BackofficeRelatedCountLink.js.map +1 -1
  102. package/lib/esm/components/backoffice/refs/backofficeEntityIdRef.css.js +1 -1
  103. package/lib/esm/components/backoffice/refs/backofficeRelatedCountLink.css.js +1 -1
  104. package/lib/esm/components/backoffice/routing/BackofficeContentBoundary.js.map +1 -1
  105. package/lib/esm/components/backoffice/routing/BackofficeContentError.js.map +1 -1
  106. package/lib/esm/components/backoffice/routing/BackofficeContentFallback.js.map +1 -1
  107. package/lib/esm/components/backoffice/routing/BackofficeRouteFallback.js.map +1 -1
  108. package/lib/esm/components/backoffice/routing/BackofficeRoutePendingBar.js.map +1 -1
  109. package/lib/esm/components/backoffice/routing/backofficeContentBoundary.css.js +1 -1
  110. package/lib/esm/components/backoffice/routing/backofficeContentError.css.js +1 -1
  111. package/lib/esm/components/backoffice/routing/backofficeContentFallback.css.js +1 -1
  112. package/lib/esm/components/backoffice/routing/backofficeRouteFallback.css.js +1 -1
  113. package/lib/esm/components/backoffice/routing/backofficeRoutePendingBar.css.js +1 -1
  114. package/lib/esm/components/backoffice/routing/backofficeRoutePendingBar.css.js.map +1 -1
  115. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityDetailScaffold.js.map +1 -1
  116. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js.map +1 -1
  117. package/lib/esm/components/backoffice/scaffolds/BackofficeListFilterContext.js.map +1 -1
  118. package/lib/esm/components/backoffice/scaffolds/BackofficeTabbedDetailShell.js.map +1 -1
  119. package/lib/esm/components/backoffice/scaffolds/backofficeEntityListScaffold.css.js +1 -1
  120. package/lib/esm/components/backoffice/scaffolds/backofficeTabbedDetailShell.css.js +1 -1
  121. package/lib/esm/components/backoffice/shared/BackofficeFilterableCell.js.map +1 -1
  122. package/lib/esm/components/backoffice/shared/BackofficeFormattedCurrency.js.map +1 -1
  123. package/lib/esm/components/backoffice/shared/BackofficeFormattedNumber.js.map +1 -1
  124. package/lib/esm/components/backoffice/shared/BackofficeInlineFilterRow.js.map +1 -1
  125. package/lib/esm/components/backoffice/shared/backofficeFilterableCell.css.js +5 -5
  126. package/lib/esm/components/backoffice/shared/backofficeFilterableCell.css.js.map +1 -1
  127. package/lib/esm/components/backoffice/shared/backofficeInlineFilterRow.css.js +1 -1
  128. package/lib/esm/components/backoffice/tools/BackofficeToolsDocPanel.js +1 -1
  129. package/lib/esm/components/backoffice/tools/BackofficeToolsDocPanel.js.map +1 -1
  130. package/lib/esm/components/backoffice/tools/BackofficeToolsErrorFallback.js.map +1 -1
  131. package/lib/esm/components/backoffice/tools/BackofficeToolsJsonForm.js.map +1 -1
  132. package/lib/esm/components/backoffice/tools/BackofficeToolsQueryBoundary.js.map +1 -1
  133. package/lib/esm/components/backoffice/tools/backofficeToolsDocPanel.css.js +1 -1
  134. package/lib/esm/components/backoffice/tools/backofficeToolsDocPanel.css.js.map +1 -1
  135. package/lib/esm/components/backoffice/tools/backofficeToolsForm.css.js +1 -1
  136. package/lib/esm/components/backoffice/tools/backofficeToolsJsonForm.css.js +1 -1
  137. package/lib/esm/components/backoffice/tools/parseToolJson.js.map +1 -1
  138. package/lib/esm/filters/filterHelpers.js.map +1 -1
  139. package/lib/esm/hooks/useAuth.js.map +1 -1
  140. package/lib/esm/hooks/useBackofficeAuth.js.map +1 -1
  141. package/lib/esm/hooks/useBackofficeInfiniteScrollSentinel.js.map +1 -1
  142. package/lib/esm/hooks/useBackofficeListRefetch.js.map +1 -1
  143. package/lib/esm/hooks/useBackofficeListUrlState.js.map +1 -1
  144. package/lib/esm/hooks/useBackofficeLoadMore.js.map +1 -1
  145. package/lib/esm/hooks/useBackofficeSessionAuth.js.map +1 -1
  146. package/lib/esm/hooks/useBackofficeSidebarPins.js.map +1 -1
  147. package/lib/esm/hooks/useConditionalSubscription.js.map +1 -1
  148. package/lib/esm/hooks/useCopyToClipboard.js.map +1 -1
  149. package/lib/esm/hooks/useInfiniteConnection.js.map +1 -1
  150. package/lib/esm/hooks/useRefetchNeededReload.js.map +1 -1
  151. package/lib/esm/hooks/useSidebarGroupCollapse.js.map +1 -1
  152. package/lib/esm/i18n/createI18nInstance.js.map +1 -1
  153. package/lib/esm/i18n/mergeResourceLanguages.js.map +1 -1
  154. package/lib/esm/i18n/resources.js.map +1 -1
  155. package/lib/esm/i18n/useBackofficeFormats.js.map +1 -1
  156. package/lib/esm/i18n/useBackofficeReactTranslation.js.map +1 -1
  157. package/lib/esm/i18n/useReviewStatusLabel.js.map +1 -1
  158. package/lib/esm/modules/base64.js.map +1 -1
  159. package/lib/esm/modules/formatFileSize.js.map +1 -1
  160. package/lib/esm/modules/webauthn.js.map +1 -1
  161. package/lib/esm/node_modules/@babel/runtime/helpers/arrayLikeToArray.js.map +1 -1
  162. package/lib/esm/node_modules/@babel/runtime/helpers/arrayWithoutHoles.js.map +1 -1
  163. package/lib/esm/node_modules/@babel/runtime/helpers/defineProperty.js.map +1 -1
  164. package/lib/esm/node_modules/@babel/runtime/helpers/interopRequireDefault.js.map +1 -1
  165. package/lib/esm/node_modules/@babel/runtime/helpers/iterableToArray.js.map +1 -1
  166. package/lib/esm/node_modules/@babel/runtime/helpers/nonIterableSpread.js.map +1 -1
  167. package/lib/esm/node_modules/@babel/runtime/helpers/objectSpread2.js.map +1 -1
  168. package/lib/esm/node_modules/@babel/runtime/helpers/objectWithoutPropertiesLoose.js.map +1 -1
  169. package/lib/esm/node_modules/@babel/runtime/helpers/toConsumableArray.js.map +1 -1
  170. package/lib/esm/node_modules/@babel/runtime/helpers/toPrimitive.js.map +1 -1
  171. package/lib/esm/node_modules/@babel/runtime/helpers/toPropertyKey.js.map +1 -1
  172. package/lib/esm/node_modules/@babel/runtime/helpers/typeof.js.map +1 -1
  173. package/lib/esm/node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js.map +1 -1
  174. package/lib/esm/node_modules/@vanilla-extract/recipes/dist/createRuntimeFn-62c9670f.esm.js.map +1 -1
  175. package/lib/esm/node_modules/fbjs/lib/areEqual.js.map +1 -1
  176. package/lib/esm/node_modules/invariant/browser.js.map +1 -1
  177. package/lib/esm/node_modules/relay-test-utils/index.js.map +1 -1
  178. package/lib/esm/node_modules/relay-test-utils/lib/RelayMockPayloadGenerator.js.map +1 -1
  179. package/lib/esm/node_modules/relay-test-utils/lib/RelayModernMockEnvironment.js.map +1 -1
  180. package/lib/esm/node_modules/relay-test-utils/lib/RelayResolverTestUtils.js.map +1 -1
  181. package/lib/esm/node_modules/relay-test-utils/lib/index.js.map +1 -1
  182. package/lib/esm/node_modules/relay-test-utils/lib/unwrapContainer.js.map +1 -1
  183. package/lib/esm/pages/BackofficeAcceptInvitationPage.js.map +1 -1
  184. package/lib/esm/pages/BackofficeDashboardPage.helpers.js.map +1 -1
  185. package/lib/esm/pages/BackofficeDashboardPage.js.map +1 -1
  186. package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js.map +1 -1
  187. package/lib/esm/pages/BackofficeEntityDetailPage.helpers.js.map +1 -1
  188. package/lib/esm/pages/BackofficeEntityDetailPage.js +2 -2
  189. package/lib/esm/pages/BackofficeEntityDetailPage.js.map +1 -1
  190. package/lib/esm/pages/BackofficeEntityDetailPage.view-helpers.js.map +1 -1
  191. package/lib/esm/pages/BackofficeEntityDetailUnknownPageRedirect.js.map +1 -1
  192. package/lib/esm/pages/BackofficeEntityListPage.helpers.js.map +1 -1
  193. package/lib/esm/pages/BackofficeEntityListPage.js.map +1 -1
  194. package/lib/esm/pages/BackofficeHubPage.js.map +1 -1
  195. package/lib/esm/pages/BackofficeLayoutPage.js.map +1 -1
  196. package/lib/esm/pages/BackofficeLoginPage.js.map +1 -1
  197. package/lib/esm/pages/BackofficePasswordResetCompletePage.js.map +1 -1
  198. package/lib/esm/pages/BackofficePasswordResetRequestPage.js.map +1 -1
  199. package/lib/esm/pages/BackofficeVerifyEmailPage.js.map +1 -1
  200. package/lib/esm/pages/backofficeDashboardPage.css.js +1 -1
  201. package/lib/esm/pages/backofficeEntityDetailPage.css.js +1 -1
  202. package/lib/esm/pages/backofficeEntityListPage.css.js +1 -1
  203. package/lib/esm/pages/detail/BackofficeEntityDetailLayoutContext.js.map +1 -1
  204. package/lib/esm/pages/detail/buildTabsItems.js.map +1 -1
  205. package/lib/esm/pages/detail/pageResolution.js.map +1 -1
  206. package/lib/esm/provider/BackofficeConfigContext.js.map +1 -1
  207. package/lib/esm/provider/BackofficeProvider.js.map +1 -1
  208. package/lib/esm/provider/dashboardRegistrations.js.map +1 -1
  209. package/lib/esm/provider/entityRegistry.js.map +1 -1
  210. package/lib/esm/provider/lazyValue.js.map +1 -1
  211. package/lib/esm/provider/useBackofficeEntityLoader.js.map +1 -1
  212. package/lib/esm/provider/useBackofficeLazyValue.js.map +1 -1
  213. package/lib/esm/relay/RelayProvider.js.map +1 -1
  214. package/lib/esm/relay/connectionUtils.js.map +1 -1
  215. package/lib/esm/relay/createInlineReader.js.map +1 -1
  216. package/lib/esm/relay/envHelpers.js.map +1 -1
  217. package/lib/esm/relay/environment.js.map +1 -1
  218. package/lib/esm/relay/mutationResult.js.map +1 -1
  219. package/lib/esm/router/backofficeAuthPaths.js.map +1 -1
  220. package/lib/esm/router/createBackofficeRoutes.js.map +1 -1
  221. package/lib/esm/storybook/relay/RelayStory.css.js +1 -1
  222. package/lib/esm/storybook/relay/RelayStory.js.map +1 -1
  223. package/lib/esm/storybook/relay/mockResolvers.js.map +1 -1
  224. package/lib/esm/style.css +1 -1
  225. package/lib/esm/subscriptions/useCursorResumableSubscription.js.map +1 -1
  226. package/lib/types/components/backoffice/errors/BackofficeErrorBoundary.stories.d.ts +1 -1
  227. package/lib/types/components/backoffice/errors/BackofficeErrorBoundary.stories.d.ts.map +1 -1
  228. package/lib/types/components/backoffice/overview/backofficeOverviewLayout.css.d.ts.map +1 -1
  229. package/lib/types/components/backoffice/tools/backofficeToolsDocPanel.css.d.ts.map +1 -1
  230. package/package.json +16 -16
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeEntityListScaffold.js","names":[],"sources":["../../../../../src/components/backoffice/scaffolds/BackofficeEntityListScaffold.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n type JSX,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { BackofficeEmptyState } from '@plumile/ui/backoffice/molecules/backoffice_empty_state/BackofficeEmptyState.js';\nimport { BackofficeFilterDrawer } from '@plumile/ui/backoffice/molecules/backoffice_filter_drawer/BackofficeFilterDrawer.js';\nimport { BackofficeFilterField } from '@plumile/ui/backoffice/molecules/backoffice_filter_field/BackofficeFilterField.js';\nimport { BackofficeListFooter } from '@plumile/ui/backoffice/molecules/backoffice_list_footer/BackofficeListFooter.js';\nimport { BackofficePageHeader } from '@plumile/ui/backoffice/molecules/backoffice_page_header/BackofficePageHeader.js';\nimport { BackofficeToolbar } from '@plumile/ui/backoffice/molecules/backoffice_toolbar/BackofficeToolbar.js';\nimport { BackofficeTableSkeleton } from '@plumile/ui/backoffice/molecules/backoffice_table_skeleton/BackofficeTableSkeleton.js';\nimport {\n FilterChipRow,\n type FilterChip,\n} from '@plumile/ui/backoffice/molecules/filter_chip_row/FilterChipRow.js';\nimport { InlineBanner } from '@plumile/ui/components/feedback/InlineBanner.js';\nimport { ListPageTemplate } from '@plumile/ui/backoffice/templates/list_page_template/ListPageTemplate.js';\nimport {\n type DataTableColumn,\n type GetRowId,\n} from '@plumile/ui/components/data-table/DataTable.js';\nimport { ResponsiveRecordList } from '@plumile/ui/components/data-table/ResponsiveRecordList.js';\nimport { VirtualizedConnectionTable } from '@plumile/ui/components/data-table/VirtualizedConnectionTable.js';\nimport { SimpleSelect } from '@plumile/ui/components/select/SimpleSelect.js';\nimport { denseTableClass } from '@plumile/ui/shared/backofficeTableDensity.css.js';\n\nimport {\n readWhereValue,\n setWhereValue,\n} from '@plumile/backoffice-core/filters/where.js';\nimport { resolveBackofficeListRuntimeConfig } from '@plumile/backoffice-core/config/listRuntime.js';\nimport type {\n BackofficeFilterSpec,\n BackofficeListState,\n BackofficePickerScope,\n BackofficeRuntimeResolvedListFacetConfig,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\n\nimport { BackofficeErrorBoundary } from '../errors/BackofficeErrorBoundary.js';\nimport {\n EntityFilterValue,\n EntityFilterValueText,\n} from '../filters/EntityFilterValue.js';\nimport { EntityIdPickerDialog } from '../pickers/EntityIdPickerDialog.js';\nimport { EntityIdFilterField } from '../filters/EntityIdFilterField.js';\nimport { DeferredFilterSearchInput } from '../filters/DeferredFilterSearchInput.js';\nimport { BackofficeListFilterProvider } from './BackofficeListFilterContext.js';\nimport { BACKOFFICE_LIST_BODY_SCROLL_MODE } from './backofficeListScrollMode.js';\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeInfiniteScrollSentinel } from '../../../hooks/useBackofficeInfiniteScrollSentinel.js';\nimport { isDevEnv } from '../../../relay/envHelpers.js';\n\nimport * as styles from './backofficeEntityListScaffold.css.js';\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nconst getFilterValue = <Where extends Record<string, unknown>>(\n filter: BackofficeFilterSpec<Where>,\n where: Where | null,\n): unknown => {\n if (filter.fromGraphQL != null && where != null) {\n return filter.fromGraphQL(where);\n }\n\n const key = (filter.whereKey ?? filter.id) as keyof Where;\n return readWhereValue(where, key, filter.path);\n};\n\nconst getFilterDisplayValue = <Where extends Record<string, unknown>>(\n filter: BackofficeFilterSpec<Where>,\n raw: unknown,\n options: {\n enumLabel: (value: string) => string;\n booleanLabel: (value: boolean) => string;\n fallbackBooleanLabels: { yes: string; no: string };\n },\n): ReactNode | null => {\n if (raw == null) {\n return null;\n }\n\n if (Array.isArray(raw)) {\n const normalized = raw\n .map((entry) => {\n if (entry == null) {\n return null;\n }\n if (\n typeof entry !== 'string' &&\n typeof entry !== 'number' &&\n typeof entry !== 'boolean'\n ) {\n return null;\n }\n const value = String(entry).trim();\n if (value === '') {\n return null;\n }\n return value;\n })\n .filter((entry): entry is string => {\n return entry != null;\n });\n\n if (normalized.length === 0) {\n return null;\n }\n return normalized.join(', ');\n }\n\n if (typeof raw === 'boolean') {\n if (filter.kind === 'boolean') {\n return options.booleanLabel(raw);\n }\n if (raw) {\n return options.fallbackBooleanLabels.yes;\n }\n return options.fallbackBooleanLabels.no;\n }\n\n if (typeof raw !== 'string' && typeof raw !== 'number') {\n return null;\n }\n\n const rawString = String(raw).trim();\n if (rawString === '') {\n return null;\n }\n\n if (filter.kind === 'entityId') {\n return <EntityFilterValue entityId={filter.entity} id={rawString} />;\n }\n\n if (filter.kind === 'enum') {\n return options.enumLabel(rawString);\n }\n\n return rawString;\n};\n\nconst toDatetimeInputValue = (value: string): string => {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n return value;\n }\n const offsetMs = date.getTimezoneOffset() * 60_000;\n return new Date(date.getTime() - offsetMs).toISOString().slice(0, 16);\n};\n\nconst fromDatetimeInputValue = (value: string): string => {\n const normalized = value.trim();\n if (normalized === '') {\n return '';\n }\n const date = new Date(normalized);\n if (Number.isNaN(date.getTime())) {\n return normalized;\n }\n return date.toISOString();\n};\n\ntype RuntimeWhere = Record<string, unknown>;\ntype RuntimeSort = string;\n\ntype Props<RowView> = {\n config: BackofficeRuntimeResolvedListFacetConfig;\n state: BackofficeListState<RuntimeWhere, RuntimeSort>;\n pushState: (next: BackofficeListState<RuntimeWhere, RuntimeSort>) => void;\n header?: {\n title?: string;\n subtitle?: string;\n };\n headerActions?: ReactNode;\n rows: readonly RowView[];\n getRowId: GetRowId<RowView>;\n columns: readonly DataTableColumn<RowView>[];\n gridTemplateColumns?: string;\n hasNextPage: boolean;\n isLoadingMore: boolean;\n isRefreshing?: boolean;\n onLoadMore: () => void;\n onRefresh?: () => void;\n totalCount?: number | null;\n emptyState?: JSX.Element;\n statusBanner?: ReactNode;\n isLoadingInitial?: boolean;\n virtualize?: boolean;\n variant?: 'page' | 'embedded';\n showFilters?: boolean;\n};\n\nexport const BackofficeEntityListScaffold = <RowView,>(\n props: Props<RowView>,\n): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const {\n config,\n state,\n pushState,\n rows,\n getRowId,\n columns,\n gridTemplateColumns,\n hasNextPage,\n isLoadingMore,\n isRefreshing = false,\n onLoadMore,\n onRefresh,\n totalCount,\n emptyState,\n statusBanner,\n header,\n headerActions,\n isLoadingInitial = false,\n variant = 'page',\n showFilters = true,\n } = props;\n const listConfig = config.list;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const listDefaults = config.listDefaults ??\n listConfig.defaultState ?? { where: null, sort: null };\n\n const columnsWithPrimary = useMemo(() => {\n const hasPrimary = columns.some((col) => {\n return col.isPrimary === true;\n });\n if (hasPrimary || columns.length === 0) {\n return columns;\n }\n return columns.map((col, index) => {\n const { header } = col;\n if (index === 0) {\n return { ...col, isPrimary: true, header };\n }\n return { ...col, header };\n });\n }, [columns]);\n\n const chips = useMemo<readonly FilterChip[]>(() => {\n const out: FilterChip[] = [];\n for (const filter of listConfig.filters) {\n const raw = getFilterValue(filter, state.where);\n const displayValue = getFilterDisplayValue(filter, raw, {\n enumLabel: (value) => {\n if (filter.kind !== 'enum') {\n return value;\n }\n const match = filter.options.find((option) => {\n return option.value === value;\n });\n if (match != null) {\n return resolveLabel(match.label, tApp);\n }\n return value;\n },\n booleanLabel: (value) => {\n if (filter.kind === 'boolean') {\n if (value && filter.trueLabel != null) {\n return resolveLabel(filter.trueLabel, tApp);\n }\n if (!value && filter.falseLabel != null) {\n return resolveLabel(filter.falseLabel, tApp);\n }\n }\n if (value) {\n return t('filters.boolean.yes');\n }\n return t('filters.boolean.no');\n },\n fallbackBooleanLabels: {\n yes: t('filters.boolean.yes'),\n no: t('filters.boolean.no'),\n },\n });\n\n if (displayValue != null) {\n let idValue = String(raw);\n if (Array.isArray(raw)) {\n idValue = raw.join(',');\n }\n const label = (\n <span>\n {resolveLabel(filter.label, tApp)}: {displayValue}\n </span>\n );\n out.push({\n id: `${filter.id}:${idValue}`,\n label,\n onRemove: () => {\n const key = filter.whereKey ?? filter.id;\n const nextWhere = setWhereValue(\n state.where,\n key,\n null,\n filter.path,\n );\n pushState({ ...state, where: nextWhere });\n },\n });\n }\n }\n return out;\n }, [listConfig.filters, pushState, state, t, tApp]);\n\n const handleClearAll = useCallback(() => {\n pushState({\n ...listDefaults,\n });\n }, [listDefaults, pushState]);\n const [isFilterDrawerOpen, setIsFilterDrawerOpen] = useState(false);\n const [filterSearch, setFilterSearch] = useState('');\n\n const [pickerDialog, setPickerDialog] = useState<{\n entity: string;\n whereKey: keyof RuntimeWhere;\n label: string;\n path?: readonly string[];\n scope?: BackofficePickerScope<Record<string, unknown>>;\n } | null>(null);\n\n const renderFilterControl = useCallback(\n (filter: BackofficeFilterSpec<RuntimeWhere>): JSX.Element => {\n const key = filter.whereKey ?? filter.id;\n const candidate = getFilterValue(filter, state.where);\n let value = '';\n if (typeof candidate === 'string') {\n value = candidate;\n }\n if (typeof candidate === 'number' && Number.isFinite(candidate)) {\n value = String(candidate);\n }\n\n const filterLabelText = resolveLabel(filter.label, tApp);\n\n if (filter.kind === 'text') {\n const placeholderLabelText =\n filter.placeholderLabel != null\n ? resolveLabel(filter.placeholderLabel, tApp)\n : filterLabelText;\n let placeholder = t('filters.placeholders.search', {\n label: placeholderLabelText,\n });\n if (filter.placeholderText != null) {\n placeholder = resolveLabel(filter.placeholderText, tApp);\n }\n return (\n <DeferredFilterSearchInput\n value={toDatetimeInputValue(value)}\n onApply={(next) => {\n const normalized = fromDatetimeInputValue(next);\n const nextWhere = setWhereValue(\n state.where,\n key,\n normalized,\n filter.path,\n );\n pushState({ ...state, where: nextWhere });\n }}\n placeholder={placeholder}\n ariaLabel={placeholder}\n className={styles.filterInput}\n />\n );\n }\n\n if (filter.kind === 'datetime') {\n const placeholderLabelText =\n filter.placeholderLabel != null\n ? resolveLabel(filter.placeholderLabel, tApp)\n : filterLabelText;\n let placeholder = t('filters.placeholders.search', {\n label: placeholderLabelText,\n });\n if (filter.placeholderText != null) {\n placeholder = resolveLabel(filter.placeholderText, tApp);\n }\n return (\n <DeferredFilterSearchInput\n value={value}\n onApply={(next) => {\n const nextWhere = setWhereValue(\n state.where,\n key,\n next,\n filter.path,\n );\n pushState({ ...state, where: nextWhere });\n }}\n placeholder={placeholder}\n ariaLabel={placeholder}\n className={styles.filterInput}\n type=\"datetime-local\"\n />\n );\n }\n\n if (filter.kind === 'number') {\n const placeholderLabelText =\n filter.placeholderLabel != null\n ? resolveLabel(filter.placeholderLabel, tApp)\n : filterLabelText;\n let placeholder = t('filters.placeholders.search', {\n label: placeholderLabelText,\n });\n if (filter.placeholderText != null) {\n placeholder = resolveLabel(filter.placeholderText, tApp);\n }\n return (\n <DeferredFilterSearchInput\n value={value}\n onApply={(next) => {\n const normalized = next.trim();\n const parsed = normalized === '' ? null : Number(normalized);\n const nextWhere = setWhereValue(\n state.where,\n key,\n Number.isFinite(parsed) ? parsed : null,\n filter.path,\n );\n pushState({ ...state, where: nextWhere });\n }}\n placeholder={placeholder}\n ariaLabel={placeholder}\n className={styles.filterInput}\n inputMode={filter.inputMode ?? 'numeric'}\n type=\"text\"\n />\n );\n }\n\n if (filter.kind === 'enum') {\n const options = [\n {\n id: 'any',\n value: '',\n label: t('filters.all', {\n label: filterLabelText,\n }),\n },\n ...filter.options.map((option) => {\n return {\n id: option.value,\n value: option.value,\n label: resolveLabel(option.label, tApp),\n };\n }),\n ];\n\n return (\n <SimpleSelect\n options={options}\n value={value}\n size=\"small\"\n ariaLabel={filterLabelText}\n onChange={(next) => {\n const nextWhere = setWhereValue(\n state.where,\n key,\n next,\n filter.path,\n );\n pushState({ ...state, where: nextWhere });\n }}\n />\n );\n }\n\n if (filter.kind === 'boolean') {\n let current: boolean | null = null;\n if (typeof candidate === 'boolean') {\n current = candidate;\n }\n\n let selectValue = '';\n if (current === true) {\n selectValue = 'true';\n }\n if (current === false) {\n selectValue = 'false';\n }\n\n const trueLabel =\n filter.trueLabel != null\n ? resolveLabel(filter.trueLabel, tApp)\n : t('filters.boolean.yes');\n const falseLabel =\n filter.falseLabel != null\n ? resolveLabel(filter.falseLabel, tApp)\n : t('filters.boolean.no');\n const options = [\n {\n id: 'any',\n value: '',\n label: t('filters.all', {\n label: filterLabelText,\n }),\n },\n {\n id: 'true',\n value: 'true',\n label: trueLabel,\n },\n {\n id: 'false',\n value: 'false',\n label: falseLabel,\n },\n ];\n\n return (\n <SimpleSelect\n options={options}\n value={selectValue}\n size=\"small\"\n ariaLabel={filterLabelText}\n onChange={(next) => {\n let parsed: boolean | null = null;\n if (next === 'true') {\n parsed = true;\n }\n if (next === 'false') {\n parsed = false;\n }\n const nextWhere = setWhereValue(\n state.where,\n key,\n parsed,\n filter.path,\n );\n pushState({ ...state, where: nextWhere });\n }}\n />\n );\n }\n\n const pickerScope = (() => {\n if (filter.pickerScope == null) {\n return undefined;\n }\n if (typeof filter.pickerScope === 'function') {\n return filter.pickerScope(state.where);\n }\n return filter.pickerScope;\n })();\n let currentId: string | null = null;\n if (typeof candidate === 'string') {\n currentId = candidate;\n }\n\n const renderField = (\n displayValue: string | null = null,\n isResolving = false,\n ) => {\n const normalizedDisplayValue = displayValue?.trim() ?? '';\n return (\n <EntityIdFilterField\n label={filterLabelText}\n value={currentId}\n displayValue={normalizedDisplayValue}\n isResolving={isResolving}\n placeholder={t('filters.placeholders.anyEntity', {\n label: filterLabelText,\n })}\n onPick={() => {\n setPickerDialog({\n entity: filter.entity,\n whereKey: key,\n label: filterLabelText,\n path: filter.path,\n scope: pickerScope,\n });\n }}\n onClear={() => {\n const nextWhere = setWhereValue(\n state.where,\n key,\n null,\n filter.path,\n );\n pushState({ ...state, where: nextWhere });\n }}\n />\n );\n };\n\n if (currentId == null || currentId.trim() === '') {\n return renderField();\n }\n\n return (\n <EntityFilterValueText entityId={filter.entity} id={currentId}>\n {(label, valueState) => {\n const isResolving = valueState?.status === 'loading';\n return renderField(\n isResolving ? t('common.loading') : label,\n isResolving,\n );\n }}\n </EntityFilterValueText>\n );\n },\n [pushState, state, t, tApp],\n );\n\n const hasPlacementConfig = useMemo(() => {\n return listConfig.filters.some((filter) => {\n return filter.placement != null;\n });\n }, [listConfig.filters]);\n\n const quickFilters = useMemo(() => {\n if (listConfig.filters.length === 0) {\n return [];\n }\n const maxPromotedFilters = listConfig.ui?.toolbar?.maxPromotedFilters ?? 3;\n if (hasPlacementConfig) {\n return listConfig.filters.filter((filter) => {\n return filter.placement === 'quick' || filter.placement === 'both';\n });\n }\n return listConfig.filters.slice(0, maxPromotedFilters);\n }, [listConfig.filters, listConfig.ui?.toolbar, hasPlacementConfig]);\n\n const drawerFilters = useMemo(() => {\n return listConfig.filters.filter((filter) => {\n if (filter.placement == null) {\n return true;\n }\n return filter.placement === 'drawer' || filter.placement === 'both';\n });\n }, [listConfig.filters]);\n\n const searchFilter = useMemo(() => {\n return quickFilters.find((filter) => {\n return filter.kind === 'text';\n });\n }, [quickFilters]);\n\n const quickFiltersNode = useMemo(() => {\n const visibleQuickFilters = quickFilters.filter((filter) => {\n return filter !== searchFilter;\n });\n\n if (visibleQuickFilters.length === 0) {\n return null;\n }\n\n return (\n <div className={styles.controlsRow}>\n {visibleQuickFilters.map((filter) => {\n return <span key={filter.id}>{renderFilterControl(filter)}</span>;\n })}\n </div>\n );\n }, [quickFilters, renderFilterControl, searchFilter]);\n\n const searchNode = useMemo(() => {\n if (searchFilter == null) {\n return null;\n }\n return renderFilterControl(searchFilter);\n }, [renderFilterControl, searchFilter]);\n\n const sortNode = useMemo(() => {\n if (listConfig.sorts.length === 0) {\n return null;\n }\n const firstSort = listConfig.sorts[0];\n if (firstSort == null) {\n return null;\n }\n const options = listConfig.sorts.map((s) => {\n return { id: s.id, value: s.id, label: resolveLabel(s.label, tApp) };\n });\n return (\n <SimpleSelect\n options={options}\n value={state.sort ?? firstSort.id}\n size=\"small\"\n ariaLabel={t('list.sort.label')}\n onChange={(next) => {\n pushState({\n ...state,\n sort: next,\n });\n }}\n />\n );\n }, [listConfig.sorts, pushState, state, t, tApp]);\n\n const chipsNode = useMemo(() => {\n if (chips.length === 0) {\n return null;\n }\n return <FilterChipRow chips={chips} onClearAll={handleClearAll} />;\n }, [chips, handleClearAll]);\n\n const drawerSections = useMemo(() => {\n if (drawerFilters.length === 0) {\n return [];\n }\n\n const normalizedQuery = filterSearch.trim().toLowerCase();\n const items: { id: string; node: JSX.Element }[] = [];\n\n for (const filter of drawerFilters) {\n const resolvedLabel = resolveLabel(filter.label, tApp);\n const matchesQuery =\n normalizedQuery === '' ||\n resolvedLabel.toLowerCase().includes(normalizedQuery);\n\n if (matchesQuery) {\n items.push({\n id: filter.id,\n node: (\n <BackofficeFilterField label={resolvedLabel}>\n {renderFilterControl(filter)}\n </BackofficeFilterField>\n ),\n });\n }\n }\n\n if (items.length === 0) {\n return [];\n }\n\n return [\n {\n id: 'backoffice.filters.sections.default',\n title: t('filters.sections.default'),\n items,\n },\n ];\n }, [drawerFilters, filterSearch, renderFilterControl, t, tApp]);\n\n const allFiltersNode = useMemo(() => {\n if (drawerFilters.length === 0) {\n return null;\n }\n const activeCount = chips.length;\n let label = t('filters.trigger');\n if (activeCount > 0) {\n label = t('filters.triggerWithCount', {\n count: activeCount,\n });\n }\n return (\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={() => {\n setIsFilterDrawerOpen(true);\n }}\n >\n {label}\n </Button>\n );\n }, [chips.length, drawerFilters.length, t]);\n\n const filterDrawerEmptyLabel =\n filterSearch.trim() === ''\n ? undefined\n : t('filters.drawer.emptySearchResults');\n\n const filterDrawerNode = (\n <BackofficeFilterDrawer\n isOpen={isFilterDrawerOpen}\n onClose={() => {\n setIsFilterDrawerOpen(false);\n setFilterSearch('');\n }}\n sections={drawerSections}\n searchValue={filterSearch}\n onSearchChange={(next) => {\n setFilterSearch(next);\n }}\n onReset={handleClearAll}\n emptyLabel={filterDrawerEmptyLabel}\n />\n );\n\n const resolvedEmptyState = useMemo((): JSX.Element => {\n if (emptyState != null) {\n return emptyState;\n }\n\n if (isLoadingInitial) {\n return (\n <BackofficeTableSkeleton\n variant=\"embedded\"\n ariaLabel={t('common.loading')}\n />\n );\n }\n\n if (chips.length > 0) {\n return (\n <BackofficeEmptyState\n title={t('emptyState.listEmpty.title')}\n description={t('emptyState.listEmptyFiltered.description')}\n actions={\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={handleClearAll}\n >\n {t('emptyState.listEmptyFiltered.actions.reset')}\n </Button>\n }\n />\n );\n }\n\n return (\n <BackofficeEmptyState\n title={t('emptyState.listEmpty.title')}\n description={t('emptyState.listEmpty.description')}\n />\n );\n }, [chips.length, emptyState, handleClearAll, isLoadingInitial, t]);\n\n const tableFooterMeta = useMemo(() => {\n if (typeof totalCount !== 'number') {\n if (rows.length === 0) {\n return null;\n }\n return (\n <span>\n {t('list.loaded', {\n count: rows.length,\n })}\n </span>\n );\n }\n return (\n <span>\n {t('list.showing', {\n shown: rows.length,\n total: totalCount,\n })}\n </span>\n );\n }, [rows.length, t, totalCount]);\n\n const runtimeConfig = useMemo(() => {\n const resolvedDisplayMode =\n listConfig.ui?.displayMode ?? listConfig.responsive?.mode ?? 'auto';\n return resolveBackofficeListRuntimeConfig({\n kind: listConfig.kind,\n displayMode: resolvedDisplayMode,\n ui: listConfig.ui,\n });\n }, [listConfig.kind, listConfig.responsive?.mode, listConfig.ui]);\n\n const hasKnownRemainingRows =\n typeof totalCount === 'number' && rows.length < totalCount;\n const hasInconsistentPageInfo = hasKnownRemainingRows && !hasNextPage;\n\n useEffect(() => {\n if (\n !hasInconsistentPageInfo ||\n !runtimeConfig.infiniteScroll.showInconsistentPageInfo ||\n !isDevEnv()\n ) {\n return;\n }\n // eslint-disable-next-line no-console\n console.warn(\n 'Backoffice list received inconsistent pageInfo: loaded rows are lower than totalCount but hasNextPage is false.',\n {\n entityId: config.id,\n loadedCount: rows.length,\n totalCount,\n },\n );\n }, [\n config.id,\n hasInconsistentPageInfo,\n rows.length,\n runtimeConfig.infiniteScroll.showInconsistentPageInfo,\n totalCount,\n ]);\n\n const shouldVirtualizeTable =\n props.virtualize === true || runtimeConfig.virtualization.enabled;\n\n const { sentinelRef } = useBackofficeInfiniteScrollSentinel({\n enabled: !shouldVirtualizeTable && runtimeConfig.infiniteScroll.enabled,\n hasNextPage,\n isLoading: isLoadingMore,\n onIntersect: onLoadMore,\n rootMargin: runtimeConfig.infiniteScroll.rootMargin,\n threshold: runtimeConfig.infiniteScroll.threshold,\n });\n\n const headerTitle = header?.title ?? resolveLabel(listConfig.title, tApp);\n const headerSubtitle = header?.subtitle;\n\n const actionColumn = columnsWithPrimary.find((column) => {\n return column.mobileRole === 'action' || column.id === 'actions';\n });\n const listMode =\n listConfig.ui?.displayMode ?? listConfig.responsive?.mode ?? 'auto';\n const listDensity =\n listConfig.ui?.density ?? listConfig.responsive?.density ?? 'compact';\n\n const tableInnerNode = shouldVirtualizeTable ? (\n <VirtualizedConnectionTable\n columns={columnsWithPrimary}\n rows={rows}\n getRowId={getRowId}\n emptyState={resolvedEmptyState}\n className={denseTableClass}\n gridTemplateColumns={gridTemplateColumns}\n virtualization={runtimeConfig.virtualization}\n infiniteScroll={{\n enabled: runtimeConfig.infiniteScroll.enabled,\n thresholdPx: runtimeConfig.infiniteScroll.thresholdPx,\n autoLoad: runtimeConfig.infiniteScroll.autoLoad,\n }}\n hasNextPage={hasNextPage}\n isLoadingMore={isLoadingMore}\n onLoadMore={onLoadMore}\n bodyScrollMode={BACKOFFICE_LIST_BODY_SCROLL_MODE}\n />\n ) : (\n <ResponsiveRecordList\n columns={columnsWithPrimary}\n rows={rows}\n getRowId={getRowId}\n emptyState={resolvedEmptyState}\n className={denseTableClass}\n gridTemplateColumns={gridTemplateColumns}\n mode={listMode}\n density={listDensity}\n bodyScrollMode={BACKOFFICE_LIST_BODY_SCROLL_MODE}\n bodyFooterNode={\n runtimeConfig.infiniteScroll.enabled ? (\n <div ref={sentinelRef} aria-hidden=\"true\" />\n ) : null\n }\n renderAction={(row) => {\n return actionColumn?.cell(row) ?? null;\n }}\n />\n );\n\n const tableNodeWithErrorBoundary = (\n <BackofficeErrorBoundary\n fallback={(args: { error: unknown; reset: () => void }) => {\n const { reset } = args;\n\n const retry = (): void => {\n reset();\n if (onRefresh != null) {\n onRefresh();\n }\n };\n\n return (\n <InlineBanner\n tone=\"danger\"\n title={t('list.errors.title')}\n actions={\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={retry}\n >\n {t('list.actions.retry')}\n </Button>\n }\n >\n {t('list.errors.tableFailed')}\n </InlineBanner>\n );\n }}\n >\n {tableInnerNode}\n </BackofficeErrorBoundary>\n );\n\n const filtersBarNode = showFilters ? (\n <>\n <BackofficeToolbar\n search={searchNode}\n primaryFilters={quickFiltersNode}\n filterDrawerTrigger={allFiltersNode}\n sort={sortNode}\n utilityActions={\n onRefresh == null ? null : (\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n isLoading={isRefreshing}\n loadingLabel={t('list.actions.refreshing')}\n onClick={() => {\n onRefresh();\n }}\n >\n {t('list.actions.refresh')}\n </Button>\n )\n }\n chips={chipsNode}\n density=\"compact\"\n />\n {filterDrawerNode}\n </>\n ) : null;\n\n const tableNode = (\n <div className={styles.tableHost}>\n {tableNodeWithErrorBoundary}\n <EntityIdPickerDialog\n isOpen={pickerDialog != null}\n entity={pickerDialog?.entity ?? config.id}\n title={pickerDialog?.label ?? t('picker.title')}\n scope={pickerDialog?.scope}\n onClose={() => {\n setPickerDialog(null);\n }}\n onSelectId={(id) => {\n if (pickerDialog == null) {\n return;\n }\n const nextWhere = setWhereValue(\n state.where,\n pickerDialog.whereKey,\n id,\n pickerDialog.path,\n );\n pushState({ ...state, where: nextWhere });\n }}\n />\n </div>\n );\n\n const shouldRenderTableFooter =\n rows.length > 0 || isLoadingMore || hasNextPage;\n\n const tableFooterNode = shouldRenderTableFooter ? (\n <>\n <BackofficeListFooter\n mode=\"status\"\n loadedCount={rows.length}\n totalCount={totalCount}\n hasNextPage={hasNextPage}\n isLoading={isLoadingMore}\n pageInfoState={\n hasInconsistentPageInfo\n ? 'inconsistent'\n : isLoadingMore\n ? 'loading'\n : hasNextPage\n ? 'ready'\n : 'complete'\n }\n labels={{\n loaded: tableFooterMeta,\n loading: t('list.loadMore.loading'),\n end: t('list.loadMore.end'),\n }}\n />\n </>\n ) : null;\n\n if (variant === 'embedded') {\n return (\n <BackofficeListFilterProvider\n config={config}\n state={state}\n pushState={pushState}\n >\n <div className={styles.embeddedContainer}>\n <div className={styles.embeddedHeader}>{headerTitle}</div>\n {filtersBarNode}\n {statusBanner}\n {tableNode}\n {tableFooterNode}\n </div>\n </BackofficeListFilterProvider>\n );\n }\n\n return (\n <BackofficeListFilterProvider\n config={config}\n state={state}\n pushState={pushState}\n >\n <ListPageTemplate\n headerNode={\n <BackofficePageHeader\n title={headerTitle}\n subtitle={headerSubtitle}\n actions={headerActions}\n />\n }\n toolbarNode={filtersBarNode}\n statusNode={statusBanner}\n tableNode={tableNode}\n tableFooterNode={tableFooterNode}\n presentation=\"flat\"\n bodyScrollMode={BACKOFFICE_LIST_BODY_SCROLL_MODE}\n />\n </BackofficeListFilterProvider>\n );\n};\n\nexport default BackofficeEntityListScaffold;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DA,IAAM,KAAgB,GAAkB,MAC/B,EAAM,EAAK,EAGd,KACJ,GACA,MAEI,EAAO,eAAe,QAAQ,KAAS,OAClC,EAAO,YAAY,EAAM,GAI3B,EAAe,GADT,EAAO,YAAY,EAAO,IACL,EAAO,KAAK,EAG1C,MACJ,GACA,GACA,MAKqB;CACrB,IAAI,KAAO,MACT,OAAO;CAGT,IAAI,MAAM,QAAQ,EAAI,EAAE;EACtB,IAAM,IAAa,EAChB,KAAK,MAAU;GAId,IAHI,KAAS,QAIX,OAAO,KAAU,YACjB,OAAO,KAAU,YACjB,OAAO,KAAU,WAEjB,OAAO;GAET,IAAM,IAAQ,OAAO,EAAM,CAAC,MAAM;GAIlC,OAHI,MAAU,KACL,OAEF;IACP,CACD,QAAQ,MACA,KAAS,KAChB;EAKJ,OAHI,EAAW,WAAW,IACjB,OAEF,EAAW,KAAK,KAAK;;CAG9B,IAAI,OAAO,KAAQ,WAOjB,OANI,EAAO,SAAS,YACX,EAAQ,aAAa,EAAI,GAE9B,IACK,EAAQ,sBAAsB,MAEhC,EAAQ,sBAAsB;CAGvC,IAAI,OAAO,KAAQ,YAAY,OAAO,KAAQ,UAC5C,OAAO;CAGT,IAAM,IAAY,OAAO,EAAI,CAAC,MAAM;CAapC,OAZI,MAAc,KACT,OAGL,EAAO,SAAS,aACX,kBAAC,GAAD;EAAmB,UAAU,EAAO;EAAQ,IAAI;EAAa,CAAA,GAGlE,EAAO,SAAS,SACX,EAAQ,UAAU,EAAU,GAG9B;GAGH,MAAwB,MAA0B;CACtD,IAAM,IAAO,IAAI,KAAK,EAAM;CAC5B,IAAI,OAAO,MAAM,EAAK,SAAS,CAAC,EAC9B,OAAO;CAET,IAAM,IAAW,EAAK,mBAAmB,GAAG;CAC5C,OAAO,IAAI,KAAK,EAAK,SAAS,GAAG,EAAS,CAAC,aAAa,CAAC,MAAM,GAAG,GAAG;GAGjE,MAA0B,MAA0B;CACxD,IAAM,IAAa,EAAM,MAAM;CAC/B,IAAI,MAAe,IACjB,OAAO;CAET,IAAM,IAAO,IAAI,KAAK,EAAW;CAIjC,OAHI,OAAO,MAAM,EAAK,SAAS,CAAC,GACvB,IAEF,EAAK,aAAa;GAiCd,KACX,MACuB;CACvB,IAAM,EAAE,GAAG,MAAS,IAAgB,EAC9B,EAAE,SAAM,GAA+B,EACvC,EACJ,WACA,UACA,cACA,SACA,aACA,YACA,wBACA,gBACA,kBACA,mBAAe,IACf,eACA,cACA,eACA,eACA,iBACA,WACA,mBACA,uBAAmB,IACnB,cAAU,QACV,kBAAc,OACZ,GACE,IAAa,EAAO,MAEpB,KAAe,EAAO,gBAC1B,EAAW,gBAAgB;EAAE,OAAO;EAAM,MAAM;EAAM,EAElD,IAAqB,QACN,EAAQ,MAAM,MACxB,EAAI,cAAc,GAEvB,IAAc,EAAQ,WAAW,IAC5B,IAEF,EAAQ,KAAK,GAAK,MAAU;EACjC,IAAM,EAAE,cAAW;EAInB,OAHI,MAAU,IACL;GAAE,GAAG;GAAK,WAAW;GAAM;GAAQ,GAErC;GAAE,GAAG;GAAK;GAAQ;GACzB,EACD,CAAC,EAAQ,CAAC,EAEP,IAAQ,QAAqC;EACjD,IAAM,IAAoB,EAAE;EAC5B,KAAK,IAAM,KAAU,EAAW,SAAS;GACvC,IAAM,IAAM,EAAe,GAAQ,EAAM,MAAM,EACzC,IAAe,GAAsB,GAAQ,GAAK;IACtD,YAAY,MAAU;KACpB,IAAI,EAAO,SAAS,QAClB,OAAO;KAET,IAAM,IAAQ,EAAO,QAAQ,MAAM,MAC1B,EAAO,UAAU,EACxB;KAIF,OAHI,KAAS,OAGN,IAFE,EAAa,EAAM,OAAO,EAAK;;IAI1C,eAAe,MAAU;KACvB,IAAI,EAAO,SAAS,WAAW;MAC7B,IAAI,KAAS,EAAO,aAAa,MAC/B,OAAO,EAAa,EAAO,WAAW,EAAK;MAE7C,IAAI,CAAC,KAAS,EAAO,cAAc,MACjC,OAAO,EAAa,EAAO,YAAY,EAAK;;KAMhD,OAFS,EADL,IACO,wBAEF,qBAFwB;;IAInC,uBAAuB;KACrB,KAAK,EAAE,sBAAsB;KAC7B,IAAI,EAAE,qBAAqB;KAC5B;IACF,CAAC;GAEF,IAAI,KAAgB,MAAM;IACxB,IAAI,IAAU,OAAO,EAAI;IACzB,AAAI,MAAM,QAAQ,EAAI,KACpB,IAAU,EAAI,KAAK,IAAI;IAEzB,IAAM,IACJ,kBAAC,QAAD,EAAA,UAAA;KACG,EAAa,EAAO,OAAO,EAAK;KAAC;KAAG;KAChC,EAAA,CAAA;IAET,EAAI,KAAK;KACP,IAAI,GAAG,EAAO,GAAG,GAAG;KACpB;KACA,gBAAgB;MACd,IAAM,IAAM,EAAO,YAAY,EAAO,IAChC,IAAY,EAChB,EAAM,OACN,GACA,MACA,EAAO,KACR;MACD,EAAU;OAAE,GAAG;OAAO,OAAO;OAAW,CAAC;;KAE5C,CAAC;;;EAGN,OAAO;IACN;EAAC,EAAW;EAAS;EAAW;EAAO;EAAG;EAAK,CAAC,EAE7C,IAAiB,QAAkB;EACvC,EAAU,EACR,GAAG,IACJ,CAAC;IACD,CAAC,IAAc,EAAU,CAAC,EACvB,CAAC,IAAoB,MAAyB,EAAS,GAAM,EAC7D,CAAC,GAAc,MAAmB,EAAS,GAAG,EAE9C,CAAC,GAAc,MAAmB,EAM9B,KAAK,EAET,IAAsB,GACzB,MAA4D;EAC3D,IAAM,IAAM,EAAO,YAAY,EAAO,IAChC,IAAY,EAAe,GAAQ,EAAM,MAAM,EACjD,IAAQ;EAIZ,AAHI,OAAO,KAAc,aACvB,IAAQ,IAEN,OAAO,KAAc,YAAY,OAAO,SAAS,EAAU,KAC7D,IAAQ,OAAO,EAAU;EAG3B,IAAM,IAAkB,EAAa,EAAO,OAAO,EAAK;EAExD,IAAI,EAAO,SAAS,QAAQ;GAK1B,IAAI,IAAc,EAAE,+BAA+B,EACjD,OAJA,EAAO,oBAAoB,OAEvB,IADA,EAAa,EAAO,kBAAkB,EAAK,EAIhD,CAAC;GAIF,OAHI,EAAO,mBAAmB,SAC5B,IAAc,EAAa,EAAO,iBAAiB,EAAK,GAGxD,kBAAC,GAAD;IACE,OAAO,GAAqB,EAAM;IAClC,UAAU,MAAS;KACjB,IAAM,IAAa,GAAuB,EAAK,EACzC,IAAY,EAChB,EAAM,OACN,GACA,GACA,EAAO,KACR;KACD,EAAU;MAAE,GAAG;MAAO,OAAO;MAAW,CAAC;;IAE9B;IACb,WAAW;IACX,WAAW;IACX,CAAA;;EAIN,IAAI,EAAO,SAAS,YAAY;GAK9B,IAAI,IAAc,EAAE,+BAA+B,EACjD,OAJA,EAAO,oBAAoB,OAEvB,IADA,EAAa,EAAO,kBAAkB,EAAK,EAIhD,CAAC;GAIF,OAHI,EAAO,mBAAmB,SAC5B,IAAc,EAAa,EAAO,iBAAiB,EAAK,GAGxD,kBAAC,GAAD;IACS;IACP,UAAU,MAAS;KACjB,IAAM,IAAY,EAChB,EAAM,OACN,GACA,GACA,EAAO,KACR;KACD,EAAU;MAAE,GAAG;MAAO,OAAO;MAAW,CAAC;;IAE9B;IACb,WAAW;IACX,WAAW;IACX,MAAK;IACL,CAAA;;EAIN,IAAI,EAAO,SAAS,UAAU;GAK5B,IAAI,IAAc,EAAE,+BAA+B,EACjD,OAJA,EAAO,oBAAoB,OAEvB,IADA,EAAa,EAAO,kBAAkB,EAAK,EAIhD,CAAC;GAIF,OAHI,EAAO,mBAAmB,SAC5B,IAAc,EAAa,EAAO,iBAAiB,EAAK,GAGxD,kBAAC,GAAD;IACS;IACP,UAAU,MAAS;KACjB,IAAM,IAAa,EAAK,MAAM,EACxB,IAAS,MAAe,KAAK,OAAO,OAAO,EAAW,EACtD,IAAY,EAChB,EAAM,OACN,GACA,OAAO,SAAS,EAAO,GAAG,IAAS,MACnC,EAAO,KACR;KACD,EAAU;MAAE,GAAG;MAAO,OAAO;MAAW,CAAC;;IAE9B;IACb,WAAW;IACX,WAAW;IACX,WAAW,EAAO,aAAa;IAC/B,MAAK;IACL,CAAA;;EAIN,IAAI,EAAO,SAAS,QAkBlB,OACE,kBAAC,GAAD;GACW,SAAA,CAlBX;IACE,IAAI;IACJ,OAAO;IACP,OAAO,EAAE,eAAe,EACtB,OAAO,GACR,CAAC;IACH,EACD,GAAG,EAAO,QAAQ,KAAK,OACd;IACL,IAAI,EAAO;IACX,OAAO,EAAO;IACd,OAAO,EAAa,EAAO,OAAO,EAAK;IACxC,EACD,CAKS;GACF;GACP,MAAK;GACL,WAAW;GACX,WAAW,MAAS;IAClB,IAAM,IAAY,EAChB,EAAM,OACN,GACA,GACA,EAAO,KACR;IACD,EAAU;KAAE,GAAG;KAAO,OAAO;KAAW,CAAC;;GAE3C,CAAA;EAIN,IAAI,EAAO,SAAS,WAAW;GAC7B,IAAI,IAA0B;GAC9B,AAAI,OAAO,KAAc,cACvB,IAAU;GAGZ,IAAI,IAAc;GAIlB,AAHI,MAAY,OACd,IAAc,SAEZ,MAAY,OACd,IAAc;GAGhB,IAAM,IACJ,EAAO,aAAa,OAEhB,EAAE,sBAAsB,GADxB,EAAa,EAAO,WAAW,EAAK,EAEpC,IACJ,EAAO,cAAc,OAEjB,EAAE,qBAAqB,GADvB,EAAa,EAAO,YAAY,EAAK;GAsB3C,OACE,kBAAC,GAAD;IACW,SAAA;KArBX;MACE,IAAI;MACJ,OAAO;MACP,OAAO,EAAE,eAAe,EACtB,OAAO,GACR,CAAC;MACH;KACD;MACE,IAAI;MACJ,OAAO;MACP,OAAO;MACR;KACD;MACE,IAAI;MACJ,OAAO;MACP,OAAO;MACR;KAKU;IACT,OAAO;IACP,MAAK;IACL,WAAW;IACX,WAAW,MAAS;KAClB,IAAI,IAAyB;KAI7B,AAHI,MAAS,WACX,IAAS,KAEP,MAAS,YACX,IAAS;KAEX,IAAM,IAAY,EAChB,EAAM,OACN,GACA,GACA,EAAO,KACR;KACD,EAAU;MAAE,GAAG;MAAO,OAAO;MAAW,CAAC;;IAE3C,CAAA;;EAIN,IAAM,WAAqB;GACrB,MAAO,eAAe,MAM1B,OAHI,OAAO,EAAO,eAAgB,aACzB,EAAO,YAAY,EAAM,MAAM,GAEjC,EAAO;MACZ,EACA,IAA2B;EAC/B,AAAI,OAAO,KAAc,aACvB,IAAY;EAGd,IAAM,KACJ,IAA8B,MAC9B,IAAc,OACX;GACH,IAAM,IAAyB,GAAc,MAAM,IAAI;GACvD,OACE,kBAAC,GAAD;IACE,OAAO;IACP,OAAO;IACP,cAAc;IACD;IACb,aAAa,EAAE,kCAAkC,EAC/C,OAAO,GACR,CAAC;IACF,cAAc;KACZ,GAAgB;MACd,QAAQ,EAAO;MACf,UAAU;MACV,OAAO;MACP,MAAM,EAAO;MACb,OAAO;MACR,CAAC;;IAEJ,eAAe;KACb,IAAM,IAAY,EAChB,EAAM,OACN,GACA,MACA,EAAO,KACR;KACD,EAAU;MAAE,GAAG;MAAO,OAAO;MAAW,CAAC;;IAE3C,CAAA;;EAQN,OAJI,KAAa,QAAQ,EAAU,MAAM,KAAK,KACrC,GAAa,GAIpB,kBAAC,GAAD;GAAuB,UAAU,EAAO;GAAQ,IAAI;cAChD,GAAO,MAAe;IACtB,IAAM,IAAc,GAAY,WAAW;IAC3C,OAAO,EACL,IAAc,EAAE,iBAAiB,GAAG,GACpC,EACD;;GAEmB,CAAA;IAG5B;EAAC;EAAW;EAAO;EAAG;EAAK,CAC5B,EAEK,KAAqB,QAClB,EAAW,QAAQ,MAAM,MACvB,EAAO,aAAa,KAC3B,EACD,CAAC,EAAW,QAAQ,CAAC,EAElB,IAAe,QAAc;EACjC,IAAI,EAAW,QAAQ,WAAW,GAChC,OAAO,EAAE;EAEX,IAAM,IAAqB,EAAW,IAAI,SAAS,sBAAsB;EAMzE,OALI,KACK,EAAW,QAAQ,QAAQ,MACzB,EAAO,cAAc,WAAW,EAAO,cAAc,OAC5D,GAEG,EAAW,QAAQ,MAAM,GAAG,EAAmB;IACrD;EAAC,EAAW;EAAS,EAAW,IAAI;EAAS;EAAmB,CAAC,EAE9D,IAAgB,QACb,EAAW,QAAQ,QAAQ,MAC5B,EAAO,aAAa,OACf,KAEF,EAAO,cAAc,YAAY,EAAO,cAAc,OAC7D,EACD,CAAC,EAAW,QAAQ,CAAC,EAElB,IAAe,QACZ,EAAa,MAAM,MACjB,EAAO,SAAS,OACvB,EACD,CAAC,EAAa,CAAC,EAEZ,KAAmB,QAAc;EACrC,IAAM,IAAsB,EAAa,QAAQ,MACxC,MAAW,EAClB;EAMF,OAJI,EAAoB,WAAW,IAC1B,OAIP,kBAAC,OAAD;GAAK,WAAW;aACb,EAAoB,KAAK,MACjB,kBAAC,QAAD,EAAA,UAAuB,EAAoB,EAAO,EAAQ,EAA/C,EAAO,GAAwC,CACjE;GACE,CAAA;IAEP;EAAC;EAAc;EAAqB;EAAa,CAAC,EAE/C,KAAa,QACb,KAAgB,OACX,OAEF,EAAoB,EAAa,EACvC,CAAC,GAAqB,EAAa,CAAC,EAEjC,KAAW,QAAc;EAC7B,IAAI,EAAW,MAAM,WAAW,GAC9B,OAAO;EAET,IAAM,IAAY,EAAW,MAAM;EAOnC,OANI,KAAa,OACR,OAMP,kBAAC,GAAD;GACW,SALG,EAAW,MAAM,KAAK,OAC7B;IAAE,IAAI,EAAE;IAAI,OAAO,EAAE;IAAI,OAAO,EAAa,EAAE,OAAO,EAAK;IAAE,EAIzD;GACT,OAAO,EAAM,QAAQ,EAAU;GAC/B,MAAK;GACL,WAAW,EAAE,kBAAkB;GAC/B,WAAW,MAAS;IAClB,EAAU;KACR,GAAG;KACH,MAAM;KACP,CAAC;;GAEJ,CAAA;IAEH;EAAC,EAAW;EAAO;EAAW;EAAO;EAAG;EAAK,CAAC,EAE3C,KAAY,QACZ,EAAM,WAAW,IACZ,OAEF,kBAAC,IAAD;EAAsB;EAAO,YAAY;EAAkB,CAAA,EACjE,CAAC,GAAO,EAAe,CAAC,EAErB,KAAiB,QAAc;EACnC,IAAI,EAAc,WAAW,GAC3B,OAAO,EAAE;EAGX,IAAM,IAAkB,EAAa,MAAM,CAAC,aAAa,EACnD,IAA6C,EAAE;EAErD,KAAK,IAAM,KAAU,GAAe;GAClC,IAAM,IAAgB,EAAa,EAAO,OAAO,EAAK;GAKtD,CAHE,MAAoB,MACpB,EAAc,aAAa,CAAC,SAAS,EAAgB,KAGrD,EAAM,KAAK;IACT,IAAI,EAAO;IACX,MACE,kBAAC,IAAD;KAAuB,OAAO;eAC3B,EAAoB,EAAO;KACN,CAAA;IAE3B,CAAC;;EAQN,OAJI,EAAM,WAAW,IACZ,EAAE,GAGJ,CACL;GACE,IAAI;GACJ,OAAO,EAAE,2BAA2B;GACpC;GACD,CACF;IACA;EAAC;EAAe;EAAc;EAAqB;EAAG;EAAK,CAAC,EAEzD,KAAiB,QAAc;EACnC,IAAI,EAAc,WAAW,GAC3B,OAAO;EAET,IAAM,IAAc,EAAM,QACtB,IAAQ,EAAE,kBAAkB;EAMhC,OALI,IAAc,MAChB,IAAQ,EAAE,4BAA4B,EACpC,OAAO,GACR,CAAC,GAGF,kBAAC,GAAD;GACE,MAAK;GACL,SAAQ;GACR,MAAK;GACL,eAAe;IACb,GAAsB,GAAK;;aAG5B;GACM,CAAA;IAEV;EAAC,EAAM;EAAQ,EAAc;EAAQ;EAAE,CAAC,EAOrC,KACJ,kBAAC,IAAD;EACE,QAAQ;EACR,eAAe;GAEb,AADA,GAAsB,GAAM,EAC5B,GAAgB,GAAG;;EAErB,UAAU;EACV,aAAa;EACb,iBAAiB,MAAS;GACxB,GAAgB,EAAK;;EAEvB,SAAS;EACT,YAjBF,EAAa,MAAM,KAAK,KACpB,KAAA,IACA,EAAE,oCAAoC;EAgBxC,CAAA,EAGE,KAAqB,QACrB,MAIA,KAEA,kBAAC,IAAD;EACE,SAAQ;EACR,WAAW,EAAE,iBAAiB;EAC9B,CAAA,GAIF,EAAM,SAAS,IAEf,kBAAC,IAAD;EACE,OAAO,EAAE,6BAA6B;EACtC,aAAa,EAAE,2CAA2C;EAC1D,SACE,kBAAC,GAAD;GACE,MAAK;GACL,SAAQ;GACR,MAAK;GACL,SAAS;aAER,EAAE,6CAA6C;GACzC,CAAA;EAEX,CAAA,GAKJ,kBAAC,IAAD;EACE,OAAO,EAAE,6BAA6B;EACtC,aAAa,EAAE,mCAAmC;EAClD,CAAA,GAEH;EAAC,EAAM;EAAQ;EAAY;EAAgB;EAAkB;EAAE,CAAC,EAE7D,KAAkB,QAClB,OAAO,KAAe,WAaxB,kBAAC,QAAD,EAAA,UACG,EAAE,gBAAgB;EACjB,OAAO,EAAK;EACZ,OAAO;EACR,CAAC,EACG,CAAA,GAjBH,EAAK,WAAW,IACX,OAGP,kBAAC,QAAD,EAAA,UACG,EAAE,eAAe,EAChB,OAAO,EAAK,QACb,CAAC,EACG,CAAA,EAWV;EAAC,EAAK;EAAQ;EAAG;EAAW,CAAC,EAE1B,IAAgB,QAAc;EAClC,IAAM,IACJ,EAAW,IAAI,eAAe,EAAW,YAAY,QAAQ;EAC/D,OAAO,GAAmC;GACxC,MAAM,EAAW;GACjB,aAAa;GACb,IAAI,EAAW;GAChB,CAAC;IACD;EAAC,EAAW;EAAM,EAAW,YAAY;EAAM,EAAW;EAAG,CAAC,EAI3D,IADJ,OAAO,KAAe,YAAY,EAAK,SAAS,KACO,CAAC;CAE1D,SAAgB;EAEZ,CAAC,KACD,CAAC,EAAc,eAAe,4BAC9B,CAAC,GAAU,IAKb,QAAQ,KACN,mHACA;GACE,UAAU,EAAO;GACjB,aAAa,EAAK;GAClB;GACD,CACF;IACA;EACD,EAAO;EACP;EACA,EAAK;EACL,EAAc,eAAe;EAC7B;EACD,CAAC;CAEF,IAAM,KACJ,EAAM,eAAe,MAAQ,EAAc,eAAe,SAEtD,EAAE,oBAAgB,EAAoC;EAC1D,SAAS,CAAC,MAAyB,EAAc,eAAe;EAChE;EACA,WAAW;EACX,aAAa;EACb,YAAY,EAAc,eAAe;EACzC,WAAW,EAAc,eAAe;EACzC,CAAC,EAEI,KAAc,GAAQ,SAAS,EAAa,EAAW,OAAO,EAAK,EACnE,KAAiB,GAAQ,UAEzB,KAAe,EAAmB,MAAM,MACrC,EAAO,eAAe,YAAY,EAAO,OAAO,UACvD,EACI,KACJ,EAAW,IAAI,eAAe,EAAW,YAAY,QAAQ,QACzD,KACJ,EAAW,IAAI,WAAW,EAAW,YAAY,WAAW,WA2CxD,KACJ,kBAAC,GAAD;EACE,WAAW,MAAgD;GACzD,IAAM,EAAE,aAAU;GASlB,OACE,kBAAC,IAAD;IACE,MAAK;IACL,OAAO,EAAE,oBAAoB;IAC7B,SACE,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,MAAK;KACL,eAhBkB;MAExB,AADA,GAAO,EACH,KACS;;eAeN,EAAE,qBAAqB;KACjB,CAAA;cAGV,EAAE,0BAA0B;IAChB,CAAA;;YArEA,KACrB,kBAAC,IAAD;GACE,SAAS;GACH;GACI;GACV,YAAY;GACZ,WAAW;GACU;GACrB,gBAAgB,EAAc;GAC9B,gBAAgB;IACd,SAAS,EAAc,eAAe;IACtC,aAAa,EAAc,eAAe;IAC1C,UAAU,EAAc,eAAe;IACxC;GACY;GACE;GACH;GACZ,gBAAgB;GAChB,CAAA,GAEF,kBAAC,IAAD;GACE,SAAS;GACH;GACI;GACV,YAAY;GACZ,WAAW;GACU;GACrB,MAAM;GACN,SAAS;GACT,gBAAgB;GAChB,gBACE,EAAc,eAAe,UAC3B,kBAAC,OAAD;IAAK,KAAK;IAAa,eAAY;IAAS,CAAA,GAC1C;GAEN,eAAe,MACN,IAAc,KAAK,EAAI,IAAI;GAEpC,CAAA;EAoCwB,CAAA,EAGtB,KAAiB,KACrB,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,IAAD;EACE,QAAQ;EACR,gBAAgB;EAChB,qBAAqB;EACrB,MAAM;EACN,gBACE,KAAa,OAAO,OAClB,kBAAC,GAAD;GACE,MAAK;GACL,SAAQ;GACR,MAAK;GACL,WAAW;GACX,cAAc,EAAE,0BAA0B;GAC1C,eAAe;IACb,GAAW;;aAGZ,EAAE,uBAAuB;GACnB,CAAA;EAGb,OAAO;EACP,SAAQ;EACR,CAAA,EACD,GACA,EAAA,CAAA,GACD,MAEE,KACJ,kBAAC,OAAD;EAAK,WAAW;YAAhB,CACG,IACD,kBAAC,GAAD;GACE,QAAQ,KAAgB;GACxB,QAAQ,GAAc,UAAU,EAAO;GACvC,OAAO,GAAc,SAAS,EAAE,eAAe;GAC/C,OAAO,GAAc;GACrB,eAAe;IACb,GAAgB,KAAK;;GAEvB,aAAa,MAAO;IAClB,IAAI,KAAgB,MAClB;IAEF,IAAM,IAAY,EAChB,EAAM,OACN,EAAa,UACb,GACA,EAAa,KACd;IACD,EAAU;KAAE,GAAG;KAAO,OAAO;KAAW,CAAC;;GAE3C,CAAA,CACE;KAMF,IAFJ,EAAK,SAAS,KAAK,KAAiB,IAGpC,kBAAA,GAAA,EAAA,UACE,kBAAC,IAAD;EACE,MAAK;EACL,aAAa,EAAK;EACN;EACC;EACb,WAAW;EACX,eACE,IACI,iBACA,IACE,YACA,IACE,UACA;EAEV,QAAQ;GACN,QAAQ;GACR,SAAS,EAAE,wBAAwB;GACnC,KAAK,EAAE,oBAAoB;GAC5B;EACD,CAAA,EACD,CAAA,GACD;CAoBJ,OAlBI,OAAY,aAEZ,kBAAC,GAAD;EACU;EACD;EACI;YAEX,kBAAC,OAAD;GAAK,WAAW;aAAhB;IACE,kBAAC,OAAD;KAAK,WAAW;eAAwB;KAAkB,CAAA;IACzD;IACA;IACA;IACA;IACG;;EACuB,CAAA,GAKjC,kBAAC,GAAD;EACU;EACD;EACI;YAEX,kBAAC,IAAD;GACE,YACE,kBAAC,IAAD;IACE,OAAO;IACP,UAAU;IACV,SAAS;IACT,CAAA;GAEJ,aAAa;GACb,YAAY;GACD;GACM;GACjB,cAAa;GACb,gBAAgB;GAChB,CAAA;EAC2B,CAAA"}
1
+ {"version":3,"file":"BackofficeEntityListScaffold.js","names":[],"sources":["../../../../../src/components/backoffice/scaffolds/BackofficeEntityListScaffold.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n type JSX,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { BackofficeEmptyState } from '@plumile/ui/backoffice/molecules/backoffice_empty_state/BackofficeEmptyState.js';\nimport { BackofficeFilterDrawer } from '@plumile/ui/backoffice/molecules/backoffice_filter_drawer/BackofficeFilterDrawer.js';\nimport { BackofficeFilterField } from '@plumile/ui/backoffice/molecules/backoffice_filter_field/BackofficeFilterField.js';\nimport { BackofficeListFooter } from '@plumile/ui/backoffice/molecules/backoffice_list_footer/BackofficeListFooter.js';\nimport { BackofficePageHeader } from '@plumile/ui/backoffice/molecules/backoffice_page_header/BackofficePageHeader.js';\nimport { BackofficeToolbar } from '@plumile/ui/backoffice/molecules/backoffice_toolbar/BackofficeToolbar.js';\nimport { BackofficeTableSkeleton } from '@plumile/ui/backoffice/molecules/backoffice_table_skeleton/BackofficeTableSkeleton.js';\nimport {\n FilterChipRow,\n type FilterChip,\n} from '@plumile/ui/backoffice/molecules/filter_chip_row/FilterChipRow.js';\nimport { InlineBanner } from '@plumile/ui/components/feedback/InlineBanner.js';\nimport { ListPageTemplate } from '@plumile/ui/backoffice/templates/list_page_template/ListPageTemplate.js';\nimport {\n type DataTableColumn,\n type GetRowId,\n} from '@plumile/ui/components/data-table/DataTable.js';\nimport { ResponsiveRecordList } from '@plumile/ui/components/data-table/ResponsiveRecordList.js';\nimport { VirtualizedConnectionTable } from '@plumile/ui/components/data-table/VirtualizedConnectionTable.js';\nimport { SimpleSelect } from '@plumile/ui/components/select/SimpleSelect.js';\nimport { denseTableClass } from '@plumile/ui/shared/backofficeTableDensity.css.js';\n\nimport {\n readWhereValue,\n setWhereValue,\n} from '@plumile/backoffice-core/filters/where.js';\nimport { resolveBackofficeListRuntimeConfig } from '@plumile/backoffice-core/config/listRuntime.js';\nimport type {\n BackofficeFilterSpec,\n BackofficeListState,\n BackofficePickerScope,\n BackofficeRuntimeResolvedListFacetConfig,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\n\nimport { BackofficeErrorBoundary } from '../errors/BackofficeErrorBoundary.js';\nimport {\n EntityFilterValue,\n EntityFilterValueText,\n} from '../filters/EntityFilterValue.js';\nimport { EntityIdPickerDialog } from '../pickers/EntityIdPickerDialog.js';\nimport { EntityIdFilterField } from '../filters/EntityIdFilterField.js';\nimport { DeferredFilterSearchInput } from '../filters/DeferredFilterSearchInput.js';\nimport { BackofficeListFilterProvider } from './BackofficeListFilterContext.js';\nimport { BACKOFFICE_LIST_BODY_SCROLL_MODE } from './backofficeListScrollMode.js';\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeInfiniteScrollSentinel } from '../../../hooks/useBackofficeInfiniteScrollSentinel.js';\nimport { isDevEnv } from '../../../relay/envHelpers.js';\n\nimport * as styles from './backofficeEntityListScaffold.css.js';\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nconst getFilterValue = <Where extends Record<string, unknown>>(\n filter: BackofficeFilterSpec<Where>,\n where: Where | null,\n): unknown => {\n if (filter.fromGraphQL != null && where != null) {\n return filter.fromGraphQL(where);\n }\n\n const key = (filter.whereKey ?? filter.id) as keyof Where;\n return readWhereValue(where, key, filter.path);\n};\n\nconst getFilterDisplayValue = <Where extends Record<string, unknown>>(\n filter: BackofficeFilterSpec<Where>,\n raw: unknown,\n options: {\n enumLabel: (value: string) => string;\n booleanLabel: (value: boolean) => string;\n fallbackBooleanLabels: { yes: string; no: string };\n },\n): ReactNode | null => {\n if (raw == null) {\n return null;\n }\n\n if (Array.isArray(raw)) {\n const normalized = raw\n .map((entry) => {\n if (entry == null) {\n return null;\n }\n if (\n typeof entry !== 'string' &&\n typeof entry !== 'number' &&\n typeof entry !== 'boolean'\n ) {\n return null;\n }\n const value = String(entry).trim();\n if (value === '') {\n return null;\n }\n return value;\n })\n .filter((entry): entry is string => {\n return entry != null;\n });\n\n if (normalized.length === 0) {\n return null;\n }\n return normalized.join(', ');\n }\n\n if (typeof raw === 'boolean') {\n if (filter.kind === 'boolean') {\n return options.booleanLabel(raw);\n }\n if (raw) {\n return options.fallbackBooleanLabels.yes;\n }\n return options.fallbackBooleanLabels.no;\n }\n\n if (typeof raw !== 'string' && typeof raw !== 'number') {\n return null;\n }\n\n const rawString = String(raw).trim();\n if (rawString === '') {\n return null;\n }\n\n if (filter.kind === 'entityId') {\n return <EntityFilterValue entityId={filter.entity} id={rawString} />;\n }\n\n if (filter.kind === 'enum') {\n return options.enumLabel(rawString);\n }\n\n return rawString;\n};\n\nconst toDatetimeInputValue = (value: string): string => {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n return value;\n }\n const offsetMs = date.getTimezoneOffset() * 60_000;\n return new Date(date.getTime() - offsetMs).toISOString().slice(0, 16);\n};\n\nconst fromDatetimeInputValue = (value: string): string => {\n const normalized = value.trim();\n if (normalized === '') {\n return '';\n }\n const date = new Date(normalized);\n if (Number.isNaN(date.getTime())) {\n return normalized;\n }\n return date.toISOString();\n};\n\ntype RuntimeWhere = Record<string, unknown>;\ntype RuntimeSort = string;\n\ntype Props<RowView> = {\n config: BackofficeRuntimeResolvedListFacetConfig;\n state: BackofficeListState<RuntimeWhere, RuntimeSort>;\n pushState: (next: BackofficeListState<RuntimeWhere, RuntimeSort>) => void;\n header?: {\n title?: string;\n subtitle?: string;\n };\n headerActions?: ReactNode;\n rows: readonly RowView[];\n getRowId: GetRowId<RowView>;\n columns: readonly DataTableColumn<RowView>[];\n gridTemplateColumns?: string;\n hasNextPage: boolean;\n isLoadingMore: boolean;\n isRefreshing?: boolean;\n onLoadMore: () => void;\n onRefresh?: () => void;\n totalCount?: number | null;\n emptyState?: JSX.Element;\n statusBanner?: ReactNode;\n isLoadingInitial?: boolean;\n virtualize?: boolean;\n variant?: 'page' | 'embedded';\n showFilters?: boolean;\n};\n\nexport const BackofficeEntityListScaffold = <RowView,>(\n props: Props<RowView>,\n): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const {\n config,\n state,\n pushState,\n rows,\n getRowId,\n columns,\n gridTemplateColumns,\n hasNextPage,\n isLoadingMore,\n isRefreshing = false,\n onLoadMore,\n onRefresh,\n totalCount,\n emptyState,\n statusBanner,\n header,\n headerActions,\n isLoadingInitial = false,\n variant = 'page',\n showFilters = true,\n } = props;\n const listConfig = config.list;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const listDefaults = config.listDefaults ??\n listConfig.defaultState ?? { where: null, sort: null };\n\n const columnsWithPrimary = useMemo(() => {\n const hasPrimary = columns.some((col) => {\n return col.isPrimary === true;\n });\n if (hasPrimary || columns.length === 0) {\n return columns;\n }\n return columns.map((col, index) => {\n const { header } = col;\n if (index === 0) {\n return { ...col, isPrimary: true, header };\n }\n return { ...col, header };\n });\n }, [columns]);\n\n const chips = useMemo<readonly FilterChip[]>(() => {\n const out: FilterChip[] = [];\n for (const filter of listConfig.filters) {\n const raw = getFilterValue(filter, state.where);\n const displayValue = getFilterDisplayValue(filter, raw, {\n enumLabel: (value) => {\n if (filter.kind !== 'enum') {\n return value;\n }\n const match = filter.options.find((option) => {\n return option.value === value;\n });\n if (match != null) {\n return resolveLabel(match.label, tApp);\n }\n return value;\n },\n booleanLabel: (value) => {\n if (filter.kind === 'boolean') {\n if (value && filter.trueLabel != null) {\n return resolveLabel(filter.trueLabel, tApp);\n }\n if (!value && filter.falseLabel != null) {\n return resolveLabel(filter.falseLabel, tApp);\n }\n }\n if (value) {\n return t('filters.boolean.yes');\n }\n return t('filters.boolean.no');\n },\n fallbackBooleanLabels: {\n yes: t('filters.boolean.yes'),\n no: t('filters.boolean.no'),\n },\n });\n\n if (displayValue != null) {\n let idValue = String(raw);\n if (Array.isArray(raw)) {\n idValue = raw.join(',');\n }\n const label = (\n <span>\n {resolveLabel(filter.label, tApp)}: {displayValue}\n </span>\n );\n out.push({\n id: `${filter.id}:${idValue}`,\n label,\n onRemove: () => {\n const key = filter.whereKey ?? filter.id;\n const nextWhere = setWhereValue(\n state.where,\n key,\n null,\n filter.path,\n );\n pushState({ ...state, where: nextWhere });\n },\n });\n }\n }\n return out;\n }, [listConfig.filters, pushState, state, t, tApp]);\n\n const handleClearAll = useCallback(() => {\n pushState({\n ...listDefaults,\n });\n }, [listDefaults, pushState]);\n const [isFilterDrawerOpen, setIsFilterDrawerOpen] = useState(false);\n const [filterSearch, setFilterSearch] = useState('');\n\n const [pickerDialog, setPickerDialog] = useState<{\n entity: string;\n whereKey: keyof RuntimeWhere;\n label: string;\n path?: readonly string[];\n scope?: BackofficePickerScope<Record<string, unknown>>;\n } | null>(null);\n\n const renderFilterControl = useCallback(\n (filter: BackofficeFilterSpec<RuntimeWhere>): JSX.Element => {\n const key = filter.whereKey ?? filter.id;\n const candidate = getFilterValue(filter, state.where);\n let value = '';\n if (typeof candidate === 'string') {\n value = candidate;\n }\n if (typeof candidate === 'number' && Number.isFinite(candidate)) {\n value = String(candidate);\n }\n\n const filterLabelText = resolveLabel(filter.label, tApp);\n\n if (filter.kind === 'text') {\n const placeholderLabelText =\n filter.placeholderLabel != null\n ? resolveLabel(filter.placeholderLabel, tApp)\n : filterLabelText;\n let placeholder = t('filters.placeholders.search', {\n label: placeholderLabelText,\n });\n if (filter.placeholderText != null) {\n placeholder = resolveLabel(filter.placeholderText, tApp);\n }\n return (\n <DeferredFilterSearchInput\n value={toDatetimeInputValue(value)}\n onApply={(next) => {\n const normalized = fromDatetimeInputValue(next);\n const nextWhere = setWhereValue(\n state.where,\n key,\n normalized,\n filter.path,\n );\n pushState({ ...state, where: nextWhere });\n }}\n placeholder={placeholder}\n ariaLabel={placeholder}\n className={styles.filterInput}\n />\n );\n }\n\n if (filter.kind === 'datetime') {\n const placeholderLabelText =\n filter.placeholderLabel != null\n ? resolveLabel(filter.placeholderLabel, tApp)\n : filterLabelText;\n let placeholder = t('filters.placeholders.search', {\n label: placeholderLabelText,\n });\n if (filter.placeholderText != null) {\n placeholder = resolveLabel(filter.placeholderText, tApp);\n }\n return (\n <DeferredFilterSearchInput\n value={value}\n onApply={(next) => {\n const nextWhere = setWhereValue(\n state.where,\n key,\n next,\n filter.path,\n );\n pushState({ ...state, where: nextWhere });\n }}\n placeholder={placeholder}\n ariaLabel={placeholder}\n className={styles.filterInput}\n type=\"datetime-local\"\n />\n );\n }\n\n if (filter.kind === 'number') {\n const placeholderLabelText =\n filter.placeholderLabel != null\n ? resolveLabel(filter.placeholderLabel, tApp)\n : filterLabelText;\n let placeholder = t('filters.placeholders.search', {\n label: placeholderLabelText,\n });\n if (filter.placeholderText != null) {\n placeholder = resolveLabel(filter.placeholderText, tApp);\n }\n return (\n <DeferredFilterSearchInput\n value={value}\n onApply={(next) => {\n const normalized = next.trim();\n const parsed = normalized === '' ? null : Number(normalized);\n const nextWhere = setWhereValue(\n state.where,\n key,\n Number.isFinite(parsed) ? parsed : null,\n filter.path,\n );\n pushState({ ...state, where: nextWhere });\n }}\n placeholder={placeholder}\n ariaLabel={placeholder}\n className={styles.filterInput}\n inputMode={filter.inputMode ?? 'numeric'}\n type=\"text\"\n />\n );\n }\n\n if (filter.kind === 'enum') {\n const options = [\n {\n id: 'any',\n value: '',\n label: t('filters.all', {\n label: filterLabelText,\n }),\n },\n ...filter.options.map((option) => {\n return {\n id: option.value,\n value: option.value,\n label: resolveLabel(option.label, tApp),\n };\n }),\n ];\n\n return (\n <SimpleSelect\n options={options}\n value={value}\n size=\"small\"\n ariaLabel={filterLabelText}\n onChange={(next) => {\n const nextWhere = setWhereValue(\n state.where,\n key,\n next,\n filter.path,\n );\n pushState({ ...state, where: nextWhere });\n }}\n />\n );\n }\n\n if (filter.kind === 'boolean') {\n let current: boolean | null = null;\n if (typeof candidate === 'boolean') {\n current = candidate;\n }\n\n let selectValue = '';\n if (current === true) {\n selectValue = 'true';\n }\n if (current === false) {\n selectValue = 'false';\n }\n\n const trueLabel =\n filter.trueLabel != null\n ? resolveLabel(filter.trueLabel, tApp)\n : t('filters.boolean.yes');\n const falseLabel =\n filter.falseLabel != null\n ? resolveLabel(filter.falseLabel, tApp)\n : t('filters.boolean.no');\n const options = [\n {\n id: 'any',\n value: '',\n label: t('filters.all', {\n label: filterLabelText,\n }),\n },\n {\n id: 'true',\n value: 'true',\n label: trueLabel,\n },\n {\n id: 'false',\n value: 'false',\n label: falseLabel,\n },\n ];\n\n return (\n <SimpleSelect\n options={options}\n value={selectValue}\n size=\"small\"\n ariaLabel={filterLabelText}\n onChange={(next) => {\n let parsed: boolean | null = null;\n if (next === 'true') {\n parsed = true;\n }\n if (next === 'false') {\n parsed = false;\n }\n const nextWhere = setWhereValue(\n state.where,\n key,\n parsed,\n filter.path,\n );\n pushState({ ...state, where: nextWhere });\n }}\n />\n );\n }\n\n const pickerScope = (() => {\n if (filter.pickerScope == null) {\n return undefined;\n }\n if (typeof filter.pickerScope === 'function') {\n return filter.pickerScope(state.where);\n }\n return filter.pickerScope;\n })();\n let currentId: string | null = null;\n if (typeof candidate === 'string') {\n currentId = candidate;\n }\n\n const renderField = (\n displayValue: string | null = null,\n isResolving = false,\n ) => {\n const normalizedDisplayValue = displayValue?.trim() ?? '';\n return (\n <EntityIdFilterField\n label={filterLabelText}\n value={currentId}\n displayValue={normalizedDisplayValue}\n isResolving={isResolving}\n placeholder={t('filters.placeholders.anyEntity', {\n label: filterLabelText,\n })}\n onPick={() => {\n setPickerDialog({\n entity: filter.entity,\n whereKey: key,\n label: filterLabelText,\n path: filter.path,\n scope: pickerScope,\n });\n }}\n onClear={() => {\n const nextWhere = setWhereValue(\n state.where,\n key,\n null,\n filter.path,\n );\n pushState({ ...state, where: nextWhere });\n }}\n />\n );\n };\n\n if (currentId == null || currentId.trim() === '') {\n return renderField();\n }\n\n return (\n <EntityFilterValueText entityId={filter.entity} id={currentId}>\n {(label, valueState) => {\n const isResolving = valueState?.status === 'loading';\n return renderField(\n isResolving ? t('common.loading') : label,\n isResolving,\n );\n }}\n </EntityFilterValueText>\n );\n },\n [pushState, state, t, tApp],\n );\n\n const hasPlacementConfig = useMemo(() => {\n return listConfig.filters.some((filter) => {\n return filter.placement != null;\n });\n }, [listConfig.filters]);\n\n const quickFilters = useMemo(() => {\n if (listConfig.filters.length === 0) {\n return [];\n }\n const maxPromotedFilters = listConfig.ui?.toolbar?.maxPromotedFilters ?? 3;\n if (hasPlacementConfig) {\n return listConfig.filters.filter((filter) => {\n return filter.placement === 'quick' || filter.placement === 'both';\n });\n }\n return listConfig.filters.slice(0, maxPromotedFilters);\n }, [listConfig.filters, listConfig.ui?.toolbar, hasPlacementConfig]);\n\n const drawerFilters = useMemo(() => {\n return listConfig.filters.filter((filter) => {\n if (filter.placement == null) {\n return true;\n }\n return filter.placement === 'drawer' || filter.placement === 'both';\n });\n }, [listConfig.filters]);\n\n const searchFilter = useMemo(() => {\n return quickFilters.find((filter) => {\n return filter.kind === 'text';\n });\n }, [quickFilters]);\n\n const quickFiltersNode = useMemo(() => {\n const visibleQuickFilters = quickFilters.filter((filter) => {\n return filter !== searchFilter;\n });\n\n if (visibleQuickFilters.length === 0) {\n return null;\n }\n\n return (\n <div className={styles.controlsRow}>\n {visibleQuickFilters.map((filter) => {\n return <span key={filter.id}>{renderFilterControl(filter)}</span>;\n })}\n </div>\n );\n }, [quickFilters, renderFilterControl, searchFilter]);\n\n const searchNode = useMemo(() => {\n if (searchFilter == null) {\n return null;\n }\n return renderFilterControl(searchFilter);\n }, [renderFilterControl, searchFilter]);\n\n const sortNode = useMemo(() => {\n if (listConfig.sorts.length === 0) {\n return null;\n }\n const firstSort = listConfig.sorts[0];\n if (firstSort == null) {\n return null;\n }\n const options = listConfig.sorts.map((s) => {\n return { id: s.id, value: s.id, label: resolveLabel(s.label, tApp) };\n });\n return (\n <SimpleSelect\n options={options}\n value={state.sort ?? firstSort.id}\n size=\"small\"\n ariaLabel={t('list.sort.label')}\n onChange={(next) => {\n pushState({\n ...state,\n sort: next,\n });\n }}\n />\n );\n }, [listConfig.sorts, pushState, state, t, tApp]);\n\n const chipsNode = useMemo(() => {\n if (chips.length === 0) {\n return null;\n }\n return <FilterChipRow chips={chips} onClearAll={handleClearAll} />;\n }, [chips, handleClearAll]);\n\n const drawerSections = useMemo(() => {\n if (drawerFilters.length === 0) {\n return [];\n }\n\n const normalizedQuery = filterSearch.trim().toLowerCase();\n const items: { id: string; node: JSX.Element }[] = [];\n\n for (const filter of drawerFilters) {\n const resolvedLabel = resolveLabel(filter.label, tApp);\n const matchesQuery =\n normalizedQuery === '' ||\n resolvedLabel.toLowerCase().includes(normalizedQuery);\n\n if (matchesQuery) {\n items.push({\n id: filter.id,\n node: (\n <BackofficeFilterField label={resolvedLabel}>\n {renderFilterControl(filter)}\n </BackofficeFilterField>\n ),\n });\n }\n }\n\n if (items.length === 0) {\n return [];\n }\n\n return [\n {\n id: 'backoffice.filters.sections.default',\n title: t('filters.sections.default'),\n items,\n },\n ];\n }, [drawerFilters, filterSearch, renderFilterControl, t, tApp]);\n\n const allFiltersNode = useMemo(() => {\n if (drawerFilters.length === 0) {\n return null;\n }\n const activeCount = chips.length;\n let label = t('filters.trigger');\n if (activeCount > 0) {\n label = t('filters.triggerWithCount', {\n count: activeCount,\n });\n }\n return (\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={() => {\n setIsFilterDrawerOpen(true);\n }}\n >\n {label}\n </Button>\n );\n }, [chips.length, drawerFilters.length, t]);\n\n const filterDrawerEmptyLabel =\n filterSearch.trim() === ''\n ? undefined\n : t('filters.drawer.emptySearchResults');\n\n const filterDrawerNode = (\n <BackofficeFilterDrawer\n isOpen={isFilterDrawerOpen}\n onClose={() => {\n setIsFilterDrawerOpen(false);\n setFilterSearch('');\n }}\n sections={drawerSections}\n searchValue={filterSearch}\n onSearchChange={(next) => {\n setFilterSearch(next);\n }}\n onReset={handleClearAll}\n emptyLabel={filterDrawerEmptyLabel}\n />\n );\n\n const resolvedEmptyState = useMemo((): JSX.Element => {\n if (emptyState != null) {\n return emptyState;\n }\n\n if (isLoadingInitial) {\n return (\n <BackofficeTableSkeleton\n variant=\"embedded\"\n ariaLabel={t('common.loading')}\n />\n );\n }\n\n if (chips.length > 0) {\n return (\n <BackofficeEmptyState\n title={t('emptyState.listEmpty.title')}\n description={t('emptyState.listEmptyFiltered.description')}\n actions={\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={handleClearAll}\n >\n {t('emptyState.listEmptyFiltered.actions.reset')}\n </Button>\n }\n />\n );\n }\n\n return (\n <BackofficeEmptyState\n title={t('emptyState.listEmpty.title')}\n description={t('emptyState.listEmpty.description')}\n />\n );\n }, [chips.length, emptyState, handleClearAll, isLoadingInitial, t]);\n\n const tableFooterMeta = useMemo(() => {\n if (typeof totalCount !== 'number') {\n if (rows.length === 0) {\n return null;\n }\n return (\n <span>\n {t('list.loaded', {\n count: rows.length,\n })}\n </span>\n );\n }\n return (\n <span>\n {t('list.showing', {\n shown: rows.length,\n total: totalCount,\n })}\n </span>\n );\n }, [rows.length, t, totalCount]);\n\n const runtimeConfig = useMemo(() => {\n const resolvedDisplayMode =\n listConfig.ui?.displayMode ?? listConfig.responsive?.mode ?? 'auto';\n return resolveBackofficeListRuntimeConfig({\n kind: listConfig.kind,\n displayMode: resolvedDisplayMode,\n ui: listConfig.ui,\n });\n }, [listConfig.kind, listConfig.responsive?.mode, listConfig.ui]);\n\n const hasKnownRemainingRows =\n typeof totalCount === 'number' && rows.length < totalCount;\n const hasInconsistentPageInfo = hasKnownRemainingRows && !hasNextPage;\n\n useEffect(() => {\n if (\n !hasInconsistentPageInfo ||\n !runtimeConfig.infiniteScroll.showInconsistentPageInfo ||\n !isDevEnv()\n ) {\n return;\n }\n // eslint-disable-next-line no-console\n console.warn(\n 'Backoffice list received inconsistent pageInfo: loaded rows are lower than totalCount but hasNextPage is false.',\n {\n entityId: config.id,\n loadedCount: rows.length,\n totalCount,\n },\n );\n }, [\n config.id,\n hasInconsistentPageInfo,\n rows.length,\n runtimeConfig.infiniteScroll.showInconsistentPageInfo,\n totalCount,\n ]);\n\n const shouldVirtualizeTable =\n props.virtualize === true || runtimeConfig.virtualization.enabled;\n\n const { sentinelRef } = useBackofficeInfiniteScrollSentinel({\n enabled: !shouldVirtualizeTable && runtimeConfig.infiniteScroll.enabled,\n hasNextPage,\n isLoading: isLoadingMore,\n onIntersect: onLoadMore,\n rootMargin: runtimeConfig.infiniteScroll.rootMargin,\n threshold: runtimeConfig.infiniteScroll.threshold,\n });\n\n const headerTitle = header?.title ?? resolveLabel(listConfig.title, tApp);\n const headerSubtitle = header?.subtitle;\n\n const actionColumn = columnsWithPrimary.find((column) => {\n return column.mobileRole === 'action' || column.id === 'actions';\n });\n const listMode =\n listConfig.ui?.displayMode ?? listConfig.responsive?.mode ?? 'auto';\n const listDensity =\n listConfig.ui?.density ?? listConfig.responsive?.density ?? 'compact';\n\n const tableInnerNode = shouldVirtualizeTable ? (\n <VirtualizedConnectionTable\n columns={columnsWithPrimary}\n rows={rows}\n getRowId={getRowId}\n emptyState={resolvedEmptyState}\n className={denseTableClass}\n gridTemplateColumns={gridTemplateColumns}\n virtualization={runtimeConfig.virtualization}\n infiniteScroll={{\n enabled: runtimeConfig.infiniteScroll.enabled,\n thresholdPx: runtimeConfig.infiniteScroll.thresholdPx,\n autoLoad: runtimeConfig.infiniteScroll.autoLoad,\n }}\n hasNextPage={hasNextPage}\n isLoadingMore={isLoadingMore}\n onLoadMore={onLoadMore}\n bodyScrollMode={BACKOFFICE_LIST_BODY_SCROLL_MODE}\n />\n ) : (\n <ResponsiveRecordList\n columns={columnsWithPrimary}\n rows={rows}\n getRowId={getRowId}\n emptyState={resolvedEmptyState}\n className={denseTableClass}\n gridTemplateColumns={gridTemplateColumns}\n mode={listMode}\n density={listDensity}\n bodyScrollMode={BACKOFFICE_LIST_BODY_SCROLL_MODE}\n bodyFooterNode={\n runtimeConfig.infiniteScroll.enabled ? (\n <div ref={sentinelRef} aria-hidden=\"true\" />\n ) : null\n }\n renderAction={(row) => {\n return actionColumn?.cell(row) ?? null;\n }}\n />\n );\n\n const tableNodeWithErrorBoundary = (\n <BackofficeErrorBoundary\n fallback={(args: { error: unknown; reset: () => void }) => {\n const { reset } = args;\n\n const retry = (): void => {\n reset();\n if (onRefresh != null) {\n onRefresh();\n }\n };\n\n return (\n <InlineBanner\n tone=\"danger\"\n title={t('list.errors.title')}\n actions={\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={retry}\n >\n {t('list.actions.retry')}\n </Button>\n }\n >\n {t('list.errors.tableFailed')}\n </InlineBanner>\n );\n }}\n >\n {tableInnerNode}\n </BackofficeErrorBoundary>\n );\n\n const filtersBarNode = showFilters ? (\n <>\n <BackofficeToolbar\n search={searchNode}\n primaryFilters={quickFiltersNode}\n filterDrawerTrigger={allFiltersNode}\n sort={sortNode}\n utilityActions={\n onRefresh == null ? null : (\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n isLoading={isRefreshing}\n loadingLabel={t('list.actions.refreshing')}\n onClick={() => {\n onRefresh();\n }}\n >\n {t('list.actions.refresh')}\n </Button>\n )\n }\n chips={chipsNode}\n density=\"compact\"\n />\n {filterDrawerNode}\n </>\n ) : null;\n\n const tableNode = (\n <div className={styles.tableHost}>\n {tableNodeWithErrorBoundary}\n <EntityIdPickerDialog\n isOpen={pickerDialog != null}\n entity={pickerDialog?.entity ?? config.id}\n title={pickerDialog?.label ?? t('picker.title')}\n scope={pickerDialog?.scope}\n onClose={() => {\n setPickerDialog(null);\n }}\n onSelectId={(id) => {\n if (pickerDialog == null) {\n return;\n }\n const nextWhere = setWhereValue(\n state.where,\n pickerDialog.whereKey,\n id,\n pickerDialog.path,\n );\n pushState({ ...state, where: nextWhere });\n }}\n />\n </div>\n );\n\n const shouldRenderTableFooter =\n rows.length > 0 || isLoadingMore || hasNextPage;\n\n const tableFooterNode = shouldRenderTableFooter ? (\n <>\n <BackofficeListFooter\n mode=\"status\"\n loadedCount={rows.length}\n totalCount={totalCount}\n hasNextPage={hasNextPage}\n isLoading={isLoadingMore}\n pageInfoState={\n hasInconsistentPageInfo\n ? 'inconsistent'\n : isLoadingMore\n ? 'loading'\n : hasNextPage\n ? 'ready'\n : 'complete'\n }\n labels={{\n loaded: tableFooterMeta,\n loading: t('list.loadMore.loading'),\n end: t('list.loadMore.end'),\n }}\n />\n </>\n ) : null;\n\n if (variant === 'embedded') {\n return (\n <BackofficeListFilterProvider\n config={config}\n state={state}\n pushState={pushState}\n >\n <div className={styles.embeddedContainer}>\n <div className={styles.embeddedHeader}>{headerTitle}</div>\n {filtersBarNode}\n {statusBanner}\n {tableNode}\n {tableFooterNode}\n </div>\n </BackofficeListFilterProvider>\n );\n }\n\n return (\n <BackofficeListFilterProvider\n config={config}\n state={state}\n pushState={pushState}\n >\n <ListPageTemplate\n headerNode={\n <BackofficePageHeader\n title={headerTitle}\n subtitle={headerSubtitle}\n actions={headerActions}\n />\n }\n toolbarNode={filtersBarNode}\n statusNode={statusBanner}\n tableNode={tableNode}\n tableFooterNode={tableFooterNode}\n presentation=\"flat\"\n bodyScrollMode={BACKOFFICE_LIST_BODY_SCROLL_MODE}\n />\n </BackofficeListFilterProvider>\n );\n};\n\nexport default BackofficeEntityListScaffold;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeListFilterContext.js","names":[],"sources":["../../../../../src/components/backoffice/scaffolds/BackofficeListFilterContext.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useMemo,\n type JSX,\n type ReactNode,\n} from 'react';\n\nimport type {\n BackofficeListState,\n BackofficeRuntimeResolvedListFacetConfig,\n} from '@plumile/backoffice-core/types.js';\nimport { buildBackofficeListLink } from '@plumile/backoffice-core/state/buildListHref.js';\nimport { setWhereValue } from '@plumile/backoffice-core/filters/where.js';\n\nexport type BackofficeListFilterContextValue = {\n config: BackofficeRuntimeResolvedListFacetConfig;\n state: BackofficeListState<Record<string, unknown>, string>;\n pushState: (\n next: BackofficeListState<Record<string, unknown>, string>,\n ) => void;\n applyFilter: (\n whereKey: string,\n value: unknown,\n path?: readonly string[],\n ) => void;\n buildFilterLink: (\n whereKey: string,\n value: unknown,\n path?: readonly string[],\n ) => { pathname: string; search: string };\n};\n\nconst BackofficeListFilterContext =\n createContext<BackofficeListFilterContextValue | null>(null);\n\ntype ProviderProps<\n Where extends Record<string, unknown>,\n Sort extends string,\n> = {\n config: BackofficeRuntimeResolvedListFacetConfig;\n state: BackofficeListState<Where, Sort>;\n pushState: (next: BackofficeListState<Where, Sort>) => void;\n children: ReactNode;\n};\n\nexport const BackofficeListFilterProvider = <\n Where extends Record<string, unknown>,\n Sort extends string,\n>(\n props: ProviderProps<Where, Sort>,\n): JSX.Element => {\n const { config, state, pushState, children } = props;\n\n const applyFilter = useCallback(\n (whereKey: string, value: unknown, path?: readonly string[]) => {\n const nextWhere = setWhereValue(\n state.where,\n whereKey as keyof Where,\n value,\n path,\n );\n pushState({ ...state, where: nextWhere });\n },\n [pushState, state],\n );\n\n const buildFilterLink = useCallback(\n (whereKey: string, value: unknown, path?: readonly string[]) => {\n const nextWhere = setWhereValue(\n state.where,\n whereKey as keyof Where,\n value,\n path,\n );\n return buildBackofficeListLink(config, { ...state, where: nextWhere });\n },\n [config, state],\n );\n\n const contextValue = useMemo<BackofficeListFilterContextValue>(() => {\n return {\n config,\n state,\n pushState: pushState as BackofficeListFilterContextValue['pushState'],\n applyFilter,\n buildFilterLink,\n };\n }, [applyFilter, buildFilterLink, config, pushState, state]);\n\n return (\n <BackofficeListFilterContext.Provider value={contextValue}>\n {children}\n </BackofficeListFilterContext.Provider>\n );\n};\n\nexport const useBackofficeListFilterContext =\n (): BackofficeListFilterContextValue | null => {\n return useContext(BackofficeListFilterContext);\n };\n\nexport default BackofficeListFilterContext;\n"],"mappings":";;;;;AAkCA,IAAM,IACJ,EAAuD,KAAK,EAYjD,KAIX,MACgB;CAChB,IAAM,EAAE,WAAQ,UAAO,cAAW,gBAAa,GAEzC,IAAc,GACjB,GAAkB,GAAgB,MAA6B;EAC9D,IAAM,IAAY,EAChB,EAAM,OACN,GACA,GACA,EACD;EACD,EAAU;GAAE,GAAG;GAAO,OAAO;GAAW,CAAC;IAE3C,CAAC,GAAW,EAAM,CACnB,EAEK,IAAkB,GACrB,GAAkB,GAAgB,MAA6B;EAC9D,IAAM,IAAY,EAChB,EAAM,OACN,GACA,GACA,EACD;EACD,OAAO,EAAwB,GAAQ;GAAE,GAAG;GAAO,OAAO;GAAW,CAAC;IAExE,CAAC,GAAQ,EAAM,CAChB,EAEK,IAAe,SACZ;EACL;EACA;EACW;EACX;EACA;EACD,GACA;EAAC;EAAa;EAAiB;EAAQ;EAAW;EAAM,CAAC;CAE5D,OACE,kBAAC,EAA4B,UAA7B;EAAsC,OAAO;EAC1C;EACoC,CAAA;GAI9B,UAEF,EAAW,EAA4B"}
1
+ {"version":3,"file":"BackofficeListFilterContext.js","names":[],"sources":["../../../../../src/components/backoffice/scaffolds/BackofficeListFilterContext.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useMemo,\n type JSX,\n type ReactNode,\n} from 'react';\n\nimport type {\n BackofficeListState,\n BackofficeRuntimeResolvedListFacetConfig,\n} from '@plumile/backoffice-core/types.js';\nimport { buildBackofficeListLink } from '@plumile/backoffice-core/state/buildListHref.js';\nimport { setWhereValue } from '@plumile/backoffice-core/filters/where.js';\n\nexport type BackofficeListFilterContextValue = {\n config: BackofficeRuntimeResolvedListFacetConfig;\n state: BackofficeListState<Record<string, unknown>, string>;\n pushState: (\n next: BackofficeListState<Record<string, unknown>, string>,\n ) => void;\n applyFilter: (\n whereKey: string,\n value: unknown,\n path?: readonly string[],\n ) => void;\n buildFilterLink: (\n whereKey: string,\n value: unknown,\n path?: readonly string[],\n ) => { pathname: string; search: string };\n};\n\nconst BackofficeListFilterContext =\n createContext<BackofficeListFilterContextValue | null>(null);\n\ntype ProviderProps<\n Where extends Record<string, unknown>,\n Sort extends string,\n> = {\n config: BackofficeRuntimeResolvedListFacetConfig;\n state: BackofficeListState<Where, Sort>;\n pushState: (next: BackofficeListState<Where, Sort>) => void;\n children: ReactNode;\n};\n\nexport const BackofficeListFilterProvider = <\n Where extends Record<string, unknown>,\n Sort extends string,\n>(\n props: ProviderProps<Where, Sort>,\n): JSX.Element => {\n const { config, state, pushState, children } = props;\n\n const applyFilter = useCallback(\n (whereKey: string, value: unknown, path?: readonly string[]) => {\n const nextWhere = setWhereValue(\n state.where,\n whereKey as keyof Where,\n value,\n path,\n );\n pushState({ ...state, where: nextWhere });\n },\n [pushState, state],\n );\n\n const buildFilterLink = useCallback(\n (whereKey: string, value: unknown, path?: readonly string[]) => {\n const nextWhere = setWhereValue(\n state.where,\n whereKey as keyof Where,\n value,\n path,\n );\n return buildBackofficeListLink(config, { ...state, where: nextWhere });\n },\n [config, state],\n );\n\n const contextValue = useMemo<BackofficeListFilterContextValue>(() => {\n return {\n config,\n state,\n pushState: pushState as BackofficeListFilterContextValue['pushState'],\n applyFilter,\n buildFilterLink,\n };\n }, [applyFilter, buildFilterLink, config, pushState, state]);\n\n return (\n <BackofficeListFilterContext.Provider value={contextValue}>\n {children}\n </BackofficeListFilterContext.Provider>\n );\n};\n\nexport const useBackofficeListFilterContext =\n (): BackofficeListFilterContextValue | null => {\n return useContext(BackofficeListFilterContext);\n };\n\nexport default BackofficeListFilterContext;\n"],"mappings":";;;;;AAkCA,IAAM,IACJ,EAAuD,IAAI,GAYhD,KAIX,MACgB;CAChB,IAAM,EAAE,WAAQ,UAAO,cAAW,gBAAa,GAEzC,IAAc,GACjB,GAAkB,GAAgB,MAA6B;EAC9D,IAAM,IAAY,EAChB,EAAM,OACN,GACA,GACA,CACF;EACA,EAAU;GAAE,GAAG;GAAO,OAAO;EAAU,CAAC;CAC1C,GACA,CAAC,GAAW,CAAK,CACnB,GAEM,IAAkB,GACrB,GAAkB,GAAgB,MAA6B;EAC9D,IAAM,IAAY,EAChB,EAAM,OACN,GACA,GACA,CACF;EACA,OAAO,EAAwB,GAAQ;GAAE,GAAG;GAAO,OAAO;EAAU,CAAC;CACvE,GACA,CAAC,GAAQ,CAAK,CAChB,GAEM,IAAe,SACZ;EACL;EACA;EACW;EACX;EACA;CACF,IACC;EAAC;EAAa;EAAiB;EAAQ;EAAW;CAAK,CAAC;CAE3D,OACE,kBAAC,EAA4B,UAA7B;EAAsC,OAAO;EAC1C;CACmC,CAAA;AAE1C,GAEa,UAEF,EAAW,CAA2B"}
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeTabbedDetailShell.js","names":[],"sources":["../../../../../src/components/backoffice/scaffolds/BackofficeTabbedDetailShell.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\n\nimport { Tabs, type TabItem } from '@plumile/ui/atomic/molecules/tabs/Tabs.js';\nimport { DetailPageTemplate } from '@plumile/ui/backoffice/templates/detail_page_template/DetailPageTemplate.js';\n\nimport * as styles from './backofficeTabbedDetailShell.css.js';\n\nexport type BackofficeTabbedDetailShellProps = {\n headerNode: ReactNode;\n tabs?: readonly TabItem[];\n activeId?: string;\n children: ReactNode;\n};\n\nexport const BackofficeTabbedDetailShell = ({\n headerNode,\n tabs,\n activeId,\n children,\n}: BackofficeTabbedDetailShellProps): JSX.Element => {\n let tabsNode: JSX.Element | null = null;\n if (tabs != null && tabs.length > 1 && activeId != null) {\n const hasRouteTabs = tabs.some((tab) => {\n return tab.to != null;\n });\n let handleChange: ((id: string) => void) | undefined;\n if (!hasRouteTabs) {\n handleChange = () => {};\n }\n tabsNode = (\n <Tabs\n items={tabs}\n activeId={activeId}\n onChange={handleChange}\n className={styles.tabs}\n />\n );\n }\n\n return (\n <DetailPageTemplate headerNode={headerNode} tabsNode={tabsNode}>\n <div className={styles.tabBody}>{children}</div>\n </DetailPageTemplate>\n );\n};\n\nexport default BackofficeTabbedDetailShell;\n"],"mappings":";;;;;AAcA,IAAa,KAA+B,EAC1C,eACA,MAAA,GACA,aACA,kBACmD;CACnD,IAAI,IAA+B;CACnC,IAAI,KAAQ,QAAQ,EAAK,SAAS,KAAK,KAAY,MAAM;EACvD,IAAM,IAAe,EAAK,MAAM,MACvB,EAAI,MAAM,KACjB,EACE;EAIJ,AAHK,MACH,UAAqB,KAEvB,IACE,kBAAC,GAAD;GACE,OAAO;GACG;GACV,UAAU;GACV,WAAW;GACX,CAAA;;CAIN,OACE,kBAAC,GAAD;EAAgC;EAAsB;YACpD,kBAAC,OAAD;GAAK,WAAW;GAAiB;GAAe,CAAA;EAC7B,CAAA"}
1
+ {"version":3,"file":"BackofficeTabbedDetailShell.js","names":[],"sources":["../../../../../src/components/backoffice/scaffolds/BackofficeTabbedDetailShell.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\n\nimport { Tabs, type TabItem } from '@plumile/ui/atomic/molecules/tabs/Tabs.js';\nimport { DetailPageTemplate } from '@plumile/ui/backoffice/templates/detail_page_template/DetailPageTemplate.js';\n\nimport * as styles from './backofficeTabbedDetailShell.css.js';\n\nexport type BackofficeTabbedDetailShellProps = {\n headerNode: ReactNode;\n tabs?: readonly TabItem[];\n activeId?: string;\n children: ReactNode;\n};\n\nexport const BackofficeTabbedDetailShell = ({\n headerNode,\n tabs,\n activeId,\n children,\n}: BackofficeTabbedDetailShellProps): JSX.Element => {\n let tabsNode: JSX.Element | null = null;\n if (tabs != null && tabs.length > 1 && activeId != null) {\n const hasRouteTabs = tabs.some((tab) => {\n return tab.to != null;\n });\n let handleChange: ((id: string) => void) | undefined;\n if (!hasRouteTabs) {\n handleChange = () => {};\n }\n tabsNode = (\n <Tabs\n items={tabs}\n activeId={activeId}\n onChange={handleChange}\n className={styles.tabs}\n />\n );\n }\n\n return (\n <DetailPageTemplate headerNode={headerNode} tabsNode={tabsNode}>\n <div className={styles.tabBody}>{children}</div>\n </DetailPageTemplate>\n );\n};\n\nexport default BackofficeTabbedDetailShell;\n"],"mappings":";;;;;AAcA,IAAa,KAA+B,EAC1C,eACA,MAAA,GACA,aACA,kBACmD;CACnD,IAAI,IAA+B;CACnC,IAAI,KAAQ,QAAQ,EAAK,SAAS,KAAK,KAAY,MAAM;EACvD,IAAM,IAAe,EAAK,MAAM,MACvB,EAAI,MAAM,IAClB,GACG;EAIJ,AAHK,MACH,UAAqB,CAAC,IAExB,IACE,kBAAC,GAAD;GACE,OAAO;GACG;GACV,UAAU;GACV,WAAW;EACZ,CAAA;CAEL;CAEA,OACE,kBAAC,GAAD;EAAgC;EAAsB;YACpD,kBAAC,OAAD;GAAK,WAAW;GAAiB;EAAc,CAAA;CAC7B,CAAA;AAExB"}
@@ -1,6 +1,6 @@
1
1
  /* empty css */
2
2
  //#region src/components/backoffice/scaffolds/backofficeEntityListScaffold.css.ts
3
- var e = "txvbqbdr8 txvbqbf91 txvbqbey txvbqbff6", t = "txvbqb17ro txvbqb17w6 txvbqbs65", n = "txvbqbdr8 txvbqbf6i txvbqbffj", r = "txvbqbdr8 txvbqbf6i txvbqbi1f txvbqbs9r", i = "txvbqb9w txvbqbfd0 txvbqb19c9";
3
+ var e = "txvbqbfpn txvbqbh7g txvbqbey txvbqbhdl", t = "txvbqb19q3 txvbqb19ul txvbqbu4k", n = "txvbqbfpn txvbqbh4x txvbqbhdy", r = "txvbqbfpn txvbqbh4x txvbqbjzu txvbqbu86", i = "txvbqb9w txvbqbhbf txvbqb1bg1";
4
4
  //#endregion
5
5
  export { e as controlsRow, n as embeddedContainer, i as embeddedHeader, t as filterInput, r as tableHost };
6
6
 
@@ -1,6 +1,6 @@
1
1
  /* empty css */
2
2
  //#region src/components/backoffice/scaffolds/backofficeTabbedDetailShell.css.ts
3
- var e = "txvbqbdr8", t = "txvbqbdr8 txvbqbf6i txvbqbffw";
3
+ var e = "txvbqbfpn", t = "txvbqbfpn txvbqbh4x txvbqbheb";
4
4
  //#endregion
5
5
  export { t as tabBody, e as tabs };
6
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeFilterableCell.js","names":[],"sources":["../../../../../src/components/backoffice/shared/BackofficeFilterableCell.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\nimport { MarkdownExternalLinkSvg as ExternalLinkSvg } from '@plumile/ui/icons/markdown/MarkdownExternalLinkSvg.js';\nimport { cx } from '@plumile/ui/theme/tools.js';\n\nimport type { BackofficeEntityManifestMap } from '@plumile/backoffice-core/types.js';\nimport { BackofficeInlineLink } from '../links/BackofficeInlineLink.js';\nimport type { BackofficeLinkTarget } from '../links/types.js';\nimport * as styles from './backofficeFilterableCell.css.js';\n\nexport type BackofficeFilterableCellProps<\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n> = {\n filterAction?: ReactNode;\n children: ReactNode;\n target?: BackofficeLinkTarget<TManifest>;\n title?: string;\n openInNewTab?: boolean;\n wrap?: boolean;\n className?: string;\n icon?: 'auto' | 'none';\n};\n\nexport const BackofficeFilterableCell = ({\n filterAction,\n children,\n target,\n title,\n openInNewTab = false,\n wrap = false,\n className,\n icon = 'auto',\n}: BackofficeFilterableCellProps): JSX.Element => {\n const textNode = <span className={styles.text({ wrap })}>{children}</span>;\n\n let contentNode: JSX.Element = (\n <span className={styles.contentSlot}>{textNode}</span>\n );\n if (target != null) {\n contentNode = (\n <BackofficeInlineLink\n target={target}\n className={styles.detailLink}\n title={title}\n openInNewTab={openInNewTab}\n icon={icon}\n endAdornment={(() => {\n if (!openInNewTab) {\n return null;\n }\n return (\n <ExternalLinkSvg className={styles.detailIcon} aria-hidden=\"true\" />\n );\n })()}\n >\n {textNode}\n </BackofficeInlineLink>\n );\n }\n\n return (\n <span className={cx(styles.container, className)}>\n <span className={styles.actionSlot}>{filterAction}</span>\n {contentNode}\n </span>\n );\n};\n\nexport default BackofficeFilterableCell;\n"],"mappings":";;;;;;AAsBA,IAAa,KAA4B,EACvC,iBACA,aACA,WACA,UACA,kBAAe,IACf,UAAO,IACP,cACA,UAAO,aACyC;CAChD,IAAM,IAAW,kBAAC,QAAD;EAAM,WAAW,EAAY,EAAE,SAAM,CAAC;EAAG;EAAgB,CAAA,EAEtE,IACF,kBAAC,QAAD;EAAM,WAAW;YAAqB;EAAgB,CAAA;CAwBxD,OAtBI,KAAU,SACZ,IACE,kBAAC,GAAD;EACU;EACR,WAAW;EACJ;EACO;EACR;EACN,cACO,IAIH,kBAAC,GAAD;GAAiB,WAAW;GAAmB,eAAY;GAAS,CAAA,GAH7D;YAOV;EACoB,CAAA,GAKzB,kBAAC,QAAD;EAAM,WAAW,EAAG,GAAkB,EAAU;YAAhD,CACE,kBAAC,QAAD;GAAM,WAAW;aAAoB;GAAoB,CAAA,EACxD,EACI"}
1
+ {"version":3,"file":"BackofficeFilterableCell.js","names":[],"sources":["../../../../../src/components/backoffice/shared/BackofficeFilterableCell.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\nimport { MarkdownExternalLinkSvg as ExternalLinkSvg } from '@plumile/ui/icons/markdown/MarkdownExternalLinkSvg.js';\nimport { cx } from '@plumile/ui/theme/tools.js';\n\nimport type { BackofficeEntityManifestMap } from '@plumile/backoffice-core/types.js';\nimport { BackofficeInlineLink } from '../links/BackofficeInlineLink.js';\nimport type { BackofficeLinkTarget } from '../links/types.js';\nimport * as styles from './backofficeFilterableCell.css.js';\n\nexport type BackofficeFilterableCellProps<\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n> = {\n filterAction?: ReactNode;\n children: ReactNode;\n target?: BackofficeLinkTarget<TManifest>;\n title?: string;\n openInNewTab?: boolean;\n wrap?: boolean;\n className?: string;\n icon?: 'auto' | 'none';\n};\n\nexport const BackofficeFilterableCell = ({\n filterAction,\n children,\n target,\n title,\n openInNewTab = false,\n wrap = false,\n className,\n icon = 'auto',\n}: BackofficeFilterableCellProps): JSX.Element => {\n const textNode = <span className={styles.text({ wrap })}>{children}</span>;\n\n let contentNode: JSX.Element = (\n <span className={styles.contentSlot}>{textNode}</span>\n );\n if (target != null) {\n contentNode = (\n <BackofficeInlineLink\n target={target}\n className={styles.detailLink}\n title={title}\n openInNewTab={openInNewTab}\n icon={icon}\n endAdornment={(() => {\n if (!openInNewTab) {\n return null;\n }\n return (\n <ExternalLinkSvg className={styles.detailIcon} aria-hidden=\"true\" />\n );\n })()}\n >\n {textNode}\n </BackofficeInlineLink>\n );\n }\n\n return (\n <span className={cx(styles.container, className)}>\n <span className={styles.actionSlot}>{filterAction}</span>\n {contentNode}\n </span>\n );\n};\n\nexport default BackofficeFilterableCell;\n"],"mappings":";;;;;;AAsBA,IAAa,KAA4B,EACvC,iBACA,aACA,WACA,UACA,kBAAe,IACf,UAAO,IACP,cACA,UAAO,aACyC;CAChD,IAAM,IAAW,kBAAC,QAAD;EAAM,WAAW,EAAY,EAAE,QAAK,CAAC;EAAI;CAAe,CAAA,GAErE,IACF,kBAAC,QAAD;EAAM,WAAW;YAAqB;CAAe,CAAA;CAwBvD,OAtBI,KAAU,SACZ,IACE,kBAAC,GAAD;EACU;EACR,WAAW;EACJ;EACO;EACR;EACN,cACO,IAIH,kBAAC,GAAD;GAAiB,WAAW;GAAmB,eAAY;EAAQ,CAAA,IAH5D;YAOV;CACmB,CAAA,IAKxB,kBAAC,QAAD;EAAM,WAAW,EAAG,GAAkB,CAAS;YAA/C,CACE,kBAAC,QAAD;GAAM,WAAW;aAAoB;EAAmB,CAAA,GACvD,CACG;;AAEV"}
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeFormattedCurrency.js","names":[],"sources":["../../../../../src/components/backoffice/shared/BackofficeFormattedCurrency.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\n\nimport { useBackofficeFormats } from '../../../i18n/useBackofficeFormats.js';\n\nexport type BackofficeFormattedCurrencyProps = {\n value: number | null | undefined;\n fallback?: ReactNode;\n className?: string;\n};\n\nexport const BackofficeFormattedCurrency = ({\n value,\n fallback = '-',\n className,\n}: BackofficeFormattedCurrencyProps): JSX.Element => {\n const { formatCurrency, formatCurrencyTitle } = useBackofficeFormats();\n\n if (value == null) {\n return <span className={className}>{fallback}</span>;\n }\n\n return (\n <span className={className} title={formatCurrencyTitle(value) ?? undefined}>\n {formatCurrency(value)}\n </span>\n );\n};\n\nexport default BackofficeFormattedCurrency;\n"],"mappings":";;;AAUA,IAAa,KAA+B,EAC1C,UACA,cAAW,KACX,mBACmD;CACnD,IAAM,EAAE,mBAAgB,2BAAwB,GAAsB;CAMtE,OAJI,KAAS,OACJ,kBAAC,QAAD;EAAiB;YAAY;EAAgB,CAAA,GAIpD,kBAAC,QAAD;EAAiB;EAAW,OAAO,EAAoB,EAAM,IAAI,KAAA;YAC9D,EAAe,EAAM;EACjB,CAAA"}
1
+ {"version":3,"file":"BackofficeFormattedCurrency.js","names":[],"sources":["../../../../../src/components/backoffice/shared/BackofficeFormattedCurrency.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\n\nimport { useBackofficeFormats } from '../../../i18n/useBackofficeFormats.js';\n\nexport type BackofficeFormattedCurrencyProps = {\n value: number | null | undefined;\n fallback?: ReactNode;\n className?: string;\n};\n\nexport const BackofficeFormattedCurrency = ({\n value,\n fallback = '-',\n className,\n}: BackofficeFormattedCurrencyProps): JSX.Element => {\n const { formatCurrency, formatCurrencyTitle } = useBackofficeFormats();\n\n if (value == null) {\n return <span className={className}>{fallback}</span>;\n }\n\n return (\n <span className={className} title={formatCurrencyTitle(value) ?? undefined}>\n {formatCurrency(value)}\n </span>\n );\n};\n\nexport default BackofficeFormattedCurrency;\n"],"mappings":";;;AAUA,IAAa,KAA+B,EAC1C,UACA,cAAW,KACX,mBACmD;CACnD,IAAM,EAAE,mBAAgB,2BAAwB,EAAqB;CAMrE,OAJI,KAAS,OACJ,kBAAC,QAAD;EAAiB;YAAY;CAAe,CAAA,IAInD,kBAAC,QAAD;EAAiB;EAAW,OAAO,EAAoB,CAAK,KAAK,KAAA;YAC9D,EAAe,CAAK;CACjB,CAAA;AAEV"}
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeFormattedNumber.js","names":[],"sources":["../../../../../src/components/backoffice/shared/BackofficeFormattedNumber.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\n\nimport { useBackofficeFormats } from '../../../i18n/useBackofficeFormats.js';\n\nexport type BackofficeFormattedNumberProps = {\n value: number | null | undefined;\n fallback?: ReactNode;\n className?: string;\n};\n\nexport const BackofficeFormattedNumber = ({\n value,\n fallback = '-',\n className,\n}: BackofficeFormattedNumberProps): JSX.Element => {\n const { formatNumber } = useBackofficeFormats();\n\n if (value == null) {\n return <span className={className}>{fallback}</span>;\n }\n\n return <span className={className}>{formatNumber(value)}</span>;\n};\n\nexport default BackofficeFormattedNumber;\n"],"mappings":";;;AAUA,IAAa,KAA6B,EACxC,UACA,cAAW,KACX,mBACiD;CACjD,IAAM,EAAE,oBAAiB,GAAsB;CAM/C,OAJI,KAAS,OACJ,kBAAC,QAAD;EAAiB;YAAY;EAAgB,CAAA,GAG/C,kBAAC,QAAD;EAAiB;YAAY,EAAa,EAAM;EAAQ,CAAA"}
1
+ {"version":3,"file":"BackofficeFormattedNumber.js","names":[],"sources":["../../../../../src/components/backoffice/shared/BackofficeFormattedNumber.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\n\nimport { useBackofficeFormats } from '../../../i18n/useBackofficeFormats.js';\n\nexport type BackofficeFormattedNumberProps = {\n value: number | null | undefined;\n fallback?: ReactNode;\n className?: string;\n};\n\nexport const BackofficeFormattedNumber = ({\n value,\n fallback = '-',\n className,\n}: BackofficeFormattedNumberProps): JSX.Element => {\n const { formatNumber } = useBackofficeFormats();\n\n if (value == null) {\n return <span className={className}>{fallback}</span>;\n }\n\n return <span className={className}>{formatNumber(value)}</span>;\n};\n\nexport default BackofficeFormattedNumber;\n"],"mappings":";;;AAUA,IAAa,KAA6B,EACxC,UACA,cAAW,KACX,mBACiD;CACjD,IAAM,EAAE,oBAAiB,EAAqB;CAM9C,OAJI,KAAS,OACJ,kBAAC,QAAD;EAAiB;YAAY;CAAe,CAAA,IAG9C,kBAAC,QAAD;EAAiB;YAAY,EAAa,CAAK;CAAQ,CAAA;AAChE"}
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeInlineFilterRow.js","names":[],"sources":["../../../../../src/components/backoffice/shared/BackofficeInlineFilterRow.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\n\nimport { cx } from '@plumile/ui/theme/tools.js';\n\nimport * as styles from './backofficeInlineFilterRow.css.js';\n\nexport type BackofficeInlineFilterRowProps = {\n children: ReactNode;\n className?: string;\n};\n\nexport const BackofficeInlineFilterRow = ({\n children,\n className,\n}: BackofficeInlineFilterRowProps): JSX.Element => {\n return <span className={cx(styles.container, className)}>{children}</span>;\n};\n\nexport default BackofficeInlineFilterRow;\n"],"mappings":";;;;AAWA,IAAa,KAA6B,EACxC,aACA,mBAEO,kBAAC,QAAD;CAAM,WAAW,EAAG,GAAkB,EAAU;CAAG;CAAgB,CAAA"}
1
+ {"version":3,"file":"BackofficeInlineFilterRow.js","names":[],"sources":["../../../../../src/components/backoffice/shared/BackofficeInlineFilterRow.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\n\nimport { cx } from '@plumile/ui/theme/tools.js';\n\nimport * as styles from './backofficeInlineFilterRow.css.js';\n\nexport type BackofficeInlineFilterRowProps = {\n children: ReactNode;\n className?: string;\n};\n\nexport const BackofficeInlineFilterRow = ({\n children,\n className,\n}: BackofficeInlineFilterRowProps): JSX.Element => {\n return <span className={cx(styles.container, className)}>{children}</span>;\n};\n\nexport default BackofficeInlineFilterRow;\n"],"mappings":";;;;AAWA,IAAa,KAA6B,EACxC,aACA,mBAEO,kBAAC,QAAD;CAAM,WAAW,EAAG,GAAkB,CAAS;CAAI;AAAe,CAAA"}
@@ -1,15 +1,15 @@
1
1
  /* empty css */
2
2
  import { createRuntimeFn as e } from "../../../node_modules/@vanilla-extract/recipes/dist/createRuntimeFn-62c9670f.esm.js";
3
3
  //#region src/components/backoffice/shared/backofficeFilterableCell.css.ts
4
- var t = "_1q232kj0 txvbqbey txvbqbcta txvbqbs65 txvbqbt9i txvbqb7z", n = "txvbqbdsb txvbqbey txvbqbjtp", r = "txvbqbdsb txvbqbey txvbqbfet txvbqbt9i txvbqbs65", i = e({
5
- defaultClassName: "_1q232kj1 txvbqbt9i txvbqbs65",
4
+ var t = "_1q232kj0 txvbqbey txvbqberp txvbqbu4k txvbqbv7x txvbqb7z", n = "txvbqbfqq txvbqbey txvbqbls4", r = "txvbqbfqq txvbqbey txvbqbhd8 txvbqbv7x txvbqbu4k", i = e({
5
+ defaultClassName: "_1q232kj1 txvbqbv7x txvbqbu4k",
6
6
  variantClassNames: { wrap: {
7
- false: "_1q232kj2 txvbqbusr txvbqb16g0 txvbqb18xk",
8
- true: "_1q232kj3 txvbqb18xx txvbqb18sv"
7
+ false: "_1q232kj2 txvbqbwr6 txvbqb18ef txvbqb1avz",
8
+ true: "_1q232kj3 txvbqb1awc txvbqb1ara"
9
9
  } },
10
10
  defaultVariants: { wrap: !1 },
11
11
  compoundVariants: []
12
- }), a = "_1q232kj4 qbwcuep qbwcuen txvbqbdsb txvbqbey txvbqbfet txvbqb19c9 txvbqb3f txvbqb7h txvbqb75 txvbqb7t qbwcueo txvbqb1czl qbwcue0 txvbqb1cb0 txvbqb1cws txvbqbt9i txvbqbs65 txvbqb19d9 txvbqbfd0 txvbqb1bs9", o = "txvbqbf7y txvbqb19cb txvbqb18dc txvbqbiir";
12
+ }), a = "_1q232kj4 qbwcuep qbwcuen txvbqbfqq txvbqbey txvbqbhd8 txvbqb1bg1 txvbqb3f txvbqb7h txvbqb75 txvbqb7t qbwcueo txvbqb1gct qbwcue0 txvbqb1ffs txvbqb1ga0 txvbqbv7x txvbqbu4k txvbqb1bhb txvbqbhbf txvbqb1eol", o = "txvbqbh6d txvbqb1bg3 txvbqb1abr txvbqbkh6";
13
13
  //#endregion
14
14
  export { n as actionSlot, t as container, r as contentSlot, o as detailIcon, a as detailLink, i as text };
15
15
 
@@ -1 +1 @@
1
- {"version":3,"file":"backofficeFilterableCell.css.js","names":[],"sources":["../../../../../src/components/backoffice/shared/backofficeFilterableCell.css.ts"],"sourcesContent":["import { style } from '@vanilla-extract/css';\nimport { recipe } from '@vanilla-extract/recipes';\n\nimport { sprinkles, stateSprinkles } from '@plumile/ui/theme/sprinkles.css.js';\nimport { entityReferenceLink } from '@plumile/ui/theme/styleRecipes.css.js';\n\nexport const container = style([\n sprinkles({\n alignItems: 'center',\n columnGap: 2,\n maxWidth: 'full',\n minWidth: 0,\n verticalAlign: 'middle',\n }),\n {\n display: 'inline-grid',\n gridTemplateColumns: 'auto minmax(0, 1fr)',\n },\n]);\n\nexport const actionSlot = sprinkles({\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n});\n\nexport const contentSlot = sprinkles({\n display: 'inline-flex',\n alignItems: 'center',\n gap: 1,\n minWidth: 0,\n maxWidth: 'full',\n});\n\nexport const text = recipe({\n base: sprinkles({\n minWidth: 0,\n maxWidth: 'full',\n }),\n variants: {\n wrap: {\n false: sprinkles({\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }),\n true: sprinkles({\n whiteSpace: 'normal',\n wordBreak: 'break-word',\n }),\n },\n },\n defaultVariants: {\n wrap: false,\n },\n});\n\nexport const detailLink = style([\n entityReferenceLink,\n sprinkles({\n minWidth: 0,\n maxWidth: 'full',\n color: 'brandPrimaryRed',\n fontWeight: 'semibold',\n }),\n stateSprinkles({\n color: { hover: 'text' },\n }),\n]);\n\nexport const detailIcon = sprinkles({\n flexShrink: 0,\n color: 'textSecondary',\n width: 3.5,\n height: 3.5,\n});\n"],"mappings":""}
1
+ {"version":3,"file":"backofficeFilterableCell.css.js","names":[],"sources":["../../../../../src/components/backoffice/shared/backofficeFilterableCell.css.ts"],"sourcesContent":["import { style } from '@vanilla-extract/css';\nimport { recipe } from '@vanilla-extract/recipes';\n\nimport { sprinkles, stateSprinkles } from '@plumile/ui/theme/sprinkles.css.js';\nimport { entityReferenceLink } from '@plumile/ui/theme/styleRecipes.css.js';\n\nexport const container = style([\n sprinkles({\n alignItems: 'center',\n columnGap: 2,\n maxWidth: 'full',\n minWidth: 0,\n verticalAlign: 'middle',\n }),\n {\n display: 'inline-grid',\n gridTemplateColumns: 'auto minmax(0, 1fr)',\n },\n]);\n\nexport const actionSlot = sprinkles({\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n});\n\nexport const contentSlot = sprinkles({\n display: 'inline-flex',\n alignItems: 'center',\n gap: 1,\n minWidth: 0,\n maxWidth: 'full',\n});\n\nexport const text = recipe({\n base: sprinkles({\n minWidth: 0,\n maxWidth: 'full',\n }),\n variants: {\n wrap: {\n false: sprinkles({\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }),\n true: sprinkles({\n whiteSpace: 'normal',\n wordBreak: 'break-word',\n }),\n },\n },\n defaultVariants: {\n wrap: false,\n },\n});\n\nexport const detailLink = style([\n entityReferenceLink,\n sprinkles({\n minWidth: 0,\n maxWidth: 'full',\n color: 'tonePrimaryText',\n fontWeight: 'semibold',\n }),\n stateSprinkles({\n color: { hover: 'text' },\n }),\n]);\n\nexport const detailIcon = sprinkles({\n flexShrink: 0,\n color: 'textSecondary',\n width: 3.5,\n height: 3.5,\n});\n"],"mappings":""}
@@ -1,6 +1,6 @@
1
1
  /* empty css */
2
2
  //#region src/components/backoffice/shared/backofficeInlineFilterRow.css.ts
3
- var e = "txvbqbdsb txvbqbey txvbqbfet txvbqbf8o txvbqbs65 txvbqbt9i";
3
+ var e = "txvbqbfqq txvbqbey txvbqbhd8 txvbqbh73 txvbqbu4k txvbqbv7x";
4
4
  //#endregion
5
5
  export { e as container };
6
6
 
@@ -27,7 +27,7 @@ var f = ({ title: f, content: p, language: m, badgeLabel: h, defaultOpen: g = !1
27
27
  className: s(n, { [r]: v })
28
28
  })]
29
29
  }), v && /* @__PURE__ */ c("div", {
30
- className: "txvbqb6tp txvbqb2et txvbqb3bb txvbqb196d txvbqbuy6",
30
+ className: "txvbqb8qb txvbqb2sj txvbqb3ug txvbqb1b81 txvbqbv7x txvbqbwu2 txvbqbwwl",
31
31
  id: b,
32
32
  children: /* @__PURE__ */ c(u, {
33
33
  code: _,
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeToolsDocPanel.js","names":[],"sources":["../../../../../src/components/backoffice/tools/BackofficeToolsDocPanel.tsx"],"sourcesContent":["import { useId, useState, type JSX } from 'react';\n\nimport { LazyMarkdownCodeBlock } from '@plumile/ui/atomic/molecules/markdown/components/LazyMarkdownCodeBlock.js';\nimport { ChevronDownSvg } from '@plumile/ui/icons/ChevronDownSvg.js';\nimport { cx } from '@plumile/ui/theme/tools.js';\n\nimport * as styles from './backofficeToolsDocPanel.css.js';\n\nexport type BackofficeToolsDocPanelProps = {\n title: string;\n content: string;\n language?: string | null;\n badgeLabel?: string | null;\n defaultOpen?: boolean;\n};\n\nexport const BackofficeToolsDocPanel = ({\n title,\n content,\n language,\n badgeLabel,\n defaultOpen = false,\n}: BackofficeToolsDocPanelProps): JSX.Element | null => {\n const trimmedContent = content.trim();\n const [isOpen, setIsOpen] = useState(defaultOpen);\n const contentId = useId();\n\n if (trimmedContent === '') {\n return null;\n }\n\n return (\n <div className={styles.panel}>\n <button\n type=\"button\"\n className={styles.trigger}\n onClick={() => {\n setIsOpen((prev) => {\n return !prev;\n });\n }}\n aria-expanded={isOpen}\n aria-controls={contentId}\n >\n <span className={styles.triggerTitle}>{title}</span>\n <ChevronDownSvg\n width={16}\n height={16}\n aria-hidden=\"true\"\n className={cx(styles.triggerIcon, {\n [styles.triggerIconOpen]: isOpen,\n })}\n />\n </button>\n {isOpen && (\n <div className={styles.content} id={contentId}>\n <LazyMarkdownCodeBlock\n code={trimmedContent}\n language={language}\n badgeLabel={badgeLabel}\n />\n </div>\n )}\n </div>\n );\n};\n\nexport default BackofficeToolsDocPanel;\n"],"mappings":";;;;;;;AAgBA,IAAa,KAA2B,EACtC,UACA,SAAA,GACA,aACA,eACA,iBAAc,SACwC;CACtD,IAAM,IAAiB,EAAQ,MAAM,EAC/B,CAAC,GAAQ,KAAa,EAAS,EAAY,EAC3C,IAAY,GAAO;CAMzB,OAJI,MAAmB,KACd,OAIP,kBAAC,OAAD;EAAK,WAAW;YAAhB,CACE,kBAAC,UAAD;GACE,MAAK;GACL,WAAW;GACX,eAAe;IACb,GAAW,MACF,CAAC,EACR;;GAEJ,iBAAe;GACf,iBAAe;aATjB,CAWE,kBAAC,QAAD;IAAM,WAAW;cAAsB;IAAa,CAAA,EACpD,kBAAC,GAAD;IACE,OAAO;IACP,QAAQ;IACR,eAAY;IACZ,WAAW,EAAG,GAAoB,GAC/B,IAAyB,GAC3B,CAAC;IACF,CAAA,CACK;MACR,KACC,kBAAC,OAAD;GAAK,WAAW;GAAgB,IAAI;aAClC,kBAAC,GAAD;IACE,MAAM;IACI;IACE;IACZ,CAAA;GACE,CAAA,CAEJ"}
1
+ {"version":3,"file":"BackofficeToolsDocPanel.js","names":[],"sources":["../../../../../src/components/backoffice/tools/BackofficeToolsDocPanel.tsx"],"sourcesContent":["import { useId, useState, type JSX } from 'react';\n\nimport { LazyMarkdownCodeBlock } from '@plumile/ui/atomic/molecules/markdown/components/LazyMarkdownCodeBlock.js';\nimport { ChevronDownSvg } from '@plumile/ui/icons/ChevronDownSvg.js';\nimport { cx } from '@plumile/ui/theme/tools.js';\n\nimport * as styles from './backofficeToolsDocPanel.css.js';\n\nexport type BackofficeToolsDocPanelProps = {\n title: string;\n content: string;\n language?: string | null;\n badgeLabel?: string | null;\n defaultOpen?: boolean;\n};\n\nexport const BackofficeToolsDocPanel = ({\n title,\n content,\n language,\n badgeLabel,\n defaultOpen = false,\n}: BackofficeToolsDocPanelProps): JSX.Element | null => {\n const trimmedContent = content.trim();\n const [isOpen, setIsOpen] = useState(defaultOpen);\n const contentId = useId();\n\n if (trimmedContent === '') {\n return null;\n }\n\n return (\n <div className={styles.panel}>\n <button\n type=\"button\"\n className={styles.trigger}\n onClick={() => {\n setIsOpen((prev) => {\n return !prev;\n });\n }}\n aria-expanded={isOpen}\n aria-controls={contentId}\n >\n <span className={styles.triggerTitle}>{title}</span>\n <ChevronDownSvg\n width={16}\n height={16}\n aria-hidden=\"true\"\n className={cx(styles.triggerIcon, {\n [styles.triggerIconOpen]: isOpen,\n })}\n />\n </button>\n {isOpen && (\n <div className={styles.content} id={contentId}>\n <LazyMarkdownCodeBlock\n code={trimmedContent}\n language={language}\n badgeLabel={badgeLabel}\n />\n </div>\n )}\n </div>\n );\n};\n\nexport default BackofficeToolsDocPanel;\n"],"mappings":";;;;;;;AAgBA,IAAa,KAA2B,EACtC,UACA,SAAA,GACA,aACA,eACA,iBAAc,SACwC;CACtD,IAAM,IAAiB,EAAQ,KAAK,GAC9B,CAAC,GAAQ,KAAa,EAAS,CAAW,GAC1C,IAAY,EAAM;CAMxB,OAJI,MAAmB,KACd,OAIP,kBAAC,OAAD;EAAK,WAAW;YAAhB,CACE,kBAAC,UAAD;GACE,MAAK;GACL,WAAW;GACX,eAAe;IACb,GAAW,MACF,CAAC,CACT;GACH;GACA,iBAAe;GACf,iBAAe;aATjB,CAWE,kBAAC,QAAD;IAAM,WAAW;cAAsB;GAAY,CAAA,GACnD,kBAAC,GAAD;IACE,OAAO;IACP,QAAQ;IACR,eAAY;IACZ,WAAW,EAAG,GAAoB,GAC/B,IAAyB,EAC5B,CAAC;GACF,CAAA,CACK;MACP,KACC,kBAAC,OAAD;GAAK,WAAW;GAAgB,IAAI;aAClC,kBAAC,GAAD;IACE,MAAM;IACI;IACE;GACb,CAAA;EACE,CAAA,CAEJ;;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeToolsErrorFallback.js","names":[],"sources":["../../../../../src/components/backoffice/tools/BackofficeToolsErrorFallback.tsx"],"sourcesContent":["import { type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { BackofficeDetailSection } from '@plumile/ui/backoffice/molecules/backoffice_detail_section/BackofficeDetailSection.js';\nimport { BackofficePayloadViewer } from '@plumile/ui/backoffice/molecules/backoffice_payload_viewer/BackofficePayloadViewer.js';\n\nexport type BackofficeToolsErrorFallbackProps = {\n error: unknown;\n onRetry: () => void;\n};\n\nconst resolveErrorDetails = (error: unknown): string | null => {\n if (error instanceof Error) {\n if (error.stack != null && error.stack.trim() !== '') {\n return error.stack;\n }\n if (error.name !== '' && error.message !== '') {\n return `${error.name}: ${error.message}`;\n }\n if (error.message !== '') {\n return error.message;\n }\n return null;\n }\n\n if (typeof error === 'string') {\n return error;\n }\n\n try {\n return JSON.stringify(error, null, 2);\n } catch {\n return String(error);\n }\n};\n\nexport const BackofficeToolsErrorFallback = ({\n error,\n onRetry,\n}: BackofficeToolsErrorFallbackProps): JSX.Element => {\n const { t } = useTranslation('backofficeReact');\n let message = t('tools.errors.unknown');\n if (error instanceof Error) {\n message = error.message;\n }\n const details = resolveErrorDetails(error);\n let detailsContent: string | null = null;\n if (details != null) {\n const trimmed = details.trim();\n if (trimmed !== '' && trimmed !== message) {\n detailsContent = `\\`\\`\\`\\n${trimmed}\\n\\`\\`\\``;\n }\n }\n\n return (\n <>\n <BackofficeDetailSection\n title={t('tools.errors.title')}\n description={t('tools.errors.description')}\n items={[\n {\n id: 'error',\n label: t('tools.errors.label'),\n size: 'fluid',\n value: message,\n },\n ]}\n >\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={onRetry}\n >\n {t('common.actions.retry')}\n </Button>\n </BackofficeDetailSection>\n {detailsContent != null && (\n <BackofficeDetailSection title={t('tools.errors.details')}>\n <BackofficePayloadViewer content={detailsContent} format=\"markdown\" />\n </BackofficeDetailSection>\n )}\n </>\n );\n};\n\nexport default BackofficeToolsErrorFallback;\n"],"mappings":";;;;;;AAYA,IAAM,KAAuB,MAAkC;CAC7D,IAAI,aAAiB,OAUnB,OATI,EAAM,SAAS,QAAQ,EAAM,MAAM,MAAM,KAAK,KACzC,EAAM,QAEX,EAAM,SAAS,MAAM,EAAM,YAAY,KAClC,GAAG,EAAM,KAAK,IAAI,EAAM,YAE7B,EAAM,YAAY,KAGf,OAFE,EAAM;CAKjB,IAAI,OAAO,KAAU,UACnB,OAAO;CAGT,IAAI;EACF,OAAO,KAAK,UAAU,GAAO,MAAM,EAAE;SAC/B;EACN,OAAO,OAAO,EAAM;;GAIX,KAAgC,EAC3C,UACA,iBACoD;CACpD,IAAM,EAAE,SAAM,EAAe,kBAAkB,EAC3C,IAAU,EAAE,uBAAuB;CACvC,AAAI,aAAiB,UACnB,IAAU,EAAM;CAElB,IAAM,IAAU,EAAoB,EAAM,EACtC,IAAgC;CACpC,IAAI,KAAW,MAAM;EACnB,IAAM,IAAU,EAAQ,MAAM;EAC9B,AAAI,MAAY,MAAM,MAAY,MAChC,IAAiB,WAAW,EAAQ;;CAIxC,OACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;EACE,OAAO,EAAE,qBAAqB;EAC9B,aAAa,EAAE,2BAA2B;EAC1C,OAAO,CACL;GACE,IAAI;GACJ,OAAO,EAAE,qBAAqB;GAC9B,MAAM;GACN,OAAO;GACR,CACF;YAED,kBAAC,GAAD;GACE,MAAK;GACL,SAAQ;GACR,MAAK;GACL,SAAS;aAER,EAAE,uBAAuB;GACnB,CAAA;EACe,CAAA,EACzB,KAAkB,QACjB,kBAAC,GAAD;EAAyB,OAAO,EAAE,uBAAuB;YACvD,kBAAC,GAAD;GAAyB,SAAS;GAAgB,QAAO;GAAa,CAAA;EAC9C,CAAA,CAE3B,EAAA,CAAA"}
1
+ {"version":3,"file":"BackofficeToolsErrorFallback.js","names":[],"sources":["../../../../../src/components/backoffice/tools/BackofficeToolsErrorFallback.tsx"],"sourcesContent":["import { type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { BackofficeDetailSection } from '@plumile/ui/backoffice/molecules/backoffice_detail_section/BackofficeDetailSection.js';\nimport { BackofficePayloadViewer } from '@plumile/ui/backoffice/molecules/backoffice_payload_viewer/BackofficePayloadViewer.js';\n\nexport type BackofficeToolsErrorFallbackProps = {\n error: unknown;\n onRetry: () => void;\n};\n\nconst resolveErrorDetails = (error: unknown): string | null => {\n if (error instanceof Error) {\n if (error.stack != null && error.stack.trim() !== '') {\n return error.stack;\n }\n if (error.name !== '' && error.message !== '') {\n return `${error.name}: ${error.message}`;\n }\n if (error.message !== '') {\n return error.message;\n }\n return null;\n }\n\n if (typeof error === 'string') {\n return error;\n }\n\n try {\n return JSON.stringify(error, null, 2);\n } catch {\n return String(error);\n }\n};\n\nexport const BackofficeToolsErrorFallback = ({\n error,\n onRetry,\n}: BackofficeToolsErrorFallbackProps): JSX.Element => {\n const { t } = useTranslation('backofficeReact');\n let message = t('tools.errors.unknown');\n if (error instanceof Error) {\n message = error.message;\n }\n const details = resolveErrorDetails(error);\n let detailsContent: string | null = null;\n if (details != null) {\n const trimmed = details.trim();\n if (trimmed !== '' && trimmed !== message) {\n detailsContent = `\\`\\`\\`\\n${trimmed}\\n\\`\\`\\``;\n }\n }\n\n return (\n <>\n <BackofficeDetailSection\n title={t('tools.errors.title')}\n description={t('tools.errors.description')}\n items={[\n {\n id: 'error',\n label: t('tools.errors.label'),\n size: 'fluid',\n value: message,\n },\n ]}\n >\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={onRetry}\n >\n {t('common.actions.retry')}\n </Button>\n </BackofficeDetailSection>\n {detailsContent != null && (\n <BackofficeDetailSection title={t('tools.errors.details')}>\n <BackofficePayloadViewer content={detailsContent} format=\"markdown\" />\n </BackofficeDetailSection>\n )}\n </>\n );\n};\n\nexport default BackofficeToolsErrorFallback;\n"],"mappings":";;;;;;AAYA,IAAM,KAAuB,MAAkC;CAC7D,IAAI,aAAiB,OAUnB,OATI,EAAM,SAAS,QAAQ,EAAM,MAAM,KAAK,MAAM,KACzC,EAAM,QAEX,EAAM,SAAS,MAAM,EAAM,YAAY,KAClC,GAAG,EAAM,KAAK,IAAI,EAAM,YAE7B,EAAM,YAAY,KAGf,OAFE,EAAM;CAKjB,IAAI,OAAO,KAAU,UACnB,OAAO;CAGT,IAAI;EACF,OAAO,KAAK,UAAU,GAAO,MAAM,CAAC;CACtC,QAAQ;EACN,OAAO,OAAO,CAAK;CACrB;AACF,GAEa,KAAgC,EAC3C,UACA,iBACoD;CACpD,IAAM,EAAE,SAAM,EAAe,iBAAiB,GAC1C,IAAU,EAAE,sBAAsB;CACtC,AAAI,aAAiB,UACnB,IAAU,EAAM;CAElB,IAAM,IAAU,EAAoB,CAAK,GACrC,IAAgC;CACpC,IAAI,KAAW,MAAM;EACnB,IAAM,IAAU,EAAQ,KAAK;EAC7B,AAAI,MAAY,MAAM,MAAY,MAChC,IAAiB,WAAW,EAAQ;CAExC;CAEA,OACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;EACE,OAAO,EAAE,oBAAoB;EAC7B,aAAa,EAAE,0BAA0B;EACzC,OAAO,CACL;GACE,IAAI;GACJ,OAAO,EAAE,oBAAoB;GAC7B,MAAM;GACN,OAAO;EACT,CACF;YAEA,kBAAC,GAAD;GACE,MAAK;GACL,SAAQ;GACR,MAAK;GACL,SAAS;aAER,EAAE,sBAAsB;EACnB,CAAA;CACe,CAAA,GACxB,KAAkB,QACjB,kBAAC,GAAD;EAAyB,OAAO,EAAE,sBAAsB;YACtD,kBAAC,GAAD;GAAyB,SAAS;GAAgB,QAAO;EAAY,CAAA;CAC9C,CAAA,CAE3B,EAAA,CAAA;AAEN"}
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeToolsJsonForm.js","names":[],"sources":["../../../../../src/components/backoffice/tools/BackofficeToolsJsonForm.tsx"],"sourcesContent":["import { useId, type FormEvent, type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { Label } from '@plumile/ui/atomic/atoms/label/Label.js';\nimport { Textarea } from '@plumile/ui/atomic/atoms/textarea/Textarea.js';\nimport { Form } from '@plumile/ui/atomic/molecules/form/Form.js';\nimport { FormError } from '@plumile/ui/atomic/molecules/form_error/FormError.js';\nimport { FormGroup } from '@plumile/ui/atomic/molecules/form/FormGroup.js';\n\nimport * as styles from './backofficeToolsJsonForm.css.js';\n\nexport type BackofficeToolsJsonFormProps = {\n value: string;\n onChange: (next: string) => void;\n onSubmit: () => void;\n error?: string | null;\n disabled?: boolean;\n label?: string;\n submitLabel?: string;\n exampleValue?: string;\n exampleLabel?: string;\n};\n\nexport const BackofficeToolsJsonForm = ({\n value,\n onChange,\n onSubmit,\n error,\n disabled = false,\n label,\n submitLabel,\n exampleValue,\n exampleLabel,\n}: BackofficeToolsJsonFormProps): JSX.Element => {\n const { t } = useTranslation('backofficeReact');\n const inputId = useId();\n const errorId = useId();\n\n const resolvedLabel = label ?? t('tools.forms.inputJsonLabel');\n const resolvedSubmitLabel = submitLabel ?? t('tools.forms.actions.run');\n const resolvedExampleLabel =\n exampleLabel ?? t('tools.forms.actions.insertExample');\n let resolvedExampleValue = '';\n if (typeof exampleValue === 'string') {\n resolvedExampleValue = exampleValue;\n }\n const hasExample = resolvedExampleValue.trim() !== '';\n const hasError = error != null && error.trim() !== '';\n let describedBy: string | undefined;\n if (hasError) {\n describedBy = errorId;\n }\n\n const handleSubmit = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (disabled) {\n return;\n }\n onSubmit();\n };\n\n return (\n <Form onSubmit={handleSubmit} className={styles.form}>\n <FormError message={error} id={errorId} />\n <FormGroup>\n <div className={styles.inputHeader}>\n <Label htmlFor={inputId}>{resolvedLabel}</Label>\n {hasExample && (\n <Button\n type=\"button\"\n variant=\"text\"\n size=\"small\"\n disabled={disabled}\n onClick={() => {\n onChange(resolvedExampleValue);\n }}\n >\n {resolvedExampleLabel}\n </Button>\n )}\n </div>\n <Textarea\n id={inputId}\n value={value}\n onChange={(event) => {\n onChange(event.target.value);\n }}\n rows={8}\n fullWidth\n aria-invalid={hasError}\n aria-describedby={describedBy}\n />\n </FormGroup>\n <div className={styles.actions}>\n <Button\n type=\"submit\"\n variant=\"primary\"\n size=\"small\"\n disabled={disabled}\n >\n {resolvedSubmitLabel}\n </Button>\n </div>\n </Form>\n );\n};\n\nexport default BackofficeToolsJsonForm;\n"],"mappings":";;;;;;;;;;;AAwBA,IAAa,KAA2B,EACtC,UACA,aACA,aACA,UACA,cAAW,IACX,UACA,gBACA,iBACA,sBAC+C;CAC/C,IAAM,EAAE,SAAM,EAAe,kBAAkB,EACzC,IAAU,GAAO,EACjB,IAAU,GAAO,EAEjB,IAAgB,KAAS,EAAE,6BAA6B,EACxD,IAAsB,KAAe,EAAE,0BAA0B,EACjE,IACJ,KAAgB,EAAE,oCAAoC,EACpD,IAAuB;CAC3B,AAAI,OAAO,KAAiB,aAC1B,IAAuB;CAEzB,IAAM,IAAa,EAAqB,MAAM,KAAK,IAC7C,IAAW,KAAS,QAAQ,EAAM,MAAM,KAAK,IAC/C;CAaJ,OAZI,MACF,IAAc,IAYd,kBAAC,GAAD;EAAM,WATc,MAAsC;GAC1D,EAAM,gBAAgB,EAClB,MAGJ,GAAU;;EAIoB,WAAW;YAAzC;GACE,kBAAC,GAAD;IAAW,SAAS;IAAO,IAAI;IAAW,CAAA;GAC1C,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;IAAK,WAAW;cAAhB,CACE,kBAAC,GAAD;KAAO,SAAS;eAAU;KAAsB,CAAA,EAC/C,KACC,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,MAAK;KACK;KACV,eAAe;MACb,EAAS,EAAqB;;eAG/B;KACM,CAAA,CAEP;OACN,kBAAC,GAAD;IACE,IAAI;IACG;IACP,WAAW,MAAU;KACnB,EAAS,EAAM,OAAO,MAAM;;IAE9B,MAAM;IACN,WAAA;IACA,gBAAc;IACd,oBAAkB;IAClB,CAAA,CACQ,EAAA,CAAA;GACZ,kBAAC,OAAD;IAAK,WAAW;cACd,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,MAAK;KACK;eAET;KACM,CAAA;IACL,CAAA;GACD"}
1
+ {"version":3,"file":"BackofficeToolsJsonForm.js","names":[],"sources":["../../../../../src/components/backoffice/tools/BackofficeToolsJsonForm.tsx"],"sourcesContent":["import { useId, type FormEvent, type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { Label } from '@plumile/ui/atomic/atoms/label/Label.js';\nimport { Textarea } from '@plumile/ui/atomic/atoms/textarea/Textarea.js';\nimport { Form } from '@plumile/ui/atomic/molecules/form/Form.js';\nimport { FormError } from '@plumile/ui/atomic/molecules/form_error/FormError.js';\nimport { FormGroup } from '@plumile/ui/atomic/molecules/form/FormGroup.js';\n\nimport * as styles from './backofficeToolsJsonForm.css.js';\n\nexport type BackofficeToolsJsonFormProps = {\n value: string;\n onChange: (next: string) => void;\n onSubmit: () => void;\n error?: string | null;\n disabled?: boolean;\n label?: string;\n submitLabel?: string;\n exampleValue?: string;\n exampleLabel?: string;\n};\n\nexport const BackofficeToolsJsonForm = ({\n value,\n onChange,\n onSubmit,\n error,\n disabled = false,\n label,\n submitLabel,\n exampleValue,\n exampleLabel,\n}: BackofficeToolsJsonFormProps): JSX.Element => {\n const { t } = useTranslation('backofficeReact');\n const inputId = useId();\n const errorId = useId();\n\n const resolvedLabel = label ?? t('tools.forms.inputJsonLabel');\n const resolvedSubmitLabel = submitLabel ?? t('tools.forms.actions.run');\n const resolvedExampleLabel =\n exampleLabel ?? t('tools.forms.actions.insertExample');\n let resolvedExampleValue = '';\n if (typeof exampleValue === 'string') {\n resolvedExampleValue = exampleValue;\n }\n const hasExample = resolvedExampleValue.trim() !== '';\n const hasError = error != null && error.trim() !== '';\n let describedBy: string | undefined;\n if (hasError) {\n describedBy = errorId;\n }\n\n const handleSubmit = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (disabled) {\n return;\n }\n onSubmit();\n };\n\n return (\n <Form onSubmit={handleSubmit} className={styles.form}>\n <FormError message={error} id={errorId} />\n <FormGroup>\n <div className={styles.inputHeader}>\n <Label htmlFor={inputId}>{resolvedLabel}</Label>\n {hasExample && (\n <Button\n type=\"button\"\n variant=\"text\"\n size=\"small\"\n disabled={disabled}\n onClick={() => {\n onChange(resolvedExampleValue);\n }}\n >\n {resolvedExampleLabel}\n </Button>\n )}\n </div>\n <Textarea\n id={inputId}\n value={value}\n onChange={(event) => {\n onChange(event.target.value);\n }}\n rows={8}\n fullWidth\n aria-invalid={hasError}\n aria-describedby={describedBy}\n />\n </FormGroup>\n <div className={styles.actions}>\n <Button\n type=\"submit\"\n variant=\"primary\"\n size=\"small\"\n disabled={disabled}\n >\n {resolvedSubmitLabel}\n </Button>\n </div>\n </Form>\n );\n};\n\nexport default BackofficeToolsJsonForm;\n"],"mappings":";;;;;;;;;;;AAwBA,IAAa,KAA2B,EACtC,UACA,aACA,aACA,UACA,cAAW,IACX,UACA,gBACA,iBACA,sBAC+C;CAC/C,IAAM,EAAE,SAAM,EAAe,iBAAiB,GACxC,IAAU,EAAM,GAChB,IAAU,EAAM,GAEhB,IAAgB,KAAS,EAAE,4BAA4B,GACvD,IAAsB,KAAe,EAAE,yBAAyB,GAChE,IACJ,KAAgB,EAAE,mCAAmC,GACnD,IAAuB;CAC3B,AAAI,OAAO,KAAiB,aAC1B,IAAuB;CAEzB,IAAM,IAAa,EAAqB,KAAK,MAAM,IAC7C,IAAW,KAAS,QAAQ,EAAM,KAAK,MAAM,IAC/C;CAaJ,OAZI,MACF,IAAc,IAYd,kBAAC,GAAD;EAAM,WATc,MAAsC;GAC1D,EAAM,eAAe,GACjB,MAGJ,EAAS;EACX;EAGgC,WAAW;YAAzC;GACE,kBAAC,GAAD;IAAW,SAAS;IAAO,IAAI;GAAU,CAAA;GACzC,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;IAAK,WAAW;cAAhB,CACE,kBAAC,GAAD;KAAO,SAAS;eAAU;IAAqB,CAAA,GAC9C,KACC,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,MAAK;KACK;KACV,eAAe;MACb,EAAS,CAAoB;KAC/B;eAEC;IACK,CAAA,CAEP;OACL,kBAAC,GAAD;IACE,IAAI;IACG;IACP,WAAW,MAAU;KACnB,EAAS,EAAM,OAAO,KAAK;IAC7B;IACA,MAAM;IACN,WAAA;IACA,gBAAc;IACd,oBAAkB;GACnB,CAAA,CACQ,EAAA,CAAA;GACX,kBAAC,OAAD;IAAK,WAAW;cACd,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,MAAK;KACK;eAET;IACK,CAAA;GACL,CAAA;EACD;;AAEV"}
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeToolsQueryBoundary.js","names":[],"sources":["../../../../../src/components/backoffice/tools/BackofficeToolsQueryBoundary.tsx"],"sourcesContent":["import { Suspense, type JSX, type ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { Spinner } from '@plumile/ui/backoffice/atoms/spinner/Spinner.js';\nimport { BackofficeDetailSection } from '@plumile/ui/backoffice/molecules/backoffice_detail_section/BackofficeDetailSection.js';\n\nimport { BackofficeErrorBoundary } from '../errors/BackofficeErrorBoundary.js';\n\nimport { BackofficeToolsErrorFallback } from './BackofficeToolsErrorFallback.js';\nimport * as styles from './backofficeToolsForm.css.js';\n\nexport type BackofficeToolsQueryBoundaryProps = {\n children: ReactNode;\n};\n\nexport const BackofficeToolsQueryBoundary = ({\n children,\n}: BackofficeToolsQueryBoundaryProps): JSX.Element => {\n const { t } = useTranslation('backofficeReact');\n\n const fallback = (\n <BackofficeDetailSection\n title={t('tools.output')}\n description={t('tools.loading.description')}\n >\n <div className={styles.loadingState} role=\"status\" aria-live=\"polite\">\n <Spinner />\n </div>\n </BackofficeDetailSection>\n );\n\n return (\n <BackofficeErrorBoundary\n fallback={({ error, reset }) => {\n return <BackofficeToolsErrorFallback error={error} onRetry={reset} />;\n }}\n >\n <Suspense fallback={fallback}>{children}</Suspense>\n </BackofficeErrorBoundary>\n );\n};\n\nexport default BackofficeToolsQueryBoundary;\n"],"mappings":";;;;;;;;;AAeA,IAAa,KAAgC,EAC3C,kBACoD;CACpD,IAAM,EAAE,SAAM,EAAe,kBAAkB;CAa/C,OACE,kBAAC,GAAD;EACE,WAAW,EAAE,UAAO,eACX,kBAAC,GAAD;GAAqC;GAAO,SAAS;GAAS,CAAA;YAGvE,kBAAC,GAAD;GAAoB,UAhBtB,kBAAC,GAAD;IACE,OAAO,EAAE,eAAe;IACxB,aAAa,EAAE,4BAA4B;cAE3C,kBAAC,OAAD;KAAK,WAAW;KAAqB,MAAK;KAAS,aAAU;eAC3D,kBAAC,GAAD,EAAW,CAAA;KACP,CAAA;IACkB,CASJ;GAAW;GAAoB,CAAA;EAC3B,CAAA"}
1
+ {"version":3,"file":"BackofficeToolsQueryBoundary.js","names":[],"sources":["../../../../../src/components/backoffice/tools/BackofficeToolsQueryBoundary.tsx"],"sourcesContent":["import { Suspense, type JSX, type ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { Spinner } from '@plumile/ui/backoffice/atoms/spinner/Spinner.js';\nimport { BackofficeDetailSection } from '@plumile/ui/backoffice/molecules/backoffice_detail_section/BackofficeDetailSection.js';\n\nimport { BackofficeErrorBoundary } from '../errors/BackofficeErrorBoundary.js';\n\nimport { BackofficeToolsErrorFallback } from './BackofficeToolsErrorFallback.js';\nimport * as styles from './backofficeToolsForm.css.js';\n\nexport type BackofficeToolsQueryBoundaryProps = {\n children: ReactNode;\n};\n\nexport const BackofficeToolsQueryBoundary = ({\n children,\n}: BackofficeToolsQueryBoundaryProps): JSX.Element => {\n const { t } = useTranslation('backofficeReact');\n\n const fallback = (\n <BackofficeDetailSection\n title={t('tools.output')}\n description={t('tools.loading.description')}\n >\n <div className={styles.loadingState} role=\"status\" aria-live=\"polite\">\n <Spinner />\n </div>\n </BackofficeDetailSection>\n );\n\n return (\n <BackofficeErrorBoundary\n fallback={({ error, reset }) => {\n return <BackofficeToolsErrorFallback error={error} onRetry={reset} />;\n }}\n >\n <Suspense fallback={fallback}>{children}</Suspense>\n </BackofficeErrorBoundary>\n );\n};\n\nexport default BackofficeToolsQueryBoundary;\n"],"mappings":";;;;;;;;;AAeA,IAAa,KAAgC,EAC3C,kBACoD;CACpD,IAAM,EAAE,SAAM,EAAe,iBAAiB;CAa9C,OACE,kBAAC,GAAD;EACE,WAAW,EAAE,UAAO,eACX,kBAAC,GAAD;GAAqC;GAAO,SAAS;EAAQ,CAAA;YAGtE,kBAAC,GAAD;GAAoB,UAhBtB,kBAAC,GAAD;IACE,OAAO,EAAE,cAAc;IACvB,aAAa,EAAE,2BAA2B;cAE1C,kBAAC,OAAD;KAAK,WAAW;KAAqB,MAAK;KAAS,aAAU;eAC3D,kBAAC,GAAD,CAAU,CAAA;IACP,CAAA;GACkB,CASH;GAAW;EAAmB,CAAA;CAC3B,CAAA;AAE7B"}
@@ -1,6 +1,6 @@
1
1
  /* empty css */
2
2
  //#region src/components/backoffice/tools/backofficeToolsDocPanel.css.ts
3
- var e = "txvbqbdr8 txvbqbf6i txvbqbffj", t = "txvbqb1uy txvbqb2et txvbqb17h txvbqb2gm txvbqb196b txvbqbusr", n = "_8o9eh80 txvbqbyov txvbqbzmg txvbqb10jo txvbqbvvr txvbqb17w0 txvbqbdr8 txvbqbey txvbqbjus txvbqbff6 txvbqb1933 txvbqb1g5 txvbqb2e3 txvbqb19c9 txvbqbv txvbqb16ex", r = "txvbqb9w txvbqbfd0", i = "txvbqb19cb txvbqb7p txvbqb75 txvbqb7t", a = "txvbqb30", o = "txvbqb6tp txvbqb2et txvbqb3bb txvbqb196d txvbqbuy6";
3
+ var e = "txvbqbfpn txvbqbh4x txvbqbhdy", t = "txvbqb28o txvbqb2sj txvbqb1cw txvbqb2uc txvbqb1b7z txvbqbv7x txvbqbwr6", n = "_8o9eh80 txvbqb10na txvbqb11kv txvbqb12i3 txvbqbxu6 txvbqb19uf txvbqbfpn txvbqbey txvbqblt7 txvbqbhdl txvbqb1b4r txvbqb1tv txvbqb2rt txvbqb1bg1 txvbqbv txvbqb18dc", r = "txvbqb9w txvbqbhbf", i = "txvbqb1bg3 txvbqb7p txvbqb75 txvbqb7t", a = "txvbqb30", o = "txvbqb8qb txvbqb2sj txvbqb3ug txvbqb1b81 txvbqbv7x txvbqbwu2 txvbqbwwl";
4
4
  //#endregion
5
5
  export { o as content, t as panel, e as panelGroup, n as trigger, i as triggerIcon, a as triggerIconOpen, r as triggerTitle };
6
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"backofficeToolsDocPanel.css.js","names":[],"sources":["../../../../../src/components/backoffice/tools/backofficeToolsDocPanel.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.css.js';\n\nexport const panelGroup = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 3,\n});\n\nexport const panel = sprinkles({\n borderWidth: 'default',\n borderStyle: 'solid',\n borderColor: 'border',\n borderRadius: 'lg',\n backgroundColor: 'surface',\n overflow: 'hidden',\n});\n\nexport const trigger = style([\n sprinkles({\n width: 'full',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 2,\n paddingY: 3,\n paddingX: 4,\n backgroundColor: 'transparent',\n borderWidth: 0,\n borderStyle: 'none',\n color: 'text',\n cursor: 'pointer',\n textAlign: 'left',\n }),\n {\n selectors: {\n '&:focus-visible': {\n outline: 'none',\n boxShadow: `inset 0 0 0 2px ${vars.colors.primary}`,\n },\n },\n },\n]);\n\nexport const triggerTitle = sprinkles({\n fontSize: 'base',\n fontWeight: 'semibold',\n});\n\nexport const triggerIcon = sprinkles({\n color: 'textSecondary',\n transitionProperty: 'transform',\n transitionDuration: 120,\n transitionTimingFunction: 'ease',\n});\n\nexport const triggerIconOpen = sprinkles({\n rotate: 180,\n});\n\nexport const content = sprinkles({\n borderTopWidth: 'px',\n borderStyle: 'solid',\n borderTopColor: 'borderLight',\n backgroundColor: 'surfaceSecondary',\n padding: 3,\n});\n"],"mappings":""}
1
+ {"version":3,"file":"backofficeToolsDocPanel.css.js","names":[],"sources":["../../../../../src/components/backoffice/tools/backofficeToolsDocPanel.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.css.js';\n\nexport const panelGroup = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 3,\n});\n\nexport const panel = sprinkles({\n borderWidth: 'default',\n borderStyle: 'solid',\n borderColor: 'border',\n borderRadius: 'lg',\n backgroundColor: 'surface',\n minWidth: 0,\n overflow: 'hidden',\n});\n\nexport const trigger = style([\n sprinkles({\n width: 'full',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 2,\n paddingY: 3,\n paddingX: 4,\n backgroundColor: 'transparent',\n borderWidth: 0,\n borderStyle: 'none',\n color: 'text',\n cursor: 'pointer',\n textAlign: 'left',\n }),\n {\n selectors: {\n '&:focus-visible': {\n outline: 'none',\n boxShadow: `inset 0 0 0 2px ${vars.colors.primary}`,\n },\n },\n },\n]);\n\nexport const triggerTitle = sprinkles({\n fontSize: 'base',\n fontWeight: 'semibold',\n});\n\nexport const triggerIcon = sprinkles({\n color: 'textSecondary',\n transitionProperty: 'transform',\n transitionDuration: 120,\n transitionTimingFunction: 'ease',\n});\n\nexport const triggerIconOpen = sprinkles({\n rotate: 180,\n});\n\nexport const content = sprinkles({\n borderTopWidth: 'px',\n borderStyle: 'solid',\n borderTopColor: 'borderLight',\n backgroundColor: 'surfaceSecondary',\n minWidth: 0,\n overflowX: 'auto',\n padding: 3,\n});\n"],"mappings":""}
@@ -1,6 +1,6 @@
1
1
  /* empty css */
2
2
  //#region src/components/backoffice/tools/backofficeToolsForm.css.ts
3
- var e = "txvbqbdr8 txvbqbf6i txvbqbffj", t = "txvbqbdr8 txvbqbju2 txvbqbjv6", n = "txvbqbdr8 txvbqbey txvbqbjus txvbqbf91 txvbqbff6", r = "txvbqbdr8 txvbqbf6i txvbqbffj", i = "txvbqbdrl txvbqbffw txvbqbhf1", a = "txvbqb10ke txvbqbvwh txvbqbdr8 txvbqbjtp";
3
+ var e = "txvbqbfpn txvbqbh4x txvbqbhdy", t = "txvbqbfpn txvbqblsh txvbqbltl", n = "txvbqbfpn txvbqbey txvbqblt7 txvbqbh7g txvbqbhdl", r = "txvbqbfpn txvbqbh4x txvbqbhdy", i = "txvbqbfq0 txvbqbheb txvbqbjdg", a = "txvbqb12it txvbqbxuw txvbqbfpn txvbqbls4";
4
4
  //#endregion
5
5
  export { t as actions, e as form, n as inputHeader, i as keyValueGrid, a as loadingState, r as outputStack };
6
6
 
@@ -1,6 +1,6 @@
1
1
  /* empty css */
2
2
  //#region src/components/backoffice/tools/backofficeToolsJsonForm.css.ts
3
- var e = "txvbqbdr8 txvbqbf6i txvbqbffw", t = "txvbqbdr8 txvbqbju2 txvbqbjv6", n = "txvbqbdr8 txvbqbey txvbqbjus txvbqbf91 txvbqbff6";
3
+ var e = "txvbqbfpn txvbqbh4x txvbqbheb", t = "txvbqbfpn txvbqblsh txvbqbltl", n = "txvbqbfpn txvbqbey txvbqblt7 txvbqbh7g txvbqbhdl";
4
4
  //#endregion
5
5
  export { t as actions, e as form, n as inputHeader };
6
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"parseToolJson.js","names":[],"sources":["../../../../../src/components/backoffice/tools/parseToolJson.ts"],"sourcesContent":["/**\n * Parses JSON input and ensures it is a plain object.\n */\nexport function parseToolJson(value: string): Record<string, unknown> | null {\n try {\n const parsed: unknown = JSON.parse(value);\n if (parsed == null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return null;\n }\n return parsed as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n"],"mappings":";AAGA,SAAgB,EAAc,GAA+C;CAC3E,IAAI;EACF,IAAM,IAAkB,KAAK,MAAM,EAAM;EAIzC,OAHsB,OAAO,KAAW,aAApC,KAAgD,MAAM,QAAQ,EAAO,GAChE,OAEF;SACD;EACN,OAAO"}
1
+ {"version":3,"file":"parseToolJson.js","names":[],"sources":["../../../../../src/components/backoffice/tools/parseToolJson.ts"],"sourcesContent":["/**\n * Parses JSON input and ensures it is a plain object.\n */\nexport function parseToolJson(value: string): Record<string, unknown> | null {\n try {\n const parsed: unknown = JSON.parse(value);\n if (parsed == null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return null;\n }\n return parsed as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n"],"mappings":";AAGA,SAAgB,EAAc,GAA+C;CAC3E,IAAI;EACF,IAAM,IAAkB,KAAK,MAAM,CAAK;EAIxC,OAHsB,OAAO,KAAW,aAApC,KAAgD,MAAM,QAAQ,CAAM,IAC/D,OAEF;CACT,QAAQ;EACN,OAAO;CACT;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"filterHelpers.js","names":[],"sources":["../../../src/filters/filterHelpers.ts"],"sourcesContent":["import type {\n BackofficeFilterSpec,\n BackofficeRuntimeResolvedListFacetConfig,\n} from '@plumile/backoffice-core/types.js';\n\n/** Compare two optional path arrays for equality. */\nconst arePathsEqual = (\n left?: readonly string[],\n right?: readonly string[],\n): boolean => {\n const leftPath = left ?? [];\n const rightPath = right ?? [];\n if (leftPath.length !== rightPath.length) {\n return false;\n }\n return leftPath.every((segment, index) => {\n return segment === rightPath[index];\n });\n};\n\n/** Find a filter spec by its where key and optional path. */\nexport function resolveFilterForWhereKey(\n config: BackofficeRuntimeResolvedListFacetConfig,\n whereKey: string,\n path?: readonly string[],\n): BackofficeFilterSpec<Record<string, unknown>> | null {\n const { filters } = config.list;\n const match = filters.find((filter) => {\n return (\n String(filter.whereKey ?? filter.id) === whereKey &&\n arePathsEqual(filter.path, path)\n );\n });\n return match ?? null;\n}\n\n/** Resolve a filter spec from a column id, alias, or contains field. */\nexport function resolveFilterForColumn(\n config: BackofficeRuntimeResolvedListFacetConfig,\n columnId: string,\n columnAliases?: Record<string, string>,\n): BackofficeFilterSpec<Record<string, unknown>> | null {\n const direct = resolveFilterForWhereKey(config, columnId);\n if (direct != null) {\n return direct;\n }\n\n const { [columnId]: alias } = columnAliases ?? {};\n if (alias != null) {\n const aliasFilter = resolveFilterForWhereKey(config, alias);\n if (aliasFilter != null) {\n return aliasFilter;\n }\n }\n\n const containsKey = `${columnId}Contains`;\n const containsFilter = resolveFilterForWhereKey(config, containsKey);\n if (containsFilter != null) {\n return containsFilter;\n }\n\n return null;\n}\n\n/** Check if a value is compatible with a filter spec. */\nexport function canFilterValue<Where extends Record<string, unknown>>(\n filter: BackofficeFilterSpec<Where>,\n value: unknown,\n): boolean {\n if (value == null) {\n return false;\n }\n\n if (filter.kind === 'boolean') {\n return typeof value === 'boolean';\n }\n\n if (filter.kind === 'entityId') {\n return typeof value === 'string' && value.trim() !== '';\n }\n\n if (filter.kind === 'number') {\n return typeof value === 'number' && Number.isFinite(value);\n }\n\n if (filter.kind === 'datetime') {\n return typeof value === 'string' && value.trim() !== '';\n }\n\n if (typeof value === 'number') {\n return false;\n }\n\n if (typeof value !== 'string') {\n return false;\n }\n\n return value.trim() !== '';\n}\n"],"mappings":";AAMA,IAAM,KACJ,GACA,MACY;CACZ,IAAM,IAAW,KAAQ,EAAE,EACrB,IAAY,KAAS,EAAE;CAI7B,OAHI,EAAS,WAAW,EAAU,SAG3B,EAAS,OAAO,GAAS,MACvB,MAAY,EAAU,GAC7B,GAJO;;AAQX,SAAgB,EACd,GACA,GACA,GACsD;CACtD,IAAM,EAAE,eAAY,EAAO;CAO3B,OANc,EAAQ,MAAM,MAExB,OAAO,EAAO,YAAY,EAAO,GAAG,KAAK,KACzC,EAAc,EAAO,MAAM,EAAK,CAG7B,IAAS;;AAIlB,SAAgB,EACd,GACA,GACA,GACsD;CACtD,IAAM,IAAS,EAAyB,GAAQ,EAAS;CACzD,IAAI,KAAU,MACZ,OAAO;CAGT,IAAM,GAAG,IAAW,MAAU,KAAiB,EAAE;CACjD,IAAI,KAAS,MAAM;EACjB,IAAM,IAAc,EAAyB,GAAQ,EAAM;EAC3D,IAAI,KAAe,MACjB,OAAO;;CAUX,OALuB,EAAyB,GAAQ,GADjC,EAAS,UAE5B,IAIG;;AAIT,SAAgB,EACd,GACA,GACS;CA6BT,OA5BI,KAAS,OACJ,KAGL,EAAO,SAAS,YACX,OAAO,KAAU,YAGtB,EAAO,SAAS,aACX,OAAO,KAAU,YAAY,EAAM,MAAM,KAAK,KAGnD,EAAO,SAAS,WACX,OAAO,KAAU,YAAY,OAAO,SAAS,EAAM,GAGxD,EAAO,SAAS,aACX,OAAO,KAAU,YAAY,EAAM,MAAM,KAAK,KAGnD,OAAO,KAAU,YAIjB,OAAO,KAAU,WACZ,KAGF,EAAM,MAAM,KAAK"}
1
+ {"version":3,"file":"filterHelpers.js","names":[],"sources":["../../../src/filters/filterHelpers.ts"],"sourcesContent":["import type {\n BackofficeFilterSpec,\n BackofficeRuntimeResolvedListFacetConfig,\n} from '@plumile/backoffice-core/types.js';\n\n/** Compare two optional path arrays for equality. */\nconst arePathsEqual = (\n left?: readonly string[],\n right?: readonly string[],\n): boolean => {\n const leftPath = left ?? [];\n const rightPath = right ?? [];\n if (leftPath.length !== rightPath.length) {\n return false;\n }\n return leftPath.every((segment, index) => {\n return segment === rightPath[index];\n });\n};\n\n/** Find a filter spec by its where key and optional path. */\nexport function resolveFilterForWhereKey(\n config: BackofficeRuntimeResolvedListFacetConfig,\n whereKey: string,\n path?: readonly string[],\n): BackofficeFilterSpec<Record<string, unknown>> | null {\n const { filters } = config.list;\n const match = filters.find((filter) => {\n return (\n String(filter.whereKey ?? filter.id) === whereKey &&\n arePathsEqual(filter.path, path)\n );\n });\n return match ?? null;\n}\n\n/** Resolve a filter spec from a column id, alias, or contains field. */\nexport function resolveFilterForColumn(\n config: BackofficeRuntimeResolvedListFacetConfig,\n columnId: string,\n columnAliases?: Record<string, string>,\n): BackofficeFilterSpec<Record<string, unknown>> | null {\n const direct = resolveFilterForWhereKey(config, columnId);\n if (direct != null) {\n return direct;\n }\n\n const { [columnId]: alias } = columnAliases ?? {};\n if (alias != null) {\n const aliasFilter = resolveFilterForWhereKey(config, alias);\n if (aliasFilter != null) {\n return aliasFilter;\n }\n }\n\n const containsKey = `${columnId}Contains`;\n const containsFilter = resolveFilterForWhereKey(config, containsKey);\n if (containsFilter != null) {\n return containsFilter;\n }\n\n return null;\n}\n\n/** Check if a value is compatible with a filter spec. */\nexport function canFilterValue<Where extends Record<string, unknown>>(\n filter: BackofficeFilterSpec<Where>,\n value: unknown,\n): boolean {\n if (value == null) {\n return false;\n }\n\n if (filter.kind === 'boolean') {\n return typeof value === 'boolean';\n }\n\n if (filter.kind === 'entityId') {\n return typeof value === 'string' && value.trim() !== '';\n }\n\n if (filter.kind === 'number') {\n return typeof value === 'number' && Number.isFinite(value);\n }\n\n if (filter.kind === 'datetime') {\n return typeof value === 'string' && value.trim() !== '';\n }\n\n if (typeof value === 'number') {\n return false;\n }\n\n if (typeof value !== 'string') {\n return false;\n }\n\n return value.trim() !== '';\n}\n"],"mappings":";AAMA,IAAM,KACJ,GACA,MACY;CACZ,IAAM,IAAW,KAAQ,CAAC,GACpB,IAAY,KAAS,CAAC;CAI5B,OAHI,EAAS,WAAW,EAAU,SAG3B,EAAS,OAAO,GAAS,MACvB,MAAY,EAAU,EAC9B,IAJQ;AAKX;AAGA,SAAgB,EACd,GACA,GACA,GACsD;CACtD,IAAM,EAAE,eAAY,EAAO;CAO3B,OANc,EAAQ,MAAM,MAExB,OAAO,EAAO,YAAY,EAAO,EAAE,MAAM,KACzC,EAAc,EAAO,MAAM,CAAI,CAG5B,KAAS;AAClB;AAGA,SAAgB,EACd,GACA,GACA,GACsD;CACtD,IAAM,IAAS,EAAyB,GAAQ,CAAQ;CACxD,IAAI,KAAU,MACZ,OAAO;CAGT,IAAM,GAAG,IAAW,MAAU,KAAiB,CAAC;CAChD,IAAI,KAAS,MAAM;EACjB,IAAM,IAAc,EAAyB,GAAQ,CAAK;EAC1D,IAAI,KAAe,MACjB,OAAO;CAEX;CAQA,OALuB,EAAyB,GAAQ,GADjC,EAAS,SAE5B,KAIG;AACT;AAGA,SAAgB,EACd,GACA,GACS;CA6BT,OA5BI,KAAS,OACJ,KAGL,EAAO,SAAS,YACX,OAAO,KAAU,YAGtB,EAAO,SAAS,aACX,OAAO,KAAU,YAAY,EAAM,KAAK,MAAM,KAGnD,EAAO,SAAS,WACX,OAAO,KAAU,YAAY,OAAO,SAAS,CAAK,IAGvD,EAAO,SAAS,aACX,OAAO,KAAU,YAAY,EAAM,KAAK,MAAM,KAGnD,OAAO,KAAU,YAIjB,OAAO,KAAU,WACZ,KAGF,EAAM,KAAK,MAAM;AAC1B"}