@plumile/backoffice-react 0.1.188 → 0.1.190
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.
- package/lib/esm/auth/login/LoginFlow.js.map +1 -1
- package/lib/esm/auth/login/MethodChooser.js.map +1 -1
- package/lib/esm/auth/login/MfaChallengeForm.js.map +1 -1
- package/lib/esm/auth/login/PasskeyLoginForm.js.map +1 -1
- package/lib/esm/auth/login/loginPage.css.js +2 -0
- package/lib/esm/auth/login/synchronizeAuthStatusQuery.js.map +1 -1
- package/lib/esm/auth/pages/AcceptInvitationScreen.js.map +1 -1
- package/lib/esm/auth/pages/PasswordResetCompleteScreen.js.map +1 -1
- package/lib/esm/auth/pages/PasswordResetRequestScreen.js.map +1 -1
- package/lib/esm/auth/pages/VerifyEmailScreen.js.map +1 -1
- package/lib/esm/components/backoffice/actions/LazyBackofficeEntityActionFormDialog.js.map +1 -1
- package/lib/esm/components/backoffice/billing/BackofficeBillingUsageChart.js.map +1 -1
- package/lib/esm/components/backoffice/columns/buildDataTableColumns.js.map +1 -1
- package/lib/esm/components/backoffice/detail/BackofficeLifecycleTimelineSection.js.map +1 -1
- package/lib/esm/components/backoffice/detail/BackofficeTokenUsageBreakdown.js.map +1 -1
- package/lib/esm/components/backoffice/detail/backofficeDetailRelationLink.css.js +1 -0
- package/lib/esm/components/backoffice/detail/backofficeEntitySummaryHeader.css.js +0 -1
- package/lib/esm/components/backoffice/detail/createBackofficeEntityLinkProps.js.map +1 -1
- package/lib/esm/components/backoffice/detail/detailPayloadUtils.js.map +1 -1
- package/lib/esm/components/backoffice/filters/backofficeFilterAction.css.js +0 -1
- package/lib/esm/components/backoffice/filters/deferredFilterSearchInput.css.js +0 -1
- package/lib/esm/components/backoffice/layout/breadcrumb/assertValidBreadcrumb.js.map +1 -1
- package/lib/esm/components/backoffice/layout/buildSidebarSections.js.map +1 -1
- package/lib/esm/components/backoffice/layout/mapViewerToSidebarProfileView.js.map +1 -1
- package/lib/esm/components/backoffice/layout/sidebarUtils.js.map +1 -1
- package/lib/esm/components/backoffice/links/resolveBackofficeLink.js.map +1 -1
- package/lib/esm/components/backoffice/links/resolveBackofficeTargetIcon.js.map +1 -1
- package/lib/esm/components/backoffice/list/RowFlagsCell.js.map +1 -1
- package/lib/esm/components/backoffice/pickers/EntityIdPickerDialog.js.map +1 -1
- package/lib/esm/components/backoffice/refs/BackofficeLazyEntityCount.js.map +1 -1
- package/lib/esm/components/backoffice/refs/BackofficeRelatedCountLink.js.map +1 -1
- package/lib/esm/components/backoffice/routing/BackofficeContentBoundary.js.map +1 -1
- package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js +368 -281
- package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js.map +1 -1
- package/lib/esm/components/backoffice/scaffolds/backofficeEntityListScaffold.css.js +2 -2
- package/lib/esm/components/backoffice/scaffolds/backofficeEntityListScaffold.css.js.map +1 -1
- package/lib/esm/components/backoffice/shared/backofficeFilterableCell.css.js +1 -1
- package/lib/esm/components/backoffice/technical/TechnicalIdentifierValue.js.map +1 -1
- package/lib/esm/filters/filterHelpers.js +1 -1
- package/lib/esm/filters/filterHelpers.js.map +1 -1
- package/lib/esm/hooks/useAuth.js.map +1 -1
- package/lib/esm/hooks/useBackofficeAuth.js.map +1 -1
- package/lib/esm/hooks/useBackofficeInfiniteScrollSentinel.js.map +1 -1
- package/lib/esm/hooks/useBackofficeListUrlState.js.map +1 -1
- package/lib/esm/hooks/useBackofficeSessionAuth.js.map +1 -1
- package/lib/esm/hooks/useConditionalSubscription.js.map +1 -1
- package/lib/esm/hooks/useSidebarGroupCollapse.js.map +1 -1
- package/lib/esm/i18n/createI18nInstance.js.map +1 -1
- package/lib/esm/i18n/locales/en/backofficeReact.js +409 -405
- package/lib/esm/i18n/locales/en/backofficeReact.js.map +1 -1
- package/lib/esm/i18n/locales/fr/backofficeReact.js +412 -407
- package/lib/esm/i18n/locales/fr/backofficeReact.js.map +1 -1
- package/lib/esm/i18n/mergeResourceLanguages.js.map +1 -1
- package/lib/esm/i18n/resources.js +1 -1
- package/lib/esm/i18n/resources.js.map +1 -1
- package/lib/esm/i18n/useBackofficeFormats.js.map +1 -1
- package/lib/esm/modules/base64.js.map +1 -1
- package/lib/esm/modules/formatFileSize.js.map +1 -1
- package/lib/esm/modules/uploads.js +17 -17
- package/lib/esm/modules/uploads.js.map +1 -1
- package/lib/esm/modules/webauthn.js.map +1 -1
- package/lib/esm/node_modules/@babel/runtime/helpers/objectSpread2.js.map +1 -1
- package/lib/esm/node_modules/@babel/runtime/helpers/toPrimitive.js.map +1 -1
- package/lib/esm/node_modules/@babel/runtime/helpers/toPropertyKey.js.map +1 -1
- package/lib/esm/node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js.map +1 -1
- package/lib/esm/node_modules/@vanilla-extract/recipes/dist/createRuntimeFn-62c9670f.esm.js +1 -1
- package/lib/esm/node_modules/@vanilla-extract/recipes/dist/createRuntimeFn-62c9670f.esm.js.map +1 -1
- package/lib/esm/node_modules/fbjs/lib/areEqual.js.map +1 -1
- package/lib/esm/node_modules/relay-test-utils/lib/RelayMockPayloadGenerator.js.map +1 -1
- package/lib/esm/node_modules/relay-test-utils/lib/RelayModernMockEnvironment.js.map +1 -1
- package/lib/esm/node_modules/relay-test-utils/lib/RelayResolverTestUtils.js.map +1 -1
- package/lib/esm/pages/BackofficeDashboardPage.js.map +1 -1
- package/lib/esm/pages/BackofficeDashboardWidgetContent.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityDetailPage.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityDetailPage.view-helpers.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityListDataPage.js +77 -70
- package/lib/esm/pages/BackofficeEntityListDataPage.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityListPage.helpers.js +5 -5
- package/lib/esm/pages/BackofficeEntityListPage.helpers.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityListPage.js +89 -85
- package/lib/esm/pages/BackofficeEntityListPage.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityListRouteContext.js.map +1 -1
- package/lib/esm/pages/BackofficeHubPage.js.map +1 -1
- package/lib/esm/pages/BackofficeLayoutPage.js.map +1 -1
- package/lib/esm/pages/BackofficeLoginPage.js.map +1 -1
- package/lib/esm/pages/BackofficePasswordResetRequestPage.js.map +1 -1
- package/lib/esm/pages/BackofficeVerifyEmailPage.js.map +1 -1
- package/lib/esm/pages/detail/BackofficeEntityDetailManifestFallback.js.map +1 -1
- package/lib/esm/pages/detail/pageResolution.js.map +1 -1
- package/lib/esm/provider/BackofficeListUiStateContext.js +88 -0
- package/lib/esm/provider/BackofficeListUiStateContext.js.map +1 -0
- package/lib/esm/provider/BackofficeProvider.js +80 -79
- package/lib/esm/provider/BackofficeProvider.js.map +1 -1
- package/lib/esm/provider/entityRegistry.js.map +1 -1
- package/lib/esm/provider/lazyValue.js.map +1 -1
- package/lib/esm/provider/useBackofficeEntityLoader.js.map +1 -1
- package/lib/esm/relay/connectionUtils.js.map +1 -1
- package/lib/esm/relay/envHelpers.js.map +1 -1
- package/lib/esm/router/createBackofficeRoutes.js.map +1 -1
- package/lib/esm/storybook/relay/RelayStory.js.map +1 -1
- package/lib/esm/storybook/relay/mockResolvers.js.map +1 -1
- package/lib/types/components/backoffice/detail/BackofficeLifecycleTimelineSection.d.ts.map +1 -1
- package/lib/types/components/backoffice/pickers/EntityIdPickerDialog.d.ts.map +1 -1
- package/lib/types/components/backoffice/scaffolds/BackofficeEntityListScaffold.d.ts +2 -0
- package/lib/types/components/backoffice/scaffolds/BackofficeEntityListScaffold.d.ts.map +1 -1
- package/lib/types/components/backoffice/scaffolds/backofficeEntityListScaffold.css.d.ts +2 -0
- package/lib/types/components/backoffice/scaffolds/backofficeEntityListScaffold.css.d.ts.map +1 -1
- package/lib/types/components/backoffice/technical/TechnicalIdentifierValue.d.ts.map +1 -1
- package/lib/types/filters/filterHelpers.d.ts.map +1 -1
- package/lib/types/hooks/useAuth.d.ts.map +1 -1
- package/lib/types/i18n/resources.d.ts +7 -0
- package/lib/types/i18n/resources.d.ts.map +1 -1
- package/lib/types/modules/uploads.d.ts.map +1 -1
- package/lib/types/modules/webauthn.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityListDataPage.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityListPage.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityListRouteContext.d.ts +2 -0
- package/lib/types/pages/BackofficeEntityListRouteContext.d.ts.map +1 -1
- package/lib/types/pages/BackofficePasswordResetRequestPage.d.ts.map +1 -1
- package/lib/types/pages/BackofficeVerifyEmailPage.d.ts.map +1 -1
- package/lib/types/pages/detail/pageResolution.d.ts.map +1 -1
- package/lib/types/provider/BackofficeListUiStateContext.d.ts +21 -0
- package/lib/types/provider/BackofficeListUiStateContext.d.ts.map +1 -0
- package/lib/types/provider/BackofficeProvider.d.ts.map +1 -1
- package/lib/types/provider/types.d.ts.map +1 -1
- 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 { Spinner } from '@plumile/ui/backoffice/atoms/spinner/Spinner.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 loadedCountLabel?: ReactNode;\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 loadedCountLabel,\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((): ReactNode => {\n if (loadedCountLabel != null) {\n return loadedCountLabel;\n }\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 }, [loadedCountLabel, 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\n className={styles.tableHost}\n aria-busy={isRefreshing ? 'true' : undefined}\n >\n {isRefreshing && !isLoadingInitial ? (\n <div className={styles.refreshingIndicator} role=\"status\">\n <Spinner size={14} ariaLabel={t('list.refreshingRows')} />\n <span>{t('list.refreshingRows')}</span>\n </div>\n ) : null}\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
|
+
{"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 { Spinner } from '@plumile/ui/backoffice/atoms/spinner/Spinner.js';\nimport { Tag } from '@plumile/ui/backoffice/atoms/tag/Tag.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 type { BackofficeFilterDrawerState } from '../../../provider/BackofficeListUiStateContext.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 normalizeStringArray = (value: unknown): readonly string[] => {\n if (!Array.isArray(value)) {\n return [];\n }\n return value\n .map((entry) => {\n if (entry == null) {\n return null;\n }\n const normalized = String(entry).trim();\n if (normalized === '') {\n return null;\n }\n return normalized;\n })\n .filter((entry): entry is string => {\n return entry != null;\n });\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 = normalizeStringArray(raw);\n\n if (normalized.length === 0) {\n return null;\n }\n\n if (filter.kind === 'entityIdList') {\n return (\n <>\n {normalized.map((id, index) => {\n return (\n <span key={id}>\n <EntityFilterValue entityId={filter.entity} id={id} />\n {index < normalized.length - 1 ? ', ' : null}\n </span>\n );\n })}\n </>\n );\n }\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 loadedCountLabel?: ReactNode;\n emptyState?: JSX.Element;\n statusBanner?: ReactNode;\n isLoadingInitial?: boolean;\n virtualize?: boolean;\n variant?: 'page' | 'embedded';\n showFilters?: boolean;\n filterDrawerState?: BackofficeFilterDrawerState;\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 loadedCountLabel,\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 [localIsFilterDrawerOpen, setLocalIsFilterDrawerOpen] = useState(false);\n const [localFilterSearch, setLocalFilterSearch] = useState('');\n const drawerState = props.filterDrawerState ?? {\n isOpen: localIsFilterDrawerOpen,\n search: localFilterSearch,\n setOpen: setLocalIsFilterDrawerOpen,\n setSearch: setLocalFilterSearch,\n reset: () => {\n setLocalIsFilterDrawerOpen(false);\n setLocalFilterSearch('');\n },\n };\n const isFilterDrawerOpen = drawerState.isOpen;\n const filterSearch = drawerState.search;\n const setIsFilterDrawerOpen = drawerState.setOpen;\n const setFilterSearch = drawerState.setSearch;\n const resetFilterDrawer = drawerState.reset;\n\n const [pickerDialog, setPickerDialog] = useState<{\n entity: string;\n whereKey: keyof RuntimeWhere;\n label: string;\n mode: 'single' | 'list';\n currentIds?: readonly 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={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 />\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={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 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\n if (filter.kind === 'entityIdList') {\n const currentIds = normalizeStringArray(candidate);\n const selectedCount = currentIds.length;\n const displayValue =\n selectedCount === 0\n ? null\n : t('filters.selectedEntities', {\n count: selectedCount,\n });\n\n const removeId = (id: string): void => {\n const nextIds = currentIds.filter((currentId) => {\n return currentId !== id;\n });\n const nextWhere = setWhereValue(\n state.where,\n key,\n nextIds.length === 0 ? null : nextIds,\n filter.path,\n );\n pushState({ ...state, where: nextWhere });\n };\n\n return (\n <div className={styles.entityIdListFilter}>\n <EntityIdFilterField\n label={filterLabelText}\n value={selectedCount === 0 ? null : currentIds.join(',')}\n displayValue={displayValue}\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 mode: 'list',\n currentIds,\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 {currentIds.length > 0 ? (\n <div className={styles.entityIdListTags}>\n {currentIds.map((id) => {\n return (\n <Tag\n key={id}\n removeLabel={t('filters.actions.removeFilterValue', {\n label: filterLabelText,\n })}\n onRemove={() => {\n removeId(id);\n }}\n >\n <EntityFilterValue entityId={filter.entity} id={id} />\n </Tag>\n );\n })}\n </div>\n ) : null}\n </div>\n );\n }\n\n if (filter.kind === 'stringList') {\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 values = next\n .split(/[\\n,]+/u)\n .map((entry) => {\n return entry.trim();\n })\n .filter((entry) => {\n return entry !== '';\n });\n const nextWhere = setWhereValue(\n state.where,\n key,\n values,\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 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 mode: 'single',\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, setIsFilterDrawerOpen, 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 resetFilterDrawer();\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((): ReactNode => {\n if (loadedCountLabel != null) {\n return loadedCountLabel;\n }\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 }, [loadedCountLabel, 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\n className={styles.tableHost}\n aria-busy={isRefreshing ? 'true' : undefined}\n >\n {isRefreshing && !isLoadingInitial ? (\n <div className={styles.refreshingIndicator} role=\"status\">\n <Spinner size={14} ariaLabel={t('list.refreshingRows')} />\n <span>{t('list.refreshingRows')}</span>\n </div>\n ) : null}\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 if (pickerDialog.mode === 'list') {\n const currentIds = pickerDialog.currentIds ?? [];\n const nextIds = currentIds.includes(id)\n ? currentIds\n : [...currentIds, id];\n const nextWhere = setWhereValue(\n state.where,\n pickerDialog.whereKey,\n nextIds,\n pickerDialog.path,\n );\n setIsFilterDrawerOpen(true);\n pushState({ ...state, where: nextWhere });\n return;\n }\n const nextWhere = setWhereValue(\n state.where,\n pickerDialog.whereKey,\n id,\n pickerDialog.path,\n );\n setIsFilterDrawerOpen(true);\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,7 +1,7 @@
|
|
|
1
1
|
/* empty css */
|
|
2
2
|
//#region src/components/backoffice/scaffolds/backofficeEntityListScaffold.css.ts
|
|
3
|
-
var e = "txvbqbfpn txvbqbh7g txvbqbey txvbqbhdl", t = "txvbqb19qg txvbqb19uy txvbqbu4k", n = "txvbqbfpn txvbqbh4x
|
|
3
|
+
var e = "txvbqbfpn txvbqbh7g txvbqbey txvbqbhdl", t = "txvbqb19qg txvbqb19uy txvbqbu4k", n = "txvbqbfpn txvbqbh4x txvbqbhdl txvbqb19us", r = "txvbqbfpn txvbqbh7g txvbqbey txvbqbhd8 txvbqbv7x", i = "txvbqbfpn txvbqbh4x txvbqbhdy", a = "txvbqbfpn txvbqbh4x txvbqbjzu txvbqbu86", o = "txvbqb10mx txvbqb11ki txvbqb12hq txvbqbxtt txvbqbfpn txvbqbey txvbqbhdl txvbqbge txvbqbp66 txvbqb29r txvbqb2sj txvbqb1d9 txvbqb2tz txvbqb1b8p txvbqb1bgt txvbqb9j txvbqbo4z", s = "txvbqb9w txvbqbhbf txvbqb1bgr";
|
|
4
4
|
//#endregion
|
|
5
|
-
export { e as controlsRow,
|
|
5
|
+
export { e as controlsRow, i as embeddedContainer, s as embeddedHeader, n as entityIdListFilter, r as entityIdListTags, t as filterInput, o as refreshingIndicator, a as tableHost };
|
|
6
6
|
|
|
7
7
|
//# sourceMappingURL=backofficeEntityListScaffold.css.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backofficeEntityListScaffold.css.js","names":[],"sources":["../../../../../src/components/backoffice/scaffolds/backofficeEntityListScaffold.css.ts"],"sourcesContent":["import { sprinkles } from '@plumile/ui/theme/sprinkles.css.js';\n\nexport const controlsRow = sprinkles({\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: 2,\n});\n\nexport const filterInput = sprinkles({\n width: {\n base: 72,\n max767: 'full',\n },\n maxWidth: 'full',\n});\n\nexport const embeddedContainer = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 3,\n});\n\nexport const tableHost = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n height: 'full',\n minHeight: 0,\n});\n\nexport const refreshingIndicator = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n alignSelf: 'flex-start',\n paddingX: 2,\n paddingY: 1,\n marginBottom: 2,\n borderWidth: 'px',\n borderStyle: 'solid',\n borderColor: 'borderSubtle',\n borderRadius: 'md',\n backgroundColor: 'surface',\n color: 'textSecondary',\n fontSize: 'sm',\n lineHeight: 'tight',\n});\n\nexport const embeddedHeader = sprinkles({\n fontSize: 'base',\n fontWeight: 'semibold',\n color: 'text',\n});\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"backofficeEntityListScaffold.css.js","names":[],"sources":["../../../../../src/components/backoffice/scaffolds/backofficeEntityListScaffold.css.ts"],"sourcesContent":["import { sprinkles } from '@plumile/ui/theme/sprinkles.css.js';\n\nexport const controlsRow = sprinkles({\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: 2,\n});\n\nexport const filterInput = sprinkles({\n width: {\n base: 72,\n max767: 'full',\n },\n maxWidth: 'full',\n});\n\nexport const entityIdListFilter = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n width: 'full',\n});\n\nexport const entityIdListTags = sprinkles({\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: 1,\n minWidth: 0,\n});\n\nexport const embeddedContainer = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 3,\n});\n\nexport const tableHost = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n height: 'full',\n minHeight: 0,\n});\n\nexport const refreshingIndicator = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n alignSelf: 'flex-start',\n paddingX: 2,\n paddingY: 1,\n marginBottom: 2,\n borderWidth: 'px',\n borderStyle: 'solid',\n borderColor: 'borderSubtle',\n borderRadius: 'md',\n backgroundColor: 'surface',\n color: 'textSecondary',\n fontSize: 'sm',\n lineHeight: 'tight',\n});\n\nexport const embeddedHeader = sprinkles({\n fontSize: 'base',\n fontWeight: 'semibold',\n color: 'text',\n});\n"],"mappings":""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* empty css */
|
|
2
|
-
import {
|
|
2
|
+
import { c as e } from "../../../node_modules/@vanilla-extract/recipes/dist/createRuntimeFn-62c9670f.esm.js";
|
|
3
3
|
//#region src/components/backoffice/shared/backofficeFilterableCell.css.ts
|
|
4
4
|
var t = "_1q232kj0 txvbqbey txvbqberp txvbqbu4k txvbqbv7x txvbqb7z", n = "txvbqbfqq txvbqbey txvbqbls4", r = "txvbqbfqq txvbqbey txvbqbhd8 txvbqbv7x txvbqbu4k", i = e({
|
|
5
5
|
defaultClassName: "_1q232kj1 txvbqbv7x txvbqbu4k",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TechnicalIdentifierValue.js","names":[],"sources":["../../../../../src/components/backoffice/technical/TechnicalIdentifierValue.tsx"],"sourcesContent":["import { type JSX } from 'react';\n\nimport { CopyableText } from '@plumile/ui/backoffice/atoms/copyable_text/CopyableText.js';\n\nconst MIN_ABBREVIATED_LENGTH = 16;\nconst PREFIX_LENGTH = 6;\nconst SUFFIX_LENGTH = 6;\n\nexport type TechnicalIdentifierVariant =\n
|
|
1
|
+
{"version":3,"file":"TechnicalIdentifierValue.js","names":[],"sources":["../../../../../src/components/backoffice/technical/TechnicalIdentifierValue.tsx"],"sourcesContent":["import { type JSX } from 'react';\n\nimport { CopyableText } from '@plumile/ui/backoffice/atoms/copyable_text/CopyableText.js';\n\nconst MIN_ABBREVIATED_LENGTH = 16;\nconst PREFIX_LENGTH = 6;\nconst SUFFIX_LENGTH = 6;\n\nexport type TechnicalIdentifierVariant =\n 'id' | 'hash' | 'token' | 'fingerprint' | 'external';\n\nexport const normalizeTechnicalIdentifier = (\n value: string | number | null | undefined,\n): string | null => {\n if (value == null) {\n return null;\n }\n const normalized = String(value).trim();\n if (normalized === '') {\n return null;\n }\n return normalized;\n};\n\nexport const abbreviateTechnicalIdentifier = (\n value: string,\n variant: TechnicalIdentifierVariant = 'id',\n): string => {\n if (value.length <= MIN_ABBREVIATED_LENGTH) {\n return value;\n }\n\n if (variant === 'fingerprint') {\n const parts = value.split(':');\n if (parts.length > 4) {\n return `${parts.slice(0, 2).join(':')}:...:${parts.slice(-2).join(':')}`;\n }\n }\n\n return `${value.slice(0, PREFIX_LENGTH)}...${value.slice(-SUFFIX_LENGTH)}`;\n};\n\nexport type TechnicalIdentifierValueProps = {\n value: string | number | null | undefined;\n copyValue?: string | null | undefined;\n variant?: TechnicalIdentifierVariant;\n copyLabel: string;\n};\n\nexport const TechnicalIdentifierValue = ({\n value,\n copyValue,\n variant,\n copyLabel,\n}: TechnicalIdentifierValueProps): JSX.Element | null => {\n const normalized = normalizeTechnicalIdentifier(value);\n if (normalized == null) {\n return null;\n }\n\n return (\n <CopyableText\n value={abbreviateTechnicalIdentifier(normalized, variant)}\n copyValue={copyValue ?? normalized}\n copyLabel={copyLabel}\n />\n );\n};\n"],"mappings":";;;AAIA,IAAM,IAAyB,IACzB,IAAgB,GAMT,KACX,MACkB;CAClB,IAAI,KAAS,MACX,OAAO;CAET,IAAM,IAAa,OAAO,CAAK,CAAC,CAAC,KAAK;CAItC,OAHI,MAAe,KACV,OAEF;AACT,GAEa,KACX,GACA,IAAsC,SAC3B;CACX,IAAI,EAAM,UAAU,GAClB,OAAO;CAGT,IAAI,MAAY,eAAe;EAC7B,IAAM,IAAQ,EAAM,MAAM,GAAG;EAC7B,IAAI,EAAM,SAAS,GACjB,OAAO,GAAG,EAAM,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,OAAO,EAAM,MAAM,EAAE,CAAC,CAAC,KAAK,GAAG;CAEzE;CAEA,OAAO,GAAG,EAAM,MAAM,GAAG,CAAa,EAAE,KAAK,EAAM,MAAM,EAAc;AACzE,GASa,KAA4B,EACvC,UACA,cACA,YACA,mBACuD;CACvD,IAAM,IAAa,EAA6B,CAAK;CAKrD,OAJI,KAAc,OACT,OAIP,kBAAC,GAAD;EACE,OAAO,EAA8B,GAAY,CAAO;EACxD,WAAW,KAAa;EACb;CACZ,CAAA;AAEL"}
|
|
@@ -18,7 +18,7 @@ function n(e, n, r) {
|
|
|
18
18
|
return t(e, `${n}Contains`) ?? null;
|
|
19
19
|
}
|
|
20
20
|
function r(e, t) {
|
|
21
|
-
return t == null ? !1 : e.kind === "boolean" ? typeof t == "boolean" : e.kind === "entityId" ? typeof t == "string" && t.trim() !== "" : e.kind === "number" ? typeof t == "number" && Number.isFinite(t) : e.kind === "datetime" ? typeof t == "string" && t.trim() !== "" : typeof t == "number" || typeof t != "string" ? !1 : t.trim() !== "";
|
|
21
|
+
return t == null ? !1 : e.kind === "boolean" ? typeof t == "boolean" : e.kind === "entityId" ? typeof t == "string" && t.trim() !== "" : e.kind === "number" ? typeof t == "number" && Number.isFinite(t) : e.kind === "datetime" ? typeof t == "string" && t.trim() !== "" : e.kind === "stringList" ? typeof t == "string" ? t.trim() !== "" : Array.isArray(t) && t.some((e) => typeof e == "string" && e.trim() !== "") : typeof t == "number" || typeof t != "string" ? !1 : t.trim() !== "";
|
|
22
22
|
}
|
|
23
23
|
//#endregion
|
|
24
24
|
export { r as canFilterValue, n as resolveFilterForColumn, t as resolveFilterForWhereKey };
|
|
@@ -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,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;
|
|
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 (filter.kind === 'stringList') {\n if (typeof value === 'string') {\n return value.trim() !== '';\n }\n return (\n Array.isArray(value) &&\n value.some((entry) => {\n return typeof entry === 'string' && entry.trim() !== '';\n })\n );\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;CAyCT,OAxCI,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,EAAO,SAAS,eACd,OAAO,KAAU,WACZ,EAAM,KAAK,MAAM,KAGxB,MAAM,QAAQ,CAAK,KACnB,EAAM,MAAM,MACH,OAAO,KAAU,YAAY,EAAM,KAAK,MAAM,EACtD,IAID,OAAO,KAAU,YAIjB,OAAO,KAAU,WACZ,KAGF,EAAM,KAAK,MAAM;AAC1B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAuth.js","names":[],"sources":["../../../src/hooks/useAuth.ts"],"sourcesContent":["/* eslint-disable no-ternary */\nimport { useCallback, useState } from 'react';\n\nimport {\n type MutationPayloadBase,\n requireField,\n resolveMutationOutcome,\n} from '../relay/mutationResult.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\n\nimport { resetRelayStore } from '../relay/environment.js';\nimport type { PayloadError } from 'relay-runtime';\n\nimport type {\n AuthMethod,\n LoginNextStep,\n MfaLevel,\n} from '../modules/sharedSchemaTypes.js';\nimport {\n base64UrlToBuffer,\n bufferToBase64Url,\n parseSignCount,\n} from '../modules/webauthn.js';\n\nexport type AuthPayload = {\n authMethod: AuthMethod | null | undefined;\n challengeToken: string | null | undefined;\n loggedInUser: { id: string } | null | undefined;\n mfaLevel: MfaLevel | null | undefined;\n nextStep: LoginNextStep | null | undefined;\n};\n\ntype LoginErrorReason =\n | 'INVALID_CREDENTIALS'\n | 'ACCOUNT_LOCKED'\n | 'RATE_LIMITED'\n | 'INTERNAL_ERROR';\n\ntype LogoutErrorReason =\n | 'UNAUTHENTICATED'\n | 'SESSION_NOT_FOUND'\n | 'INTERNAL_ERROR';\n\ntype BeginAuthenticationErrorReason = 'INVALID_EMAIL' | 'INTERNAL_ERROR';\n\ntype BeginPasskeyLoginErrorReason =\n | 'INVALID_EMAIL'\n | 'PASSKEY_NOT_FOUND'\n | 'PASSKEY_NOT_SUPPORTED'\n | 'INTERNAL_ERROR';\n\ntype FinishPasskeyLoginErrorReason =\n | 'INVALID_CHALLENGE_TOKEN'\n | 'CHALLENGE_EXPIRED'\n | 'INVALID_ASSERTION'\n | 'INTERNAL_ERROR';\n\ntype CompleteMfaErrorReason =\n | 'INVALID_CHALLENGE_TOKEN'\n | 'CHALLENGE_EXPIRED'\n | 'INVALID_CODE'\n | 'TOO_MANY_ATTEMPTS'\n | 'INTERNAL_ERROR';\n\ntype AcceptInvitationErrorReason =\n | 'INVALID_TOKEN'\n | 'TOKEN_EXPIRED'\n | 'ALREADY_ACCEPTED'\n | 'PASSWORD_MISMATCH'\n | 'PASSWORD_POLICY_VIOLATION'\n | 'RATE_LIMITED'\n | 'EMAIL_MISMATCH'\n | 'INTERNAL_ERROR';\n\nexport type BeginAuthenticationPayload =\n MutationPayloadBase<BeginAuthenticationErrorReason> & {\n lockedUntil: string | null | undefined;\n methods: readonly {\n method: AuthMethod;\n mfaEnforced?: boolean | null | undefined;\n }[];\n };\n\nexport type BeginPasskeyLoginPayload =\n MutationPayloadBase<BeginPasskeyLoginErrorReason> & {\n allowCredentials: readonly string[];\n challenge: string;\n challengeToken: string;\n rpId: string;\n };\n\ntype LoginMutationPayload = MutationPayloadBase<LoginErrorReason> & {\n payload?: AuthPayload | null | undefined;\n};\n\ntype LogoutPayload = {\n loggedOut?: boolean | null | undefined;\n};\n\ntype LogoutMutationPayload = MutationPayloadBase<LogoutErrorReason> & {\n payload?: LogoutPayload | null | undefined;\n};\n\ntype CompleteMfaMutationPayload =\n MutationPayloadBase<CompleteMfaErrorReason> & {\n payload?: AuthPayload | null | undefined;\n };\n\ntype FinishPasskeyLoginMutationPayload =\n MutationPayloadBase<FinishPasskeyLoginErrorReason> & {\n payload?: AuthPayload | null | undefined;\n };\n\ntype AcceptInvitationMutationPayload =\n MutationPayloadBase<AcceptInvitationErrorReason> & {\n payload?: AuthPayload | null | undefined;\n };\n\nexport type LoginResponse = { login: AuthPayload | LoginMutationPayload };\nexport type LogoutResponse = { logout: LogoutPayload | LogoutMutationPayload };\nexport type CompleteMfaResponse = {\n completeMfa: AuthPayload | CompleteMfaMutationPayload;\n};\nexport type FinishPasskeyLoginResponse = {\n finishPasskeyLogin: AuthPayload | FinishPasskeyLoginMutationPayload;\n};\nexport type AcceptInvitationResponse = {\n acceptInvitation: AuthPayload | AcceptInvitationMutationPayload;\n};\nexport type BeginAuthenticationResponse = {\n beginAuthentication: BeginAuthenticationPayload;\n};\nexport type BeginPasskeyLoginResponse = {\n beginPasskeyLogin: BeginPasskeyLoginPayload;\n};\n\nexport type LoginVariables = {\n input: LoginCredentials;\n};\n\nexport type LogoutVariables = Record<PropertyKey, never>;\n\nexport type CompleteMfaVariables = {\n input: {\n challengeToken: string;\n code: string;\n };\n};\n\nexport type BeginPasskeyLoginVariables = {\n email: string;\n};\n\nexport type FinishPasskeyLoginVariables = {\n input: {\n challenge: string;\n challengeToken: string;\n credentialId: string;\n signCount: number;\n userHandle?: string | null;\n };\n};\n\nexport type AcceptInvitationVariables = {\n input: {\n token: string;\n password: string;\n passwordConfirmation: string;\n };\n};\n\nexport type BeginAuthenticationVariables = {\n email: string;\n};\n\ntype MutationCommitConfig<TVariables, TResponse> = {\n variables: TVariables;\n onCompleted?: (\n response: TResponse,\n errors: readonly PayloadError[] | null,\n ) => void;\n onError?: (error: Error) => void;\n};\n\ntype MutationCommit<TVariables, TResponse> = (\n config: MutationCommitConfig<TVariables, TResponse>,\n) => void;\n\ntype MutationEntry<TVariables, TResponse> = {\n commit: MutationCommit<TVariables, TResponse>;\n isInFlight: boolean;\n};\n\nexport type AuthMutationHooks = {\n login: MutationEntry<LoginVariables, LoginResponse>;\n logout: MutationEntry<LogoutVariables, LogoutResponse>;\n completeMfa: MutationEntry<CompleteMfaVariables, CompleteMfaResponse>;\n beginPasskeyLogin: MutationEntry<\n BeginPasskeyLoginVariables,\n BeginPasskeyLoginResponse\n >;\n finishPasskeyLogin: MutationEntry<\n FinishPasskeyLoginVariables,\n FinishPasskeyLoginResponse\n >;\n acceptInvitation?: MutationEntry<\n AcceptInvitationVariables,\n AcceptInvitationResponse\n >;\n beginAuthentication: MutationEntry<\n BeginAuthenticationVariables,\n BeginAuthenticationResponse\n >;\n};\n\ninterface User {\n id: string;\n}\n\nexport type LoginStatus = 'success' | 'mfa-required' | 'error';\n\nexport interface LoginCredentials {\n email: string;\n password: string;\n}\n\nexport interface TotpCredentials {\n code: string;\n}\n\nexport interface AcceptInvitationCredentials {\n token: string;\n password: string;\n passwordConfirmation: string;\n}\n\nexport interface AuthError {\n message: string;\n code?: string;\n}\n\nexport interface UseAuthReturn {\n authMethod: AuthMethod | null;\n challengeToken: string | null;\n nextStep: LoginNextStep | null;\n mfaLevel: MfaLevel | null;\n emailHint: string | null;\n lockedUntil: string | null;\n availableMethods: AuthMethod[];\n login: (credentials: LoginCredentials) => Promise<LoginStatus>;\n loginWithPasskey: (params: { email: string }) => Promise<LoginStatus>;\n completeMfa: (credentials: TotpCredentials) => Promise<void>;\n acceptInvitation: (\n credentials: AcceptInvitationCredentials,\n ) => Promise<LoginStatus>;\n beginAuthentication: (\n email: string,\n ) => Promise<{ methods: AuthMethod[]; lockedUntil: string | null }>;\n logout: () => Promise<void>;\n reset: () => void;\n clearError: () => void;\n isLoading: boolean;\n error: AuthError | null;\n user: User | null;\n}\n\nconst initialState = {\n authMethod: null as AuthMethod | null,\n challengeToken: null as string | null,\n emailHint: null as string | null,\n mfaLevel: null as MfaLevel | null,\n nextStep: null as LoginNextStep | null,\n};\n\nexport const createUseAuth = (mutations: AuthMutationHooks) => {\n return (): UseAuthReturn => {\n const { t } = useBackofficeReactTranslation();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<AuthError | null>(null);\n const [user, setUser] = useState<User | null>(null);\n const [lockedUntil, setLockedUntil] = useState<string | null>(null);\n const [availableMethods, setAvailableMethods] = useState<AuthMethod[]>([]);\n const [authState, setAuthState] = useState(initialState);\n\n const commitLoginMutation = mutations.login.commit;\n const commitLogoutMutation = mutations.logout.commit;\n const commitCompleteMfaMutation = mutations.completeMfa.commit;\n const commitBeginPasskeyLoginMutation = mutations.beginPasskeyLogin.commit;\n const commitFinishPasskeyLoginMutation =\n mutations.finishPasskeyLogin.commit;\n const commitAcceptInvitationMutation = mutations.acceptInvitation?.commit;\n const commitBeginAuthenticationMutation =\n mutations.beginAuthentication.commit;\n\n const defaultLoginErrorMessage = t('auth.loginFlow.errors.tryAgain');\n const defaultBeginAuthenticationErrorMessage = t(\n 'auth.loginFlow.errors.tryAgain',\n );\n const defaultPasskeyErrorMessage = t('auth.passkey.errors.failed');\n const defaultMfaErrorMessage = t('auth.mfa.errors.verificationFailed');\n const defaultInvitationErrorMessage = t(\n 'auth.acceptInvitation.errors.default',\n );\n const mfaInvalidChallengeMessage = t('auth.mfa.errors.invalidChallenge');\n const passkeyNotAvailableMessage = t('auth.passkey.errors.notAvailable');\n const defaultLogoutErrorMessage = t('auth.logout.errors.default');\n const passkeyCancelledMessage = t('auth.passkey.errors.cancelled');\n const passkeyNoCredentialMessage = t('auth.passkey.errors.noCredential');\n const invitationUnavailableMessage = t(\n 'auth.acceptInvitation.errors.unavailable',\n );\n\n const reset = useCallback(() => {\n setError(null);\n setUser(null);\n setLockedUntil(null);\n setAvailableMethods([]);\n setAuthState(initialState);\n }, []);\n\n const clearError = useCallback(() => {\n setError(null);\n }, []);\n\n const updateAuthStateFromPayload = useCallback(\n (payload: AuthPayload): LoginStatus => {\n const authMethod = payload.authMethod ?? null;\n const challengeToken = payload.challengeToken ?? null;\n const mfaLevel = payload.mfaLevel ?? null;\n const nextStep = payload.nextStep ?? null;\n\n setAuthState((prev) => {\n return {\n ...prev,\n authMethod,\n challengeToken,\n mfaLevel,\n nextStep,\n };\n });\n\n if (payload.loggedInUser != null && nextStep == null) {\n setUser({\n id: payload.loggedInUser.id,\n });\n return 'success';\n }\n\n if (nextStep === 'TOTP' && challengeToken != null) {\n return 'mfa-required';\n }\n\n return 'error';\n },\n [],\n );\n\n const isMutationPayload = useCallback(\n (value: unknown): value is MutationPayloadBase => {\n return (\n value != null &&\n typeof value === 'object' &&\n ('status' in value || 'result' in value)\n );\n },\n [],\n );\n\n const mapLoginReason = useCallback(\n (reason: LoginErrorReason): string | null => {\n switch (reason) {\n case 'INVALID_CREDENTIALS':\n return t('auth.loginFlow.errors.invalidCredentials');\n case 'ACCOUNT_LOCKED':\n return t('auth.loginFlow.errors.accountLocked');\n case 'RATE_LIMITED':\n return t('auth.loginFlow.errors.rateLimited');\n case 'INTERNAL_ERROR':\n return t('auth.loginFlow.errors.tryAgain');\n default:\n return null;\n }\n },\n [t],\n );\n\n const mapBeginAuthenticationReason = useCallback(\n (reason: BeginAuthenticationErrorReason): string | null => {\n switch (reason) {\n case 'INVALID_EMAIL':\n return t('auth.loginFlow.errors.invalidEmail');\n case 'INTERNAL_ERROR':\n return t('auth.loginFlow.errors.tryAgain');\n default:\n return null;\n }\n },\n [t],\n );\n\n const mapBeginPasskeyLoginReason = useCallback(\n (reason: BeginPasskeyLoginErrorReason): string | null => {\n switch (reason) {\n case 'INVALID_EMAIL':\n return t('auth.passkey.errors.invalidEmail');\n case 'PASSKEY_NOT_FOUND':\n return t('auth.passkey.errors.notFound');\n case 'PASSKEY_NOT_SUPPORTED':\n return t('auth.passkey.errors.notAvailable');\n case 'INTERNAL_ERROR':\n return t('auth.passkey.errors.failed');\n default:\n return null;\n }\n },\n [t],\n );\n\n const mapFinishPasskeyLoginReason = useCallback(\n (reason: FinishPasskeyLoginErrorReason): string | null => {\n switch (reason) {\n case 'INVALID_CHALLENGE_TOKEN':\n return t('auth.passkey.errors.invalidChallenge');\n case 'CHALLENGE_EXPIRED':\n return t('auth.passkey.errors.challengeExpired');\n case 'INVALID_ASSERTION':\n return t('auth.passkey.errors.invalidAssertion');\n case 'INTERNAL_ERROR':\n return t('auth.passkey.errors.failed');\n default:\n return null;\n }\n },\n [t],\n );\n\n const mapCompleteMfaReason = useCallback(\n (reason: CompleteMfaErrorReason): string | null => {\n switch (reason) {\n case 'INVALID_CHALLENGE_TOKEN':\n return t('auth.mfa.errors.invalidChallenge');\n case 'CHALLENGE_EXPIRED':\n return t('auth.mfa.errors.expired');\n case 'INVALID_CODE':\n return t('auth.mfa.errors.invalidCode');\n case 'TOO_MANY_ATTEMPTS':\n return t('auth.mfa.errors.tooManyAttempts');\n case 'INTERNAL_ERROR':\n return t('auth.mfa.errors.verificationFailed');\n default:\n return null;\n }\n },\n [t],\n );\n\n const mapAcceptInvitationReason = useCallback(\n (reason: AcceptInvitationErrorReason): string | null => {\n switch (reason) {\n case 'INVALID_TOKEN':\n return t('auth.acceptInvitation.errors.invalidToken');\n case 'TOKEN_EXPIRED':\n return t('auth.acceptInvitation.errors.expired');\n case 'ALREADY_ACCEPTED':\n return t('auth.acceptInvitation.errors.alreadyAccepted');\n case 'PASSWORD_MISMATCH':\n return t('auth.acceptInvitation.errors.passwordMismatch');\n case 'PASSWORD_POLICY_VIOLATION':\n return t('auth.acceptInvitation.errors.passwordPolicyViolation');\n case 'RATE_LIMITED':\n return t('auth.acceptInvitation.errors.rateLimited');\n case 'EMAIL_MISMATCH':\n return t('auth.acceptInvitation.errors.emailMismatch');\n case 'INTERNAL_ERROR':\n return t('auth.acceptInvitation.errors.default');\n default:\n return null;\n }\n },\n [t],\n );\n\n const beginAuthentication = useCallback(\n async (\n email: string,\n ): Promise<{ methods: AuthMethod[]; lockedUntil: string | null }> => {\n return new Promise((resolve, reject) => {\n commitBeginAuthenticationMutation({\n variables: { email },\n onCompleted: (response) => {\n const rawPayload = response.beginAuthentication;\n let payload = rawPayload;\n\n if (isMutationPayload(rawPayload)) {\n const outcome = resolveMutationOutcome(rawPayload, {\n defaultErrorMessage: defaultBeginAuthenticationErrorMessage,\n mapReason: mapBeginAuthenticationReason,\n });\n if (!outcome.ok) {\n const authError: AuthError = {\n message: outcome.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n payload = outcome.payload;\n }\n\n const methods = payload.methods.map((item) => {\n return item.method;\n });\n const locked = payload.lockedUntil ?? null;\n setAvailableMethods(methods);\n setLockedUntil(locked);\n resolve({ methods, lockedUntil: locked });\n },\n onError: () => {\n const authError: AuthError = {\n message: defaultBeginAuthenticationErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n });\n });\n },\n [\n commitBeginAuthenticationMutation,\n defaultBeginAuthenticationErrorMessage,\n isMutationPayload,\n mapBeginAuthenticationReason,\n ],\n );\n\n const login = useCallback(\n async (credentials: LoginCredentials): Promise<LoginStatus> => {\n setIsLoading(true);\n setError(null);\n setAuthState((prev) => {\n return {\n ...prev,\n emailHint: credentials.email,\n };\n });\n\n return new Promise((resolve, reject) => {\n commitLoginMutation({\n variables: {\n input: credentials,\n },\n onCompleted: (response) => {\n setIsLoading(false);\n const rawPayload = response.login;\n let authPayload: AuthPayload | null = null;\n\n if (isMutationPayload(rawPayload)) {\n const outcome = resolveMutationOutcome(rawPayload, {\n defaultErrorMessage: defaultLoginErrorMessage,\n mapReason: mapLoginReason,\n });\n if (!outcome.ok) {\n const authError: AuthError = {\n message: outcome.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n authPayload = rawPayload.payload ?? null;\n } else {\n authPayload = rawPayload;\n }\n\n if (authPayload == null) {\n const authError: AuthError = {\n message: defaultLoginErrorMessage,\n };\n setError(authError);\n reject(authError);\n return;\n }\n\n const status = updateAuthStateFromPayload(authPayload);\n if (status === 'success' || status === 'mfa-required') {\n resolve(status);\n return;\n }\n\n const authError: AuthError = {\n message: defaultLoginErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n onError: () => {\n setIsLoading(false);\n const authError: AuthError = {\n message: defaultLoginErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n });\n });\n },\n [\n commitLoginMutation,\n defaultLoginErrorMessage,\n isMutationPayload,\n mapLoginReason,\n updateAuthStateFromPayload,\n ],\n );\n\n const completeMfa = useCallback(\n async (credentials: TotpCredentials): Promise<void> => {\n const { challengeToken } = authState;\n if (challengeToken == null) {\n const authError: AuthError = {\n message: mfaInvalidChallengeMessage,\n };\n setError(authError);\n return Promise.reject(authError);\n }\n\n setIsLoading(true);\n setError(null);\n\n return new Promise((resolve, reject) => {\n commitCompleteMfaMutation({\n variables: {\n input: {\n challengeToken,\n code: credentials.code,\n },\n },\n onCompleted: (response) => {\n setIsLoading(false);\n const rawPayload = response.completeMfa;\n let authPayload: AuthPayload | null = null;\n\n if (isMutationPayload(rawPayload)) {\n const outcome = resolveMutationOutcome(rawPayload, {\n defaultErrorMessage: defaultMfaErrorMessage,\n mapReason: mapCompleteMfaReason,\n });\n if (!outcome.ok) {\n const authError: AuthError = {\n message: outcome.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n authPayload = rawPayload.payload ?? null;\n } else {\n authPayload = rawPayload;\n }\n\n if (authPayload == null) {\n const authError: AuthError = {\n message: defaultMfaErrorMessage,\n };\n setError(authError);\n reject(authError);\n return;\n }\n\n const status = updateAuthStateFromPayload(authPayload);\n if (status === 'success') {\n resolve();\n return;\n }\n\n const authError: AuthError = {\n message: defaultMfaErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n onError: () => {\n setIsLoading(false);\n const authError: AuthError = {\n message: defaultMfaErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n });\n });\n },\n [\n authState,\n commitCompleteMfaMutation,\n defaultMfaErrorMessage,\n isMutationPayload,\n mapCompleteMfaReason,\n mfaInvalidChallengeMessage,\n updateAuthStateFromPayload,\n ],\n );\n\n const loginWithPasskey = useCallback(\n async ({ email }: { email: string }): Promise<LoginStatus> => {\n if (typeof window === 'undefined') {\n const authError: AuthError = {\n message: passkeyNotAvailableMessage,\n };\n setError(authError);\n return Promise.reject(authError);\n }\n\n setIsLoading(true);\n setError(null);\n setAuthState((prev) => {\n return {\n ...prev,\n emailHint: email,\n };\n });\n\n return new Promise((resolve, reject) => {\n commitBeginPasskeyLoginMutation({\n variables: {\n email,\n },\n onCompleted: (response) => {\n const rawOptions = response.beginPasskeyLogin;\n let options = rawOptions;\n\n if (isMutationPayload(rawOptions)) {\n const outcome = resolveMutationOutcome(rawOptions, {\n defaultErrorMessage: defaultPasskeyErrorMessage,\n mapReason: mapBeginPasskeyLoginReason,\n });\n if (!outcome.ok) {\n setIsLoading(false);\n const authError: AuthError = {\n message: outcome.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n options = outcome.payload;\n }\n\n const continuePasskeyLogin = async (): Promise<void> => {\n try {\n const assertion = (await navigator.credentials.get({\n publicKey: {\n allowCredentials: options.allowCredentials.map(\n (credentialId) => {\n return {\n id: base64UrlToBuffer(credentialId),\n type: 'public-key' as const,\n };\n },\n ),\n challenge: base64UrlToBuffer(options.challenge),\n rpId: options.rpId,\n userVerification: 'preferred',\n },\n })) as PublicKeyCredential | null;\n\n if (assertion == null) {\n throw new Error('PASSKEY_NO_CREDENTIAL');\n }\n\n const assertionResponse =\n assertion.response as AuthenticatorAssertionResponse;\n const signCount = parseSignCount(\n assertionResponse.authenticatorData,\n );\n\n commitFinishPasskeyLoginMutation({\n variables: {\n input: {\n challenge: options.challenge,\n challengeToken: options.challengeToken,\n credentialId: assertion.id,\n signCount,\n userHandle:\n assertionResponse.userHandle != null\n ? bufferToBase64Url(assertionResponse.userHandle)\n : null,\n },\n },\n onCompleted: (finishResponse) => {\n setIsLoading(false);\n const rawPayload = finishResponse.finishPasskeyLogin;\n let authPayload: AuthPayload | null = null;\n\n if (isMutationPayload(rawPayload)) {\n const outcome = resolveMutationOutcome(rawPayload, {\n defaultErrorMessage: defaultPasskeyErrorMessage,\n mapReason: mapFinishPasskeyLoginReason,\n });\n if (!outcome.ok) {\n const authError: AuthError = {\n message: outcome.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n authPayload = rawPayload.payload ?? null;\n } else {\n authPayload = rawPayload;\n }\n\n if (authPayload == null) {\n const authError: AuthError = {\n message: defaultPasskeyErrorMessage,\n };\n setError(authError);\n reject(authError);\n return;\n }\n\n const status = updateAuthStateFromPayload(authPayload);\n if (status === 'success') {\n resolve(status);\n return;\n }\n const authError: AuthError = {\n message: defaultPasskeyErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n onError: () => {\n setIsLoading(false);\n const authError: AuthError = {\n message: defaultPasskeyErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n });\n } catch (credentialError) {\n setIsLoading(false);\n let message = defaultPasskeyErrorMessage;\n if (\n credentialError instanceof Error &&\n credentialError.message === 'PASSKEY_NO_CREDENTIAL'\n ) {\n message = passkeyNoCredentialMessage;\n } else if (\n typeof DOMException !== 'undefined' &&\n credentialError instanceof DOMException\n ) {\n if (\n credentialError.name === 'AbortError' ||\n credentialError.name === 'NotAllowedError'\n ) {\n message = passkeyCancelledMessage;\n } else if (\n credentialError.name === 'InvalidStateError' ||\n credentialError.name === 'NotSupportedError' ||\n credentialError.name === 'SecurityError'\n ) {\n message = passkeyNotAvailableMessage;\n }\n }\n const authError: AuthError = {\n message,\n };\n setError(authError);\n reject(authError);\n }\n };\n\n continuePasskeyLogin().catch(() => {\n return undefined;\n });\n },\n onError: () => {\n setIsLoading(false);\n const authError: AuthError = {\n message: defaultPasskeyErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n });\n });\n },\n [\n commitBeginPasskeyLoginMutation,\n commitFinishPasskeyLoginMutation,\n defaultPasskeyErrorMessage,\n isMutationPayload,\n mapBeginPasskeyLoginReason,\n mapFinishPasskeyLoginReason,\n passkeyCancelledMessage,\n passkeyNoCredentialMessage,\n passkeyNotAvailableMessage,\n updateAuthStateFromPayload,\n ],\n );\n\n const acceptInvitation = useCallback(\n async (\n credentials: AcceptInvitationCredentials,\n ): Promise<LoginStatus> => {\n if (commitAcceptInvitationMutation == null) {\n const authError: AuthError = {\n message: invitationUnavailableMessage,\n };\n setError(authError);\n return Promise.reject(authError);\n }\n\n setIsLoading(true);\n setError(null);\n\n return new Promise((resolve, reject) => {\n commitAcceptInvitationMutation({\n variables: {\n input: {\n token: credentials.token,\n password: credentials.password,\n passwordConfirmation: credentials.passwordConfirmation,\n },\n },\n onCompleted: (response) => {\n setIsLoading(false);\n const rawPayload = response.acceptInvitation;\n let authPayload: AuthPayload | null = null;\n\n if (isMutationPayload(rawPayload)) {\n const outcome = resolveMutationOutcome(rawPayload, {\n defaultErrorMessage: defaultInvitationErrorMessage,\n mapReason: mapAcceptInvitationReason,\n });\n if (!outcome.ok) {\n const authError: AuthError = {\n message: outcome.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n authPayload = rawPayload.payload ?? null;\n } else {\n authPayload = rawPayload;\n }\n\n if (authPayload == null) {\n const authError: AuthError = {\n message: defaultInvitationErrorMessage,\n };\n setError(authError);\n reject(authError);\n return;\n }\n\n const status = updateAuthStateFromPayload(authPayload);\n if (status === 'success' || status === 'mfa-required') {\n resolve(status);\n return;\n }\n const authError: AuthError = {\n message: defaultInvitationErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n onError: () => {\n setIsLoading(false);\n const authError: AuthError = {\n message: defaultInvitationErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n });\n });\n },\n [\n commitAcceptInvitationMutation,\n defaultInvitationErrorMessage,\n invitationUnavailableMessage,\n isMutationPayload,\n mapAcceptInvitationReason,\n updateAuthStateFromPayload,\n ],\n );\n\n const logout = useCallback(async (): Promise<void> => {\n setIsLoading(true);\n\n return new Promise((resolve, reject) => {\n commitLogoutMutation({\n variables: {},\n onCompleted: (response) => {\n setIsLoading(false);\n const rawPayload = response.logout;\n let loggedOutValue: boolean | null = null;\n\n if (isMutationPayload(rawPayload)) {\n const outcome = resolveMutationOutcome(rawPayload, {\n defaultErrorMessage: defaultLogoutErrorMessage,\n });\n if (!outcome.ok) {\n const authError: AuthError = { message: outcome.message };\n setError(authError);\n reject(authError);\n return;\n }\n\n const loggedOutResult = requireField(\n rawPayload.payload?.loggedOut ?? null,\n defaultLogoutErrorMessage,\n );\n if (!loggedOutResult.ok) {\n const authError: AuthError = {\n message: loggedOutResult.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n loggedOutValue = loggedOutResult.value;\n } else {\n const loggedOutResult = requireField(\n rawPayload.loggedOut ?? null,\n defaultLogoutErrorMessage,\n );\n if (!loggedOutResult.ok) {\n const authError: AuthError = {\n message: loggedOutResult.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n loggedOutValue = loggedOutResult.value;\n }\n\n if (!loggedOutValue) {\n const authError: AuthError = {\n message: defaultLogoutErrorMessage,\n };\n setError(authError);\n reject(authError);\n return;\n }\n\n localStorage.removeItem('auth_token');\n localStorage.removeItem('remember_me');\n setUser(null);\n setAuthState(initialState);\n resetRelayStore();\n\n resolve();\n },\n onError: () => {\n setIsLoading(false);\n const authError: AuthError = {\n message: defaultLogoutErrorMessage,\n };\n setError(authError);\n resetRelayStore();\n\n reject(authError);\n },\n });\n });\n }, [commitLogoutMutation, defaultLogoutErrorMessage, isMutationPayload]);\n\n const combinedIsLoading =\n isLoading ||\n mutations.login.isInFlight ||\n mutations.logout.isInFlight ||\n mutations.completeMfa.isInFlight ||\n mutations.beginPasskeyLogin.isInFlight ||\n mutations.finishPasskeyLogin.isInFlight ||\n (mutations.acceptInvitation?.isInFlight ?? false) ||\n mutations.beginAuthentication.isInFlight;\n\n return {\n authMethod: authState.authMethod,\n challengeToken: authState.challengeToken,\n nextStep: authState.nextStep,\n mfaLevel: authState.mfaLevel,\n emailHint: authState.emailHint,\n login,\n loginWithPasskey,\n completeMfa,\n acceptInvitation,\n beginAuthentication,\n logout,\n reset,\n clearError,\n isLoading: combinedIsLoading,\n error,\n user,\n lockedUntil,\n availableMethods,\n };\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useAuth.js","names":[],"sources":["../../../src/hooks/useAuth.ts"],"sourcesContent":["/* eslint-disable no-ternary */\nimport { useCallback, useState } from 'react';\n\nimport {\n type MutationPayloadBase,\n requireField,\n resolveMutationOutcome,\n} from '../relay/mutationResult.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\n\nimport { resetRelayStore } from '../relay/environment.js';\nimport type { PayloadError } from 'relay-runtime';\n\nimport type {\n AuthMethod,\n LoginNextStep,\n MfaLevel,\n} from '../modules/sharedSchemaTypes.js';\nimport {\n base64UrlToBuffer,\n bufferToBase64Url,\n parseSignCount,\n} from '../modules/webauthn.js';\n\nexport type AuthPayload = {\n authMethod: AuthMethod | null | undefined;\n challengeToken: string | null | undefined;\n loggedInUser: { id: string } | null | undefined;\n mfaLevel: MfaLevel | null | undefined;\n nextStep: LoginNextStep | null | undefined;\n};\n\ntype LoginErrorReason =\n 'INVALID_CREDENTIALS' | 'ACCOUNT_LOCKED' | 'RATE_LIMITED' | 'INTERNAL_ERROR';\n\ntype LogoutErrorReason =\n 'UNAUTHENTICATED' | 'SESSION_NOT_FOUND' | 'INTERNAL_ERROR';\n\ntype BeginAuthenticationErrorReason = 'INVALID_EMAIL' | 'INTERNAL_ERROR';\n\ntype BeginPasskeyLoginErrorReason =\n | 'INVALID_EMAIL'\n | 'PASSKEY_NOT_FOUND'\n | 'PASSKEY_NOT_SUPPORTED'\n | 'INTERNAL_ERROR';\n\ntype FinishPasskeyLoginErrorReason =\n | 'INVALID_CHALLENGE_TOKEN'\n | 'CHALLENGE_EXPIRED'\n | 'INVALID_ASSERTION'\n | 'INTERNAL_ERROR';\n\ntype CompleteMfaErrorReason =\n | 'INVALID_CHALLENGE_TOKEN'\n | 'CHALLENGE_EXPIRED'\n | 'INVALID_CODE'\n | 'TOO_MANY_ATTEMPTS'\n | 'INTERNAL_ERROR';\n\ntype AcceptInvitationErrorReason =\n | 'INVALID_TOKEN'\n | 'TOKEN_EXPIRED'\n | 'ALREADY_ACCEPTED'\n | 'PASSWORD_MISMATCH'\n | 'PASSWORD_POLICY_VIOLATION'\n | 'RATE_LIMITED'\n | 'EMAIL_MISMATCH'\n | 'INTERNAL_ERROR';\n\nexport type BeginAuthenticationPayload =\n MutationPayloadBase<BeginAuthenticationErrorReason> & {\n lockedUntil: string | null | undefined;\n methods: readonly {\n method: AuthMethod;\n mfaEnforced?: boolean | null | undefined;\n }[];\n };\n\nexport type BeginPasskeyLoginPayload =\n MutationPayloadBase<BeginPasskeyLoginErrorReason> & {\n allowCredentials: readonly string[];\n challenge: string;\n challengeToken: string;\n rpId: string;\n };\n\ntype LoginMutationPayload = MutationPayloadBase<LoginErrorReason> & {\n payload?: AuthPayload | null | undefined;\n};\n\ntype LogoutPayload = {\n loggedOut?: boolean | null | undefined;\n};\n\ntype LogoutMutationPayload = MutationPayloadBase<LogoutErrorReason> & {\n payload?: LogoutPayload | null | undefined;\n};\n\ntype CompleteMfaMutationPayload =\n MutationPayloadBase<CompleteMfaErrorReason> & {\n payload?: AuthPayload | null | undefined;\n };\n\ntype FinishPasskeyLoginMutationPayload =\n MutationPayloadBase<FinishPasskeyLoginErrorReason> & {\n payload?: AuthPayload | null | undefined;\n };\n\ntype AcceptInvitationMutationPayload =\n MutationPayloadBase<AcceptInvitationErrorReason> & {\n payload?: AuthPayload | null | undefined;\n };\n\nexport type LoginResponse = { login: AuthPayload | LoginMutationPayload };\nexport type LogoutResponse = { logout: LogoutPayload | LogoutMutationPayload };\nexport type CompleteMfaResponse = {\n completeMfa: AuthPayload | CompleteMfaMutationPayload;\n};\nexport type FinishPasskeyLoginResponse = {\n finishPasskeyLogin: AuthPayload | FinishPasskeyLoginMutationPayload;\n};\nexport type AcceptInvitationResponse = {\n acceptInvitation: AuthPayload | AcceptInvitationMutationPayload;\n};\nexport type BeginAuthenticationResponse = {\n beginAuthentication: BeginAuthenticationPayload;\n};\nexport type BeginPasskeyLoginResponse = {\n beginPasskeyLogin: BeginPasskeyLoginPayload;\n};\n\nexport type LoginVariables = {\n input: LoginCredentials;\n};\n\nexport type LogoutVariables = Record<PropertyKey, never>;\n\nexport type CompleteMfaVariables = {\n input: {\n challengeToken: string;\n code: string;\n };\n};\n\nexport type BeginPasskeyLoginVariables = {\n email: string;\n};\n\nexport type FinishPasskeyLoginVariables = {\n input: {\n challenge: string;\n challengeToken: string;\n credentialId: string;\n signCount: number;\n userHandle?: string | null;\n };\n};\n\nexport type AcceptInvitationVariables = {\n input: {\n token: string;\n password: string;\n passwordConfirmation: string;\n };\n};\n\nexport type BeginAuthenticationVariables = {\n email: string;\n};\n\ntype MutationCommitConfig<TVariables, TResponse> = {\n variables: TVariables;\n onCompleted?: (\n response: TResponse,\n errors: readonly PayloadError[] | null,\n ) => void;\n onError?: (error: Error) => void;\n};\n\ntype MutationCommit<TVariables, TResponse> = (\n config: MutationCommitConfig<TVariables, TResponse>,\n) => void;\n\ntype MutationEntry<TVariables, TResponse> = {\n commit: MutationCommit<TVariables, TResponse>;\n isInFlight: boolean;\n};\n\nexport type AuthMutationHooks = {\n login: MutationEntry<LoginVariables, LoginResponse>;\n logout: MutationEntry<LogoutVariables, LogoutResponse>;\n completeMfa: MutationEntry<CompleteMfaVariables, CompleteMfaResponse>;\n beginPasskeyLogin: MutationEntry<\n BeginPasskeyLoginVariables,\n BeginPasskeyLoginResponse\n >;\n finishPasskeyLogin: MutationEntry<\n FinishPasskeyLoginVariables,\n FinishPasskeyLoginResponse\n >;\n acceptInvitation?: MutationEntry<\n AcceptInvitationVariables,\n AcceptInvitationResponse\n >;\n beginAuthentication: MutationEntry<\n BeginAuthenticationVariables,\n BeginAuthenticationResponse\n >;\n};\n\ninterface User {\n id: string;\n}\n\nexport type LoginStatus = 'success' | 'mfa-required' | 'error';\n\nexport interface LoginCredentials {\n email: string;\n password: string;\n}\n\nexport interface TotpCredentials {\n code: string;\n}\n\nexport interface AcceptInvitationCredentials {\n token: string;\n password: string;\n passwordConfirmation: string;\n}\n\nexport interface AuthError {\n message: string;\n code?: string;\n}\n\nexport interface UseAuthReturn {\n authMethod: AuthMethod | null;\n challengeToken: string | null;\n nextStep: LoginNextStep | null;\n mfaLevel: MfaLevel | null;\n emailHint: string | null;\n lockedUntil: string | null;\n availableMethods: AuthMethod[];\n login: (credentials: LoginCredentials) => Promise<LoginStatus>;\n loginWithPasskey: (params: { email: string }) => Promise<LoginStatus>;\n completeMfa: (credentials: TotpCredentials) => Promise<void>;\n acceptInvitation: (\n credentials: AcceptInvitationCredentials,\n ) => Promise<LoginStatus>;\n beginAuthentication: (\n email: string,\n ) => Promise<{ methods: AuthMethod[]; lockedUntil: string | null }>;\n logout: () => Promise<void>;\n reset: () => void;\n clearError: () => void;\n isLoading: boolean;\n error: AuthError | null;\n user: User | null;\n}\n\nconst initialState = {\n authMethod: null as AuthMethod | null,\n challengeToken: null as string | null,\n emailHint: null as string | null,\n mfaLevel: null as MfaLevel | null,\n nextStep: null as LoginNextStep | null,\n};\n\nexport const createUseAuth = (mutations: AuthMutationHooks) => {\n return (): UseAuthReturn => {\n const { t } = useBackofficeReactTranslation();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<AuthError | null>(null);\n const [user, setUser] = useState<User | null>(null);\n const [lockedUntil, setLockedUntil] = useState<string | null>(null);\n const [availableMethods, setAvailableMethods] = useState<AuthMethod[]>([]);\n const [authState, setAuthState] = useState(initialState);\n\n const commitLoginMutation = mutations.login.commit;\n const commitLogoutMutation = mutations.logout.commit;\n const commitCompleteMfaMutation = mutations.completeMfa.commit;\n const commitBeginPasskeyLoginMutation = mutations.beginPasskeyLogin.commit;\n const commitFinishPasskeyLoginMutation =\n mutations.finishPasskeyLogin.commit;\n const commitAcceptInvitationMutation = mutations.acceptInvitation?.commit;\n const commitBeginAuthenticationMutation =\n mutations.beginAuthentication.commit;\n\n const defaultLoginErrorMessage = t('auth.loginFlow.errors.tryAgain');\n const defaultBeginAuthenticationErrorMessage = t(\n 'auth.loginFlow.errors.tryAgain',\n );\n const defaultPasskeyErrorMessage = t('auth.passkey.errors.failed');\n const defaultMfaErrorMessage = t('auth.mfa.errors.verificationFailed');\n const defaultInvitationErrorMessage = t(\n 'auth.acceptInvitation.errors.default',\n );\n const mfaInvalidChallengeMessage = t('auth.mfa.errors.invalidChallenge');\n const passkeyNotAvailableMessage = t('auth.passkey.errors.notAvailable');\n const defaultLogoutErrorMessage = t('auth.logout.errors.default');\n const passkeyCancelledMessage = t('auth.passkey.errors.cancelled');\n const passkeyNoCredentialMessage = t('auth.passkey.errors.noCredential');\n const invitationUnavailableMessage = t(\n 'auth.acceptInvitation.errors.unavailable',\n );\n\n const reset = useCallback(() => {\n setError(null);\n setUser(null);\n setLockedUntil(null);\n setAvailableMethods([]);\n setAuthState(initialState);\n }, []);\n\n const clearError = useCallback(() => {\n setError(null);\n }, []);\n\n const updateAuthStateFromPayload = useCallback(\n (payload: AuthPayload): LoginStatus => {\n const authMethod = payload.authMethod ?? null;\n const challengeToken = payload.challengeToken ?? null;\n const mfaLevel = payload.mfaLevel ?? null;\n const nextStep = payload.nextStep ?? null;\n\n setAuthState((prev) => {\n return {\n ...prev,\n authMethod,\n challengeToken,\n mfaLevel,\n nextStep,\n };\n });\n\n if (payload.loggedInUser != null && nextStep == null) {\n setUser({\n id: payload.loggedInUser.id,\n });\n return 'success';\n }\n\n if (nextStep === 'TOTP' && challengeToken != null) {\n return 'mfa-required';\n }\n\n return 'error';\n },\n [],\n );\n\n const isMutationPayload = useCallback(\n (value: unknown): value is MutationPayloadBase => {\n return (\n value != null &&\n typeof value === 'object' &&\n ('status' in value || 'result' in value)\n );\n },\n [],\n );\n\n const mapLoginReason = useCallback(\n (reason: LoginErrorReason): string | null => {\n switch (reason) {\n case 'INVALID_CREDENTIALS':\n return t('auth.loginFlow.errors.invalidCredentials');\n case 'ACCOUNT_LOCKED':\n return t('auth.loginFlow.errors.accountLocked');\n case 'RATE_LIMITED':\n return t('auth.loginFlow.errors.rateLimited');\n case 'INTERNAL_ERROR':\n return t('auth.loginFlow.errors.tryAgain');\n default:\n return null;\n }\n },\n [t],\n );\n\n const mapBeginAuthenticationReason = useCallback(\n (reason: BeginAuthenticationErrorReason): string | null => {\n switch (reason) {\n case 'INVALID_EMAIL':\n return t('auth.loginFlow.errors.invalidEmail');\n case 'INTERNAL_ERROR':\n return t('auth.loginFlow.errors.tryAgain');\n default:\n return null;\n }\n },\n [t],\n );\n\n const mapBeginPasskeyLoginReason = useCallback(\n (reason: BeginPasskeyLoginErrorReason): string | null => {\n switch (reason) {\n case 'INVALID_EMAIL':\n return t('auth.passkey.errors.invalidEmail');\n case 'PASSKEY_NOT_FOUND':\n return t('auth.passkey.errors.notFound');\n case 'PASSKEY_NOT_SUPPORTED':\n return t('auth.passkey.errors.notAvailable');\n case 'INTERNAL_ERROR':\n return t('auth.passkey.errors.failed');\n default:\n return null;\n }\n },\n [t],\n );\n\n const mapFinishPasskeyLoginReason = useCallback(\n (reason: FinishPasskeyLoginErrorReason): string | null => {\n switch (reason) {\n case 'INVALID_CHALLENGE_TOKEN':\n return t('auth.passkey.errors.invalidChallenge');\n case 'CHALLENGE_EXPIRED':\n return t('auth.passkey.errors.challengeExpired');\n case 'INVALID_ASSERTION':\n return t('auth.passkey.errors.invalidAssertion');\n case 'INTERNAL_ERROR':\n return t('auth.passkey.errors.failed');\n default:\n return null;\n }\n },\n [t],\n );\n\n const mapCompleteMfaReason = useCallback(\n (reason: CompleteMfaErrorReason): string | null => {\n switch (reason) {\n case 'INVALID_CHALLENGE_TOKEN':\n return t('auth.mfa.errors.invalidChallenge');\n case 'CHALLENGE_EXPIRED':\n return t('auth.mfa.errors.expired');\n case 'INVALID_CODE':\n return t('auth.mfa.errors.invalidCode');\n case 'TOO_MANY_ATTEMPTS':\n return t('auth.mfa.errors.tooManyAttempts');\n case 'INTERNAL_ERROR':\n return t('auth.mfa.errors.verificationFailed');\n default:\n return null;\n }\n },\n [t],\n );\n\n const mapAcceptInvitationReason = useCallback(\n (reason: AcceptInvitationErrorReason): string | null => {\n switch (reason) {\n case 'INVALID_TOKEN':\n return t('auth.acceptInvitation.errors.invalidToken');\n case 'TOKEN_EXPIRED':\n return t('auth.acceptInvitation.errors.expired');\n case 'ALREADY_ACCEPTED':\n return t('auth.acceptInvitation.errors.alreadyAccepted');\n case 'PASSWORD_MISMATCH':\n return t('auth.acceptInvitation.errors.passwordMismatch');\n case 'PASSWORD_POLICY_VIOLATION':\n return t('auth.acceptInvitation.errors.passwordPolicyViolation');\n case 'RATE_LIMITED':\n return t('auth.acceptInvitation.errors.rateLimited');\n case 'EMAIL_MISMATCH':\n return t('auth.acceptInvitation.errors.emailMismatch');\n case 'INTERNAL_ERROR':\n return t('auth.acceptInvitation.errors.default');\n default:\n return null;\n }\n },\n [t],\n );\n\n const beginAuthentication = useCallback(\n async (\n email: string,\n ): Promise<{ methods: AuthMethod[]; lockedUntil: string | null }> => {\n return new Promise((resolve, reject) => {\n commitBeginAuthenticationMutation({\n variables: { email },\n onCompleted: (response) => {\n const rawPayload = response.beginAuthentication;\n let payload = rawPayload;\n\n if (isMutationPayload(rawPayload)) {\n const outcome = resolveMutationOutcome(rawPayload, {\n defaultErrorMessage: defaultBeginAuthenticationErrorMessage,\n mapReason: mapBeginAuthenticationReason,\n });\n if (!outcome.ok) {\n const authError: AuthError = {\n message: outcome.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n payload = outcome.payload;\n }\n\n const methods = payload.methods.map((item) => {\n return item.method;\n });\n const locked = payload.lockedUntil ?? null;\n setAvailableMethods(methods);\n setLockedUntil(locked);\n resolve({ methods, lockedUntil: locked });\n },\n onError: () => {\n const authError: AuthError = {\n message: defaultBeginAuthenticationErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n });\n });\n },\n [\n commitBeginAuthenticationMutation,\n defaultBeginAuthenticationErrorMessage,\n isMutationPayload,\n mapBeginAuthenticationReason,\n ],\n );\n\n const login = useCallback(\n async (credentials: LoginCredentials): Promise<LoginStatus> => {\n setIsLoading(true);\n setError(null);\n setAuthState((prev) => {\n return {\n ...prev,\n emailHint: credentials.email,\n };\n });\n\n return new Promise((resolve, reject) => {\n commitLoginMutation({\n variables: {\n input: credentials,\n },\n onCompleted: (response) => {\n setIsLoading(false);\n const rawPayload = response.login;\n let authPayload: AuthPayload | null = null;\n\n if (isMutationPayload(rawPayload)) {\n const outcome = resolveMutationOutcome(rawPayload, {\n defaultErrorMessage: defaultLoginErrorMessage,\n mapReason: mapLoginReason,\n });\n if (!outcome.ok) {\n const authError: AuthError = {\n message: outcome.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n authPayload = rawPayload.payload ?? null;\n } else {\n authPayload = rawPayload;\n }\n\n if (authPayload == null) {\n const authError: AuthError = {\n message: defaultLoginErrorMessage,\n };\n setError(authError);\n reject(authError);\n return;\n }\n\n const status = updateAuthStateFromPayload(authPayload);\n if (status === 'success' || status === 'mfa-required') {\n resolve(status);\n return;\n }\n\n const authError: AuthError = {\n message: defaultLoginErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n onError: () => {\n setIsLoading(false);\n const authError: AuthError = {\n message: defaultLoginErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n });\n });\n },\n [\n commitLoginMutation,\n defaultLoginErrorMessage,\n isMutationPayload,\n mapLoginReason,\n updateAuthStateFromPayload,\n ],\n );\n\n const completeMfa = useCallback(\n async (credentials: TotpCredentials): Promise<void> => {\n const { challengeToken } = authState;\n if (challengeToken == null) {\n const authError: AuthError = {\n message: mfaInvalidChallengeMessage,\n };\n setError(authError);\n return Promise.reject(authError);\n }\n\n setIsLoading(true);\n setError(null);\n\n return new Promise((resolve, reject) => {\n commitCompleteMfaMutation({\n variables: {\n input: {\n challengeToken,\n code: credentials.code,\n },\n },\n onCompleted: (response) => {\n setIsLoading(false);\n const rawPayload = response.completeMfa;\n let authPayload: AuthPayload | null = null;\n\n if (isMutationPayload(rawPayload)) {\n const outcome = resolveMutationOutcome(rawPayload, {\n defaultErrorMessage: defaultMfaErrorMessage,\n mapReason: mapCompleteMfaReason,\n });\n if (!outcome.ok) {\n const authError: AuthError = {\n message: outcome.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n authPayload = rawPayload.payload ?? null;\n } else {\n authPayload = rawPayload;\n }\n\n if (authPayload == null) {\n const authError: AuthError = {\n message: defaultMfaErrorMessage,\n };\n setError(authError);\n reject(authError);\n return;\n }\n\n const status = updateAuthStateFromPayload(authPayload);\n if (status === 'success') {\n resolve();\n return;\n }\n\n const authError: AuthError = {\n message: defaultMfaErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n onError: () => {\n setIsLoading(false);\n const authError: AuthError = {\n message: defaultMfaErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n });\n });\n },\n [\n authState,\n commitCompleteMfaMutation,\n defaultMfaErrorMessage,\n isMutationPayload,\n mapCompleteMfaReason,\n mfaInvalidChallengeMessage,\n updateAuthStateFromPayload,\n ],\n );\n\n const loginWithPasskey = useCallback(\n async ({ email }: { email: string }): Promise<LoginStatus> => {\n if (typeof window === 'undefined') {\n const authError: AuthError = {\n message: passkeyNotAvailableMessage,\n };\n setError(authError);\n return Promise.reject(authError);\n }\n\n setIsLoading(true);\n setError(null);\n setAuthState((prev) => {\n return {\n ...prev,\n emailHint: email,\n };\n });\n\n return new Promise((resolve, reject) => {\n commitBeginPasskeyLoginMutation({\n variables: {\n email,\n },\n onCompleted: (response) => {\n const rawOptions = response.beginPasskeyLogin;\n let options = rawOptions;\n\n if (isMutationPayload(rawOptions)) {\n const outcome = resolveMutationOutcome(rawOptions, {\n defaultErrorMessage: defaultPasskeyErrorMessage,\n mapReason: mapBeginPasskeyLoginReason,\n });\n if (!outcome.ok) {\n setIsLoading(false);\n const authError: AuthError = {\n message: outcome.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n options = outcome.payload;\n }\n\n const continuePasskeyLogin = async (): Promise<void> => {\n try {\n const assertion = (await navigator.credentials.get({\n publicKey: {\n allowCredentials: options.allowCredentials.map(\n (credentialId) => {\n return {\n id: base64UrlToBuffer(credentialId),\n type: 'public-key' as const,\n };\n },\n ),\n challenge: base64UrlToBuffer(options.challenge),\n rpId: options.rpId,\n userVerification: 'preferred',\n },\n })) as PublicKeyCredential | null;\n\n if (assertion == null) {\n throw new Error('PASSKEY_NO_CREDENTIAL');\n }\n\n const assertionResponse =\n assertion.response as AuthenticatorAssertionResponse;\n const signCount = parseSignCount(\n assertionResponse.authenticatorData,\n );\n\n commitFinishPasskeyLoginMutation({\n variables: {\n input: {\n challenge: options.challenge,\n challengeToken: options.challengeToken,\n credentialId: assertion.id,\n signCount,\n userHandle:\n assertionResponse.userHandle != null\n ? bufferToBase64Url(assertionResponse.userHandle)\n : null,\n },\n },\n onCompleted: (finishResponse) => {\n setIsLoading(false);\n const rawPayload = finishResponse.finishPasskeyLogin;\n let authPayload: AuthPayload | null = null;\n\n if (isMutationPayload(rawPayload)) {\n const outcome = resolveMutationOutcome(rawPayload, {\n defaultErrorMessage: defaultPasskeyErrorMessage,\n mapReason: mapFinishPasskeyLoginReason,\n });\n if (!outcome.ok) {\n const authError: AuthError = {\n message: outcome.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n authPayload = rawPayload.payload ?? null;\n } else {\n authPayload = rawPayload;\n }\n\n if (authPayload == null) {\n const authError: AuthError = {\n message: defaultPasskeyErrorMessage,\n };\n setError(authError);\n reject(authError);\n return;\n }\n\n const status = updateAuthStateFromPayload(authPayload);\n if (status === 'success') {\n resolve(status);\n return;\n }\n const authError: AuthError = {\n message: defaultPasskeyErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n onError: () => {\n setIsLoading(false);\n const authError: AuthError = {\n message: defaultPasskeyErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n });\n } catch (credentialError) {\n setIsLoading(false);\n let message = defaultPasskeyErrorMessage;\n if (\n credentialError instanceof Error &&\n credentialError.message === 'PASSKEY_NO_CREDENTIAL'\n ) {\n message = passkeyNoCredentialMessage;\n } else if (\n typeof DOMException !== 'undefined' &&\n credentialError instanceof DOMException\n ) {\n if (\n credentialError.name === 'AbortError' ||\n credentialError.name === 'NotAllowedError'\n ) {\n message = passkeyCancelledMessage;\n } else if (\n credentialError.name === 'InvalidStateError' ||\n credentialError.name === 'NotSupportedError' ||\n credentialError.name === 'SecurityError'\n ) {\n message = passkeyNotAvailableMessage;\n }\n }\n const authError: AuthError = {\n message,\n };\n setError(authError);\n reject(authError);\n }\n };\n\n continuePasskeyLogin().catch(() => {\n return undefined;\n });\n },\n onError: () => {\n setIsLoading(false);\n const authError: AuthError = {\n message: defaultPasskeyErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n });\n });\n },\n [\n commitBeginPasskeyLoginMutation,\n commitFinishPasskeyLoginMutation,\n defaultPasskeyErrorMessage,\n isMutationPayload,\n mapBeginPasskeyLoginReason,\n mapFinishPasskeyLoginReason,\n passkeyCancelledMessage,\n passkeyNoCredentialMessage,\n passkeyNotAvailableMessage,\n updateAuthStateFromPayload,\n ],\n );\n\n const acceptInvitation = useCallback(\n async (\n credentials: AcceptInvitationCredentials,\n ): Promise<LoginStatus> => {\n if (commitAcceptInvitationMutation == null) {\n const authError: AuthError = {\n message: invitationUnavailableMessage,\n };\n setError(authError);\n return Promise.reject(authError);\n }\n\n setIsLoading(true);\n setError(null);\n\n return new Promise((resolve, reject) => {\n commitAcceptInvitationMutation({\n variables: {\n input: {\n token: credentials.token,\n password: credentials.password,\n passwordConfirmation: credentials.passwordConfirmation,\n },\n },\n onCompleted: (response) => {\n setIsLoading(false);\n const rawPayload = response.acceptInvitation;\n let authPayload: AuthPayload | null = null;\n\n if (isMutationPayload(rawPayload)) {\n const outcome = resolveMutationOutcome(rawPayload, {\n defaultErrorMessage: defaultInvitationErrorMessage,\n mapReason: mapAcceptInvitationReason,\n });\n if (!outcome.ok) {\n const authError: AuthError = {\n message: outcome.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n authPayload = rawPayload.payload ?? null;\n } else {\n authPayload = rawPayload;\n }\n\n if (authPayload == null) {\n const authError: AuthError = {\n message: defaultInvitationErrorMessage,\n };\n setError(authError);\n reject(authError);\n return;\n }\n\n const status = updateAuthStateFromPayload(authPayload);\n if (status === 'success' || status === 'mfa-required') {\n resolve(status);\n return;\n }\n const authError: AuthError = {\n message: defaultInvitationErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n onError: () => {\n setIsLoading(false);\n const authError: AuthError = {\n message: defaultInvitationErrorMessage,\n };\n setError(authError);\n reject(authError);\n },\n });\n });\n },\n [\n commitAcceptInvitationMutation,\n defaultInvitationErrorMessage,\n invitationUnavailableMessage,\n isMutationPayload,\n mapAcceptInvitationReason,\n updateAuthStateFromPayload,\n ],\n );\n\n const logout = useCallback(async (): Promise<void> => {\n setIsLoading(true);\n\n return new Promise((resolve, reject) => {\n commitLogoutMutation({\n variables: {},\n onCompleted: (response) => {\n setIsLoading(false);\n const rawPayload = response.logout;\n let loggedOutValue: boolean | null = null;\n\n if (isMutationPayload(rawPayload)) {\n const outcome = resolveMutationOutcome(rawPayload, {\n defaultErrorMessage: defaultLogoutErrorMessage,\n });\n if (!outcome.ok) {\n const authError: AuthError = { message: outcome.message };\n setError(authError);\n reject(authError);\n return;\n }\n\n const loggedOutResult = requireField(\n rawPayload.payload?.loggedOut ?? null,\n defaultLogoutErrorMessage,\n );\n if (!loggedOutResult.ok) {\n const authError: AuthError = {\n message: loggedOutResult.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n loggedOutValue = loggedOutResult.value;\n } else {\n const loggedOutResult = requireField(\n rawPayload.loggedOut ?? null,\n defaultLogoutErrorMessage,\n );\n if (!loggedOutResult.ok) {\n const authError: AuthError = {\n message: loggedOutResult.message,\n };\n setError(authError);\n reject(authError);\n return;\n }\n loggedOutValue = loggedOutResult.value;\n }\n\n if (!loggedOutValue) {\n const authError: AuthError = {\n message: defaultLogoutErrorMessage,\n };\n setError(authError);\n reject(authError);\n return;\n }\n\n localStorage.removeItem('auth_token');\n localStorage.removeItem('remember_me');\n setUser(null);\n setAuthState(initialState);\n resetRelayStore();\n\n resolve();\n },\n onError: () => {\n setIsLoading(false);\n const authError: AuthError = {\n message: defaultLogoutErrorMessage,\n };\n setError(authError);\n resetRelayStore();\n\n reject(authError);\n },\n });\n });\n }, [commitLogoutMutation, defaultLogoutErrorMessage, isMutationPayload]);\n\n const combinedIsLoading =\n isLoading ||\n mutations.login.isInFlight ||\n mutations.logout.isInFlight ||\n mutations.completeMfa.isInFlight ||\n mutations.beginPasskeyLogin.isInFlight ||\n mutations.finishPasskeyLogin.isInFlight ||\n (mutations.acceptInvitation?.isInFlight ?? false) ||\n mutations.beginAuthentication.isInFlight;\n\n return {\n authMethod: authState.authMethod,\n challengeToken: authState.challengeToken,\n nextStep: authState.nextStep,\n mfaLevel: authState.mfaLevel,\n emailHint: authState.emailHint,\n login,\n loginWithPasskey,\n completeMfa,\n acceptInvitation,\n beginAuthentication,\n logout,\n reset,\n clearError,\n isLoading: combinedIsLoading,\n error,\n user,\n lockedUntil,\n availableMethods,\n };\n };\n};\n"],"mappings":"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"}
|