@plumile/backoffice-react 0.1.98 → 0.1.101
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/AcceptInvitationScreen-B1IPafwD.js.map +1 -1
- package/lib/esm/BackofficeAcceptInvitationPage-CEtApVwL.js.map +1 -1
- package/lib/esm/{BackofficeDashboardPage-YWvoQODn.js → BackofficeDashboardPage-r8vK_JA6.js} +4 -2
- package/lib/esm/BackofficeDashboardPage-r8vK_JA6.js.map +1 -0
- package/lib/esm/BackofficeDetailPayload-P61MDRLE.js.map +1 -1
- package/lib/esm/BackofficeEntityActionFormDialog-BgRTJ_JS.js.map +1 -1
- package/lib/esm/BackofficeEntityDetailLayoutContext-C_tBqkVq.js.map +1 -1
- package/lib/esm/BackofficeEntityDetailLayoutPage-DXjRqvcZ.js.map +1 -1
- package/lib/esm/{BackofficeEntityDetailPage-DPFXbJxC.js → BackofficeEntityDetailPage-CwzKp_Yw.js} +25 -17
- package/lib/esm/BackofficeEntityDetailPage-CwzKp_Yw.js.map +1 -0
- package/lib/esm/BackofficeEntityDetailUnknownPageRedirect-DRWTeox-.js.map +1 -1
- package/lib/esm/{BackofficeEntityListPage-C8Ucmc_E.js → BackofficeEntityListPage-DVT3rrfa.js} +5 -3
- package/lib/esm/BackofficeEntityListPage-DVT3rrfa.js.map +1 -0
- package/lib/esm/BackofficeErrorBoundary-BwRVSDHU.js.map +1 -1
- package/lib/esm/BackofficeLayoutPage-DQ0sVv24.js +609 -0
- package/lib/esm/BackofficeLayoutPage-DQ0sVv24.js.map +1 -0
- package/lib/esm/BackofficeLoginPage-Cc3kcOQV.js.map +1 -1
- package/lib/esm/BackofficePasswordResetCompletePage-CF_0t3Nq.js.map +1 -1
- package/lib/esm/BackofficePasswordResetRequestPage-BJOrQXcy.js.map +1 -1
- package/lib/esm/{BackofficeRightPageLayout-DZQvIHnj.js → BackofficeRightPageLayout-hexJmpam.js} +36 -30
- package/lib/esm/BackofficeRightPageLayout-hexJmpam.js.map +1 -0
- package/lib/esm/BackofficeTopbarPortalContext-iD7dm4_h.js.map +1 -1
- package/lib/esm/BackofficeVerifyEmailPage-C81LlsNM.js.map +1 -1
- package/lib/esm/EntityFilterValue-BWUdPBwp.js.map +1 -1
- package/lib/esm/EntityIdPickerDialog-Yhmr-WsV.js.map +1 -1
- package/lib/esm/{LazyBackofficeEntityActionFormDialog-DVPQyWlr.js → LazyBackofficeEntityActionFormDialog-L8xwaGqH.js} +110 -123
- package/lib/esm/LazyBackofficeEntityActionFormDialog-L8xwaGqH.js.map +1 -0
- package/lib/esm/PasswordResetCompleteScreen-Cgg96DPo.js.map +1 -1
- package/lib/esm/PasswordResetRequestScreen-I1nFvGLd.js.map +1 -1
- package/lib/esm/VerifyEmailScreen-Br5KyHjg.js.map +1 -1
- package/lib/esm/backoffice-react.js +11 -5
- package/lib/esm/backoffice-react.js.map +1 -1
- package/lib/esm/backofficeAuthPaths-BiJvoI5Q.js.map +1 -1
- package/lib/esm/buildBreadcrumbs-CqF9Nh6x.js.map +1 -1
- package/lib/esm/environment-DQfVyWHJ.js.map +1 -1
- package/lib/esm/mutationResult-CcQMY13J.js.map +1 -1
- package/lib/esm/pageResolution-hAQA5C6S.js.map +1 -1
- package/lib/esm/sidebarUtils-DVkLmFbS.js +52 -0
- package/lib/esm/sidebarUtils-DVkLmFbS.js.map +1 -0
- package/lib/esm/synchronizeAuthStatusQuery-BoPKMrP1.js.map +1 -1
- package/lib/esm/toastViewAction-BGTS7vqm.js.map +1 -1
- package/lib/esm/useAuth-CheTnq60.js.map +1 -1
- package/lib/esm/useBackofficeAuth-ers1FUGe.js.map +1 -1
- package/lib/esm/useBackofficeLazyValue-Bh_13h8A.js.map +1 -1
- package/lib/esm/useBackofficeListUrlState-D4fx5O7u.js.map +1 -1
- package/lib/esm/useBackofficeReactTranslation-Btt58EIo.js.map +1 -1
- package/lib/types/components/backoffice/columns/buildDataTableColumns.d.ts.map +1 -1
- package/lib/types/components/backoffice/layout/buildSidebarSections.d.ts +2 -1
- package/lib/types/components/backoffice/layout/buildSidebarSections.d.ts.map +1 -1
- package/lib/types/components/backoffice/layout/sidebarUtils.d.ts +4 -1
- package/lib/types/components/backoffice/layout/sidebarUtils.d.ts.map +1 -1
- package/lib/types/components/backoffice/scaffolds/BackofficeEntityListScaffold.d.ts.map +1 -1
- package/lib/types/hooks/useSidebarGroupCollapse.d.ts +1 -0
- package/lib/types/hooks/useSidebarGroupCollapse.d.ts.map +1 -1
- package/lib/types/i18n/resources.d.ts +2 -0
- package/lib/types/i18n/resources.d.ts.map +1 -1
- package/lib/types/pages/BackofficeDashboardPage.d.ts.map +1 -1
- package/lib/types/pages/BackofficeDashboardPage.helpers.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityDetailPage.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityDetailPage.view-helpers.d.ts +1 -0
- package/lib/types/pages/BackofficeEntityDetailPage.view-helpers.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityListPage.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityListPage.helpers.d.ts.map +1 -1
- package/lib/types/pages/BackofficeLayoutPage.d.ts.map +1 -1
- package/lib/types/provider/types.d.ts +64 -1
- package/lib/types/provider/types.d.ts.map +1 -1
- package/package.json +14 -14
- package/lib/esm/BackofficeDashboardPage-YWvoQODn.js.map +0 -1
- package/lib/esm/BackofficeEntityDetailPage-DPFXbJxC.js.map +0 -1
- package/lib/esm/BackofficeEntityListPage-C8Ucmc_E.js.map +0 -1
- package/lib/esm/BackofficeLayoutPage-CKXS0nDO.js +0 -485
- package/lib/esm/BackofficeLayoutPage-CKXS0nDO.js.map +0 -1
- package/lib/esm/BackofficeRightPageLayout-DZQvIHnj.js.map +0 -1
- package/lib/esm/LazyBackofficeEntityActionFormDialog-DVPQyWlr.js.map +0 -1
- package/lib/esm/sidebarUtils-CuwJ_3mD.js +0 -34
- package/lib/esm/sidebarUtils-CuwJ_3mD.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LazyBackofficeEntityActionFormDialog-L8xwaGqH.js","names":[],"sources":["../../src/hooks/useBackofficeLoadMore.ts","../../src/hooks/useBackofficeListRefetch.ts","../../src/components/backoffice/scaffolds/backofficeEntityListScaffold.css.ts","../../src/components/backoffice/scaffolds/BackofficeEntityListScaffold.tsx","../../src/components/backoffice/actions/LazyBackofficeEntityActionFormDialog.tsx"],"sourcesContent":["import { startTransition, useCallback } from 'react';\n\ntype Params = {\n hasNext: boolean;\n isLoadingNext: boolean;\n loadNext: (count: number) => void;\n count: number;\n};\n\n/**\n * Wraps Relay `loadNext()` with consistent guards and `startTransition()`.\n */\nexport function useBackofficeLoadMore({\n hasNext,\n isLoadingNext,\n loadNext,\n count,\n}: Params): () => void {\n return useCallback(() => {\n if (!hasNext || isLoadingNext) {\n return;\n }\n\n startTransition(() => {\n loadNext(count);\n });\n }, [count, hasNext, isLoadingNext, loadNext]);\n}\n","import { useCallback, useEffect, useRef } from 'react';\nimport type { FetchPolicy } from 'relay-runtime';\n\nimport { stableListVariablesKey } from '@plumile/backoffice-core/state/stableKey.js';\nimport type { BackofficeListVariables } from '@plumile/backoffice-core/types.js';\n\ntype RefetchFn<TVariables> = (\n vars: TVariables,\n opts: { fetchPolicy: FetchPolicy },\n) => void;\n\ntype Params<Where, Sort extends string, Variables> = {\n refetch: RefetchFn<Variables>;\n variables: BackofficeListVariables<Where, Sort>;\n defaults: BackofficeListVariables<Where, Sort>;\n fetchPolicy: FetchPolicy;\n buildVariables?: (input: BackofficeListVariables<Where, Sort>) => Variables;\n};\n\n/**\n * Standardizes refetch behavior for backoffice list components:\n * - Refetches when list URL state changes (where/sort/count), gated by a stable key.\n * - Exposes a manual refresh callback using the same variables.\n *\n * This hook must not call Relay hooks (`useFragment`, `usePaginationFragment`, ...).\n */\nexport function useBackofficeListRefetch<\n Where,\n Sort extends string,\n Variables extends Record<string, unknown>,\n>({\n refetch,\n variables,\n defaults,\n fetchPolicy,\n buildVariables,\n}: Params<Where, Sort, Variables>): { onRefresh: () => void } {\n const lastRefetchKeyRef = useRef<string | null>(\n stableListVariablesKey({\n where: defaults.where,\n sort: defaults.sort,\n count: defaults.count,\n }),\n );\n\n const resolveVariables = useCallback(\n (input: BackofficeListVariables<Where, Sort>) => {\n if (buildVariables != null) {\n return buildVariables(input);\n }\n return input as unknown as Variables;\n },\n [buildVariables],\n );\n\n useEffect(() => {\n const key = stableListVariablesKey({\n where: variables.where,\n sort: variables.sort,\n count: variables.count,\n });\n if (lastRefetchKeyRef.current === key) {\n return;\n }\n lastRefetchKeyRef.current = key;\n\n const nextVariables = resolveVariables({ ...variables, cursor: null });\n refetch(nextVariables, { fetchPolicy });\n }, [fetchPolicy, refetch, resolveVariables, variables]);\n\n const onRefresh = useCallback(() => {\n const nextVariables = resolveVariables({ ...variables, cursor: null });\n refetch(nextVariables, { fetchPolicy });\n }, [fetchPolicy, refetch, resolveVariables, variables]);\n\n return { onRefresh };\n}\n","import { sprinkles } from '@plumile/ui';\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: 72,\n maxWidth: 'full',\n});\n\nexport const embeddedContainer = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 3,\n});\n\nexport const embeddedHeader = sprinkles({\n fontSize: 'base',\n fontWeight: 'semibold',\n color: 'text',\n});\n","/* eslint-disable no-ternary */\nimport {\n type JSX,\n type ReactNode,\n useCallback,\n useMemo,\n useState,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport {\n BackofficeEmptyState,\n BackofficeFilterDrawer,\n BackofficeFilterField,\n BackofficeLoadMore,\n BackofficePageHeader,\n BackofficeTableSkeleton,\n BackofficeTableToolbar,\n Button,\n FilterChipRow,\n GlobalSearchInput,\n InlineBanner,\n ListPageTemplate,\n ResponsiveRecordList,\n SimpleSelect,\n type FilterChip,\n type DataTableColumn,\n type GetRowId,\n denseTableClass,\n} from '@plumile/ui';\n\nimport {\n readWhereValue,\n setWhereValue,\n} from '@plumile/backoffice-core/filters/where.js';\nimport type {\n BackofficeFilterSpec,\n BackofficeListState,\n BackofficePickerScope,\n BackofficeResolvedListFacetConfig,\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 { BackofficeListFilterProvider } from './BackofficeListFilterContext.js';\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.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\ntype Props<\n RowView,\n Where extends Record<string, unknown>,\n Sort extends string,\n> = {\n config: BackofficeResolvedListFacetConfig<Where, Sort>;\n state: BackofficeListState<Where, Sort>;\n pushState: (next: BackofficeListState<Where, Sort>) => 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 onLoadMore: () => void;\n onRefresh?: () => void;\n totalCount?: number | null;\n emptyState?: JSX.Element;\n isLoadingInitial?: boolean;\n virtualize?: boolean;\n variant?: 'page' | 'embedded';\n showFilters?: boolean;\n};\n\nexport const BackofficeEntityListScaffold = <\n RowView,\n Where extends Record<string, unknown>,\n Sort extends string,\n>(\n props: Props<RowView, Where, Sort>,\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 onLoadMore,\n onRefresh,\n totalCount,\n emptyState,\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) as keyof Where;\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 Where;\n label: string;\n path?: readonly string[];\n scope?: BackofficePickerScope;\n } | null>(null);\n\n const renderFilterControl = useCallback(\n (filter: BackofficeFilterSpec<Where>): JSX.Element => {\n const key = (filter.whereKey ?? filter.id) as keyof Where;\n const candidate = getFilterValue(filter, state.where);\n let value = '';\n if (typeof candidate === 'string') {\n value = 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 <GlobalSearchInput\n value={value}\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 placeholder={placeholder}\n className={styles.filterInput}\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 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 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 = (displayValue: string | null = null) => {\n const normalizedDisplayValue = displayValue?.trim() ?? '';\n return (\n <EntityIdFilterField\n label={filterLabelText}\n value={currentId}\n displayValue={normalizedDisplayValue}\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) => {\n return renderField(label);\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 if (hasPlacementConfig) {\n return listConfig.filters.filter((filter) => {\n return filter.placement === 'quick' || filter.placement === 'both';\n });\n }\n return listConfig.filters.slice(0, 3);\n }, [listConfig.filters, 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 onChange={(next) => {\n pushState({\n ...state,\n sort: next as Sort,\n });\n }}\n />\n );\n }, [listConfig.sorts, pushState, state, tApp]);\n\n const chipsNode = useMemo(() => {\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.allFilters');\n if (activeCount > 0) {\n label = t('filters.allFiltersWithCount', {\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 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 />\n );\n\n const resolvedEmptyState = useMemo((): JSX.Element => {\n if (emptyState != null) {\n return emptyState;\n }\n\n if (isLoadingInitial) {\n return <BackofficeTableSkeleton />;\n }\n\n if (chips.length > 0) {\n return (\n <BackofficeEmptyState\n title={t('emptyState.listEmpty.title')}\n description={t('emptyState.listEmptyFiltered.description')}\n actions={\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={handleClearAll}\n >\n {t('emptyState.listEmptyFiltered.actions.reset')}\n </Button>\n }\n />\n );\n }\n\n return (\n <BackofficeEmptyState\n title={t('emptyState.listEmpty.title')}\n description={t('emptyState.listEmpty.description')}\n />\n );\n }, [chips.length, emptyState, handleClearAll, isLoadingInitial, t]);\n\n const tableFooterMeta = useMemo(() => {\n if (typeof totalCount !== 'number') {\n return null;\n }\n return (\n <span>\n {t('list.showing', {\n shown: rows.length,\n total: totalCount,\n })}\n </span>\n );\n }, [rows.length, t, totalCount]);\n\n const 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 = listConfig.responsive?.mode ?? 'auto';\n const listDensity = listConfig.responsive?.density ?? 'compact';\n\n const tableInnerNode = (\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 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 <BackofficeTableToolbar\n searchSlot={searchNode}\n filtersSlot={\n <>\n {quickFiltersNode}\n {allFiltersNode}\n </>\n }\n sortSlot={sortNode}\n refreshSlot={\n <Button\n type=\"button\"\n variant=\"text\"\n size=\"small\"\n disabled={onRefresh == null}\n onClick={() => {\n if (onRefresh != null) {\n onRefresh();\n }\n }}\n >\n {t('list.actions.refresh')}\n </Button>\n }\n chipsSlot={chipsNode}\n />\n {filterDrawerNode}\n </>\n ) : null;\n\n const tableNode = (\n <div>\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 tableFooterNode = (\n <BackofficeLoadMore\n hasNextPage={hasNextPage}\n isLoading={isLoadingMore}\n meta={tableFooterMeta}\n loadMoreLabel={t('list.loadMore.more')}\n endLabel={t('list.loadMore.end')}\n loadingLabel={t('list.loadMore.loading')}\n onLoadMore={onLoadMore}\n />\n );\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 {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 tableNode={tableNode}\n tableFooterNode={tableFooterNode}\n />\n </BackofficeListFilterProvider>\n );\n};\n\nexport default BackofficeEntityListScaffold;\n","import { Suspense, lazy, type JSX } from 'react';\n\nimport type { BackofficeEntityActionFormDialogProps } from './BackofficeEntityActionFormDialog.js';\n\nconst BackofficeEntityActionFormDialog = lazy(async () => {\n const module = await import('./BackofficeEntityActionFormDialog.js');\n return { default: module.BackofficeEntityActionFormDialog };\n});\n\nexport const LazyBackofficeEntityActionFormDialog = <Node,>(\n props: BackofficeEntityActionFormDialogProps<Node>,\n): JSX.Element => {\n const Dialog = BackofficeEntityActionFormDialog as <TNode>(\n dialogProps: BackofficeEntityActionFormDialogProps<TNode>,\n ) => JSX.Element;\n\n return (\n <Suspense fallback={null}>\n <Dialog {...props} />\n </Suspense>\n );\n};\n\nexport default LazyBackofficeEntityActionFormDialog;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PasswordResetCompleteScreen-Cgg96DPo.js","names":[],"sources":["../../src/auth/pages/PasswordResetCompleteScreen.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { AuthLayout, Button, FormError, FormField } from '@plumile/ui';\n\nimport * as styles from '../login/loginPage.css.js';\nimport AuthPanel from '../login/AuthPanel.js';\n\nconst MIN_PASSWORD_LENGTH = 8;\n\ntype Props = {\n onBackToLogin: () => void;\n onCompletePasswordReset: (input: {\n newPassword: string;\n token: string;\n }) => Promise<boolean>;\n token?: string;\n};\n\nexport const PasswordResetCompleteScreen = ({\n onBackToLogin,\n onCompletePasswordReset,\n token,\n}: Props): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const [password, setPassword] = useState('');\n const [passwordConfirm, setPasswordConfirm] = useState('');\n const [status, setStatus] = useState<'idle' | 'completed'>('idle');\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const resolvedToken = useMemo(() => {\n if (token != null) {\n return token;\n }\n if (typeof window === 'undefined') {\n return '';\n }\n const params = new URLSearchParams(window.location.search);\n return params.get('token') ?? '';\n }, [token]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setError(null);\n\n if (resolvedToken === '') {\n setError(t('auth.passwordResetComplete.errors.missingToken'));\n return;\n }\n\n if (password.length < MIN_PASSWORD_LENGTH) {\n setError(\n t('auth.passwordResetComplete.errors.minLength', {\n minLength: MIN_PASSWORD_LENGTH,\n }),\n );\n return;\n }\n\n if (password !== passwordConfirm) {\n setError(t('auth.passwordResetComplete.errors.mismatch'));\n return;\n }\n\n setIsSubmitting(true);\n\n const completePasswordReset = async (): Promise<void> => {\n try {\n const success = await onCompletePasswordReset({\n newPassword: password,\n token: resolvedToken,\n });\n if (success) {\n setStatus('completed');\n } else {\n setError(t('auth.passwordResetComplete.errors.invalid'));\n }\n } catch (mutationError) {\n setError(\n mutationError instanceof Error\n ? mutationError.message\n : t('auth.passwordResetComplete.errors.invalid'),\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n completePasswordReset().catch(() => {\n return undefined;\n });\n },\n [onCompletePasswordReset, password, passwordConfirm, resolvedToken, t],\n );\n\n let content: JSX.Element;\n if (status === 'completed') {\n content = (\n <AuthPanel\n title={t('auth.passwordResetComplete.success.title')}\n description={t('auth.passwordResetComplete.success.description')}\n footer={\n <Button\n type=\"button\"\n variant=\"secondary\"\n className={styles.brandGhostButton}\n onClick={onBackToLogin}\n >\n {t('auth.passwordResetComplete.success.action')}\n </Button>\n }\n >\n <p className={styles.helper}>\n {t('auth.passwordResetComplete.success.helper')}\n </p>\n </AuthPanel>\n );\n } else {\n content = (\n <AuthPanel\n title={t('auth.passwordResetComplete.form.title')}\n description={t('auth.passwordResetComplete.form.description')}\n >\n <form className={styles.formSurface} onSubmit={handleSubmit} noValidate>\n {error != null ? <FormError>{error}</FormError> : null}\n <FormField\n label={t('auth.passwordResetComplete.form.passwordLabel')}\n name=\"new-password\"\n type=\"password\"\n value={password}\n onChange={(event) => {\n setPassword(event.target.value);\n setError(null);\n }}\n placeholder={t(\n 'auth.passwordResetComplete.form.passwordPlaceholder',\n )}\n autoComplete=\"new-password\"\n required\n />\n <FormField\n label={t('auth.passwordResetComplete.form.confirmLabel')}\n name=\"confirm-password\"\n type=\"password\"\n value={passwordConfirm}\n onChange={(event) => {\n setPasswordConfirm(event.target.value);\n setError(null);\n }}\n placeholder={t(\n 'auth.passwordResetComplete.form.confirmPlaceholder',\n )}\n autoComplete=\"new-password\"\n required\n />\n <Button type=\"submit\" isLoading={isSubmitting}>\n {t('auth.passwordResetComplete.form.submit')}\n </Button>\n </form>\n </AuthPanel>\n );\n }\n\n return (\n <AuthLayout\n title={t('auth.passwordResetComplete.title')}\n subtitle={t('auth.passwordResetComplete.subtitle')}\n >\n {content}\n </AuthLayout>\n );\n};\n"],"mappings":";;;;;;;AAeA,IAAM,IAAsB,GAWf,KAA+B,EAC1C,kBACA,4BACA,eACwB;CACxB,IAAM,EAAE,SAAM,GAA+B,EACvC,CAAC,GAAU,KAAe,EAAS,GAAG,EACtC,CAAC,GAAiB,KAAsB,EAAS,GAAG,EACpD,CAAC,GAAQ,KAAa,EAA+B,OAAO,EAC5D,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,CAAC,GAAc,KAAmB,EAAS,GAAM,EAEjD,IAAgB,QAChB,MAGA,OAAO,SAAW,MACb,KAGF,IADY,gBAAgB,OAAO,SAAS,OAC5C,CAAO,IAAI,QAAQ,IAAI,KAC7B,CAAC,EAAM,CAAC,EAEL,IAAe,GAClB,MAAsC;
|
|
1
|
+
{"version":3,"file":"PasswordResetCompleteScreen-Cgg96DPo.js","names":[],"sources":["../../src/auth/pages/PasswordResetCompleteScreen.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { AuthLayout, Button, FormError, FormField } from '@plumile/ui';\n\nimport * as styles from '../login/loginPage.css.js';\nimport AuthPanel from '../login/AuthPanel.js';\n\nconst MIN_PASSWORD_LENGTH = 8;\n\ntype Props = {\n onBackToLogin: () => void;\n onCompletePasswordReset: (input: {\n newPassword: string;\n token: string;\n }) => Promise<boolean>;\n token?: string;\n};\n\nexport const PasswordResetCompleteScreen = ({\n onBackToLogin,\n onCompletePasswordReset,\n token,\n}: Props): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const [password, setPassword] = useState('');\n const [passwordConfirm, setPasswordConfirm] = useState('');\n const [status, setStatus] = useState<'idle' | 'completed'>('idle');\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const resolvedToken = useMemo(() => {\n if (token != null) {\n return token;\n }\n if (typeof window === 'undefined') {\n return '';\n }\n const params = new URLSearchParams(window.location.search);\n return params.get('token') ?? '';\n }, [token]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setError(null);\n\n if (resolvedToken === '') {\n setError(t('auth.passwordResetComplete.errors.missingToken'));\n return;\n }\n\n if (password.length < MIN_PASSWORD_LENGTH) {\n setError(\n t('auth.passwordResetComplete.errors.minLength', {\n minLength: MIN_PASSWORD_LENGTH,\n }),\n );\n return;\n }\n\n if (password !== passwordConfirm) {\n setError(t('auth.passwordResetComplete.errors.mismatch'));\n return;\n }\n\n setIsSubmitting(true);\n\n const completePasswordReset = async (): Promise<void> => {\n try {\n const success = await onCompletePasswordReset({\n newPassword: password,\n token: resolvedToken,\n });\n if (success) {\n setStatus('completed');\n } else {\n setError(t('auth.passwordResetComplete.errors.invalid'));\n }\n } catch (mutationError) {\n setError(\n mutationError instanceof Error\n ? mutationError.message\n : t('auth.passwordResetComplete.errors.invalid'),\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n completePasswordReset().catch(() => {\n return undefined;\n });\n },\n [onCompletePasswordReset, password, passwordConfirm, resolvedToken, t],\n );\n\n let content: JSX.Element;\n if (status === 'completed') {\n content = (\n <AuthPanel\n title={t('auth.passwordResetComplete.success.title')}\n description={t('auth.passwordResetComplete.success.description')}\n footer={\n <Button\n type=\"button\"\n variant=\"secondary\"\n className={styles.brandGhostButton}\n onClick={onBackToLogin}\n >\n {t('auth.passwordResetComplete.success.action')}\n </Button>\n }\n >\n <p className={styles.helper}>\n {t('auth.passwordResetComplete.success.helper')}\n </p>\n </AuthPanel>\n );\n } else {\n content = (\n <AuthPanel\n title={t('auth.passwordResetComplete.form.title')}\n description={t('auth.passwordResetComplete.form.description')}\n >\n <form className={styles.formSurface} onSubmit={handleSubmit} noValidate>\n {error != null ? <FormError>{error}</FormError> : null}\n <FormField\n label={t('auth.passwordResetComplete.form.passwordLabel')}\n name=\"new-password\"\n type=\"password\"\n value={password}\n onChange={(event) => {\n setPassword(event.target.value);\n setError(null);\n }}\n placeholder={t(\n 'auth.passwordResetComplete.form.passwordPlaceholder',\n )}\n autoComplete=\"new-password\"\n required\n />\n <FormField\n label={t('auth.passwordResetComplete.form.confirmLabel')}\n name=\"confirm-password\"\n type=\"password\"\n value={passwordConfirm}\n onChange={(event) => {\n setPasswordConfirm(event.target.value);\n setError(null);\n }}\n placeholder={t(\n 'auth.passwordResetComplete.form.confirmPlaceholder',\n )}\n autoComplete=\"new-password\"\n required\n />\n <Button type=\"submit\" isLoading={isSubmitting}>\n {t('auth.passwordResetComplete.form.submit')}\n </Button>\n </form>\n </AuthPanel>\n );\n }\n\n return (\n <AuthLayout\n title={t('auth.passwordResetComplete.title')}\n subtitle={t('auth.passwordResetComplete.subtitle')}\n >\n {content}\n </AuthLayout>\n );\n};\n"],"mappings":";;;;;;;AAeA,IAAM,IAAsB,GAWf,KAA+B,EAC1C,kBACA,4BACA,eACwB;CACxB,IAAM,EAAE,SAAM,GAA+B,EACvC,CAAC,GAAU,KAAe,EAAS,GAAG,EACtC,CAAC,GAAiB,KAAsB,EAAS,GAAG,EACpD,CAAC,GAAQ,KAAa,EAA+B,OAAO,EAC5D,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,CAAC,GAAc,KAAmB,EAAS,GAAM,EAEjD,IAAgB,QAChB,MAGA,OAAO,SAAW,MACb,KAGF,IADY,gBAAgB,OAAO,SAAS,OAC5C,CAAO,IAAI,QAAQ,IAAI,KAC7B,CAAC,EAAM,CAAC,EAEL,IAAe,GAClB,MAAsC;EAIrC,IAHA,EAAM,gBAAgB,EACtB,EAAS,KAAK,EAEV,MAAkB,IAAI;GACxB,EAAS,EAAE,iDAAiD,CAAC;GAC7D;;EAGF,IAAI,EAAS,SAAS,GAAqB;GACzC,EACE,EAAE,+CAA+C,EAC/C,WAAW,GACZ,CAAC,CACH;GACD;;EAGF,IAAI,MAAa,GAAiB;GAChC,EAAS,EAAE,6CAA6C,CAAC;GACzD;;EA2BF,AAxBA,EAAgB,GAAK,GAwBrB,YAtByD;GACvD,IAAI;IAKF,AAAI,MAJkB,EAAwB;KAC5C,aAAa;KACb,OAAO;KACR,CAAC,GAEA,EAAU,YAAY,GAEtB,EAAS,EAAE,4CAA4C,CAAC;YAEnD,GAAe;IACtB,EACE,aAAyB,QACrB,EAAc,UACd,EAAE,4CAA4C,CACnD;aACO;IACR,EAAgB,GAAM;;MAIH,CAAC,YAAY,GAElC;IAEJ;EAAC;EAAyB;EAAU;EAAiB;EAAe;EAAE,CACvE,EAEG;CAoEJ,OAnEA,AAsBE,IAtBE,MAAW,cAEX,kBAAC,GAAD;EACE,OAAO,EAAE,2CAA2C;EACpD,aAAa,EAAE,iDAAiD;EAChE,QACE,kBAAC,GAAD;GACE,MAAK;GACL,SAAQ;GACR,WAAW;GACX,SAAS;aAER,EAAE,4CAA4C;GACxC,CAAA;YAGX,kBAAC,KAAD;GAAG,WAAW;aACX,EAAE,4CAA4C;GAC7C,CAAA;EACM,CAAA,GAIZ,kBAAC,GAAD;EACE,OAAO,EAAE,wCAAwC;EACjD,aAAa,EAAE,8CAA8C;YAE7D,kBAAC,QAAD;GAAM,WAAW;GAAoB,UAAU;GAAc,YAAA;aAA7D;IACG,KAAS,OAAwC,OAAjC,kBAAC,GAAD,EAAA,UAAY,GAAkB,CAAA;IAC/C,kBAAC,GAAD;KACE,OAAO,EAAE,gDAAgD;KACzD,MAAK;KACL,MAAK;KACL,OAAO;KACP,WAAW,MAAU;MAEnB,AADA,EAAY,EAAM,OAAO,MAAM,EAC/B,EAAS,KAAK;;KAEhB,aAAa,EACX,sDACD;KACD,cAAa;KACb,UAAA;KACA,CAAA;IACF,kBAAC,GAAD;KACE,OAAO,EAAE,+CAA+C;KACxD,MAAK;KACL,MAAK;KACL,OAAO;KACP,WAAW,MAAU;MAEnB,AADA,EAAmB,EAAM,OAAO,MAAM,EACtC,EAAS,KAAK;;KAEhB,aAAa,EACX,qDACD;KACD,cAAa;KACb,UAAA;KACA,CAAA;IACF,kBAAC,GAAD;KAAQ,MAAK;KAAS,WAAW;eAC9B,EAAE,yCAAyC;KACrC,CAAA;IACJ;;EACG,CAAA,EAKd,kBAAC,GAAD;EACE,OAAO,EAAE,mCAAmC;EAC5C,UAAU,EAAE,sCAAsC;YAEjD;EACU,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PasswordResetRequestScreen-I1nFvGLd.js","names":[],"sources":["../../src/auth/pages/PasswordResetRequestScreen.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { AuthLayout, Button, FormError, FormField } from '@plumile/ui';\n\nimport * as styles from '../login/loginPage.css.js';\nimport AuthPanel from '../login/AuthPanel.js';\n\ntype Props = {\n onStartPasswordReset: (input: {\n email: string;\n locale?: string;\n }) => Promise<boolean>;\n};\n\nexport const PasswordResetRequestScreen = ({\n onStartPasswordReset,\n}: Props): JSX.Element => {\n const { i18n, t } = useBackofficeReactTranslation();\n const [email, setEmail] = useState('');\n const [status, setStatus] = useState<'idle' | 'sent'>('idle');\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const locale = useMemo(() => {\n const language = i18n.language.trim();\n if (language !== '') {\n return language;\n }\n if (typeof navigator === 'undefined') {\n return undefined;\n }\n return navigator.language;\n }, [i18n.language]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setError(null);\n\n if (email.trim() === '') {\n setError(t('auth.passwordResetRequest.errors.emailRequired'));\n return;\n }\n\n setIsSubmitting(true);\n onStartPasswordReset({\n email: email.trim(),\n locale,\n })\n .then((success) => {\n if (success) {\n setStatus('sent');\n } else {\n setError(t('auth.passwordResetRequest.errors.startFailed'));\n }\n })\n .catch((mutationError) => {\n setError(\n mutationError instanceof Error\n ? mutationError.message\n : t('auth.passwordResetRequest.errors.startFailed'),\n );\n })\n .finally(() => {\n setIsSubmitting(false);\n });\n },\n [email, locale, onStartPasswordReset, t],\n );\n\n let content: JSX.Element;\n if (status === 'sent') {\n content = (\n <AuthPanel\n title={t('auth.passwordResetRequest.sent.title')}\n description={t('auth.passwordResetRequest.sent.description', { email })}\n footer={\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n setStatus('idle');\n }}\n >\n {t('auth.passwordResetRequest.sent.action')}\n </Button>\n }\n >\n <p className={styles.helper}>\n {t('auth.passwordResetRequest.sent.helper')}\n </p>\n </AuthPanel>\n );\n } else {\n content = (\n <AuthPanel description={t('auth.passwordResetRequest.form.description')}>\n <form className={styles.formSurface} onSubmit={handleSubmit} noValidate>\n {error != null ? <FormError>{error}</FormError> : null}\n <FormField\n label={t('auth.passwordResetRequest.form.emailLabel')}\n name=\"email\"\n type=\"email\"\n value={email}\n onChange={(event) => {\n setEmail(event.target.value);\n setError(null);\n }}\n placeholder={t('auth.passwordResetRequest.form.emailPlaceholder')}\n autoComplete=\"email\"\n autoFocus\n required\n />\n <Button type=\"submit\" isLoading={isSubmitting}>\n {t('auth.passwordResetRequest.form.submit')}\n </Button>\n </form>\n </AuthPanel>\n );\n }\n\n return (\n <AuthLayout title={t('auth.passwordResetRequest.title')}>\n {content}\n </AuthLayout>\n );\n};\n"],"mappings":";;;;;;;AAsBA,IAAa,KAA8B,EACzC,8BACwB;CACxB,IAAM,EAAE,SAAM,SAAM,GAA+B,EAC7C,CAAC,GAAO,KAAY,EAAS,GAAG,EAChC,CAAC,GAAQ,KAAa,EAA0B,OAAO,EACvD,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,CAAC,GAAc,KAAmB,EAAS,GAAM,EAEjD,IAAS,QAAc;EAC3B,IAAM,IAAW,EAAK,SAAS,MAAM;
|
|
1
|
+
{"version":3,"file":"PasswordResetRequestScreen-I1nFvGLd.js","names":[],"sources":["../../src/auth/pages/PasswordResetRequestScreen.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { AuthLayout, Button, FormError, FormField } from '@plumile/ui';\n\nimport * as styles from '../login/loginPage.css.js';\nimport AuthPanel from '../login/AuthPanel.js';\n\ntype Props = {\n onStartPasswordReset: (input: {\n email: string;\n locale?: string;\n }) => Promise<boolean>;\n};\n\nexport const PasswordResetRequestScreen = ({\n onStartPasswordReset,\n}: Props): JSX.Element => {\n const { i18n, t } = useBackofficeReactTranslation();\n const [email, setEmail] = useState('');\n const [status, setStatus] = useState<'idle' | 'sent'>('idle');\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const locale = useMemo(() => {\n const language = i18n.language.trim();\n if (language !== '') {\n return language;\n }\n if (typeof navigator === 'undefined') {\n return undefined;\n }\n return navigator.language;\n }, [i18n.language]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setError(null);\n\n if (email.trim() === '') {\n setError(t('auth.passwordResetRequest.errors.emailRequired'));\n return;\n }\n\n setIsSubmitting(true);\n onStartPasswordReset({\n email: email.trim(),\n locale,\n })\n .then((success) => {\n if (success) {\n setStatus('sent');\n } else {\n setError(t('auth.passwordResetRequest.errors.startFailed'));\n }\n })\n .catch((mutationError) => {\n setError(\n mutationError instanceof Error\n ? mutationError.message\n : t('auth.passwordResetRequest.errors.startFailed'),\n );\n })\n .finally(() => {\n setIsSubmitting(false);\n });\n },\n [email, locale, onStartPasswordReset, t],\n );\n\n let content: JSX.Element;\n if (status === 'sent') {\n content = (\n <AuthPanel\n title={t('auth.passwordResetRequest.sent.title')}\n description={t('auth.passwordResetRequest.sent.description', { email })}\n footer={\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n setStatus('idle');\n }}\n >\n {t('auth.passwordResetRequest.sent.action')}\n </Button>\n }\n >\n <p className={styles.helper}>\n {t('auth.passwordResetRequest.sent.helper')}\n </p>\n </AuthPanel>\n );\n } else {\n content = (\n <AuthPanel description={t('auth.passwordResetRequest.form.description')}>\n <form className={styles.formSurface} onSubmit={handleSubmit} noValidate>\n {error != null ? <FormError>{error}</FormError> : null}\n <FormField\n label={t('auth.passwordResetRequest.form.emailLabel')}\n name=\"email\"\n type=\"email\"\n value={email}\n onChange={(event) => {\n setEmail(event.target.value);\n setError(null);\n }}\n placeholder={t('auth.passwordResetRequest.form.emailPlaceholder')}\n autoComplete=\"email\"\n autoFocus\n required\n />\n <Button type=\"submit\" isLoading={isSubmitting}>\n {t('auth.passwordResetRequest.form.submit')}\n </Button>\n </form>\n </AuthPanel>\n );\n }\n\n return (\n <AuthLayout title={t('auth.passwordResetRequest.title')}>\n {content}\n </AuthLayout>\n );\n};\n"],"mappings":";;;;;;;AAsBA,IAAa,KAA8B,EACzC,8BACwB;CACxB,IAAM,EAAE,SAAM,SAAM,GAA+B,EAC7C,CAAC,GAAO,KAAY,EAAS,GAAG,EAChC,CAAC,GAAQ,KAAa,EAA0B,OAAO,EACvD,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,CAAC,GAAc,KAAmB,EAAS,GAAM,EAEjD,IAAS,QAAc;EAC3B,IAAM,IAAW,EAAK,SAAS,MAAM;EACrC,IAAI,MAAa,IACf,OAAO;EAEL,aAAO,YAAc,MAGzB,OAAO,UAAU;IAChB,CAAC,EAAK,SAAS,CAAC,EAEb,IAAe,GAClB,MAAsC;EAIrC,IAHA,EAAM,gBAAgB,EACtB,EAAS,KAAK,EAEV,EAAM,MAAM,KAAK,IAAI;GACvB,EAAS,EAAE,iDAAiD,CAAC;GAC7D;;EAIF,AADA,EAAgB,GAAK,EACrB,EAAqB;GACnB,OAAO,EAAM,MAAM;GACnB;GACD,CAAC,CACC,MAAM,MAAY;GACjB,AAAI,IACF,EAAU,OAAO,GAEjB,EAAS,EAAE,+CAA+C,CAAC;IAE7D,CACD,OAAO,MAAkB;GACxB,EACE,aAAyB,QACrB,EAAc,UACd,EAAE,+CAA+C,CACtD;IACD,CACD,cAAc;GACb,EAAgB,GAAM;IACtB;IAEN;EAAC;EAAO;EAAQ;EAAsB;EAAE,CACzC,EAEG;CAkDJ,OAjDA,AAuBE,IAvBE,MAAW,SAEX,kBAAC,GAAD;EACE,OAAO,EAAE,uCAAuC;EAChD,aAAa,EAAE,8CAA8C,EAAE,UAAO,CAAC;EACvE,QACE,kBAAC,GAAD;GACE,MAAK;GACL,SAAQ;GACR,eAAe;IACb,EAAU,OAAO;;aAGlB,EAAE,wCAAwC;GACpC,CAAA;YAGX,kBAAC,KAAD;GAAG,WAAW;aACX,EAAE,wCAAwC;GACzC,CAAA;EACM,CAAA,GAIZ,kBAAC,GAAD;EAAW,aAAa,EAAE,6CAA6C;YACrE,kBAAC,QAAD;GAAM,WAAW;GAAoB,UAAU;GAAc,YAAA;aAA7D;IACG,KAAS,OAAwC,OAAjC,kBAAC,GAAD,EAAA,UAAY,GAAkB,CAAA;IAC/C,kBAAC,GAAD;KACE,OAAO,EAAE,4CAA4C;KACrD,MAAK;KACL,MAAK;KACL,OAAO;KACP,WAAW,MAAU;MAEnB,AADA,EAAS,EAAM,OAAO,MAAM,EAC5B,EAAS,KAAK;;KAEhB,aAAa,EAAE,kDAAkD;KACjE,cAAa;KACb,WAAA;KACA,UAAA;KACA,CAAA;IACF,kBAAC,GAAD;KAAQ,MAAK;KAAS,WAAW;eAC9B,EAAE,wCAAwC;KACpC,CAAA;IACJ;;EACG,CAAA,EAKd,kBAAC,GAAD;EAAY,OAAO,EAAE,kCAAkC;YACpD;EACU,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VerifyEmailScreen-Br5KyHjg.js","names":[],"sources":["../../src/auth/pages/VerifyEmailScreen.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport { useEffect, useMemo, useState, type JSX } from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { AuthLayout, Button, FormError } from '@plumile/ui';\n\nimport * as styles from '../login/loginPage.css.js';\n\ntype VerificationState = 'pending' | 'success' | 'error';\n\ntype Props = {\n onBackToLogin: () => void;\n onVerifyEmail: (input: { token: string }) => Promise<boolean>;\n token?: string;\n};\n\nexport const VerifyEmailScreen = ({\n onBackToLogin,\n onVerifyEmail,\n token,\n}: Props): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const [state, setState] = useState<VerificationState>('pending');\n const [error, setError] = useState<string | null>(null);\n\n const resolvedToken = useMemo(() => {\n if (token != null) {\n return token;\n }\n if (typeof window === 'undefined') {\n return '';\n }\n const params = new URLSearchParams(window.location.search);\n return params.get('token') ?? '';\n }, [token]);\n\n useEffect(() => {\n if (resolvedToken === '') {\n setState('error');\n setError(t('auth.verifyEmail.errors.missingToken'));\n return;\n }\n\n const verifyEmail = async (): Promise<void> => {\n try {\n const success = await onVerifyEmail({ token: resolvedToken });\n if (success) {\n setState('success');\n } else {\n setState('error');\n setError(t('auth.verifyEmail.errors.invalid'));\n }\n } catch (mutationError) {\n setState('error');\n setError(\n mutationError instanceof Error\n ? mutationError.message\n : t('auth.verifyEmail.errors.invalid'),\n );\n }\n };\n\n verifyEmail().catch(() => {\n return undefined;\n });\n }, [onVerifyEmail, resolvedToken, t]);\n\n let content: JSX.Element;\n if (state === 'success') {\n content = (\n <div className={styles.stack}>\n <p className={styles.helper}>{t('auth.verifyEmail.status.success')}</p>\n <Button type=\"button\" variant=\"secondary\" onClick={onBackToLogin}>\n {t('auth.verifyEmail.actions.continue')}\n </Button>\n </div>\n );\n } else if (state === 'error') {\n content = (\n <div className={styles.stack}>\n {error != null ? <FormError>{error}</FormError> : null}\n <Button type=\"button\" variant=\"secondary\" onClick={onBackToLogin}>\n {t('auth.verifyEmail.actions.return')}\n </Button>\n </div>\n );\n } else {\n content = (\n <div className={styles.stack}>\n <p className={styles.helper}>\n {t('auth.verifyEmail.status.verifying')}\n </p>\n <Button type=\"button\" isLoading>\n {t('auth.verifyEmail.status.verifyingButton')}\n </Button>\n </div>\n );\n }\n\n return (\n <AuthLayout\n title={t('auth.verifyEmail.title')}\n subtitle={t('auth.verifyEmail.subtitle')}\n >\n {content}\n </AuthLayout>\n );\n};\n"],"mappings":";;;;;;AAgBA,IAAa,KAAqB,EAChC,kBACA,kBACA,eACwB;CACxB,IAAM,EAAE,SAAM,GAA+B,EACvC,CAAC,GAAO,KAAY,EAA4B,UAAU,EAC1D,CAAC,GAAO,KAAY,EAAwB,KAAK,EAEjD,IAAgB,QAChB,MAGA,OAAO,SAAW,MACb,KAGF,IADY,gBAAgB,OAAO,SAAS,OAC5C,CAAO,IAAI,QAAQ,IAAI,KAC7B,CAAC,EAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"VerifyEmailScreen-Br5KyHjg.js","names":[],"sources":["../../src/auth/pages/VerifyEmailScreen.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport { useEffect, useMemo, useState, type JSX } from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { AuthLayout, Button, FormError } from '@plumile/ui';\n\nimport * as styles from '../login/loginPage.css.js';\n\ntype VerificationState = 'pending' | 'success' | 'error';\n\ntype Props = {\n onBackToLogin: () => void;\n onVerifyEmail: (input: { token: string }) => Promise<boolean>;\n token?: string;\n};\n\nexport const VerifyEmailScreen = ({\n onBackToLogin,\n onVerifyEmail,\n token,\n}: Props): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const [state, setState] = useState<VerificationState>('pending');\n const [error, setError] = useState<string | null>(null);\n\n const resolvedToken = useMemo(() => {\n if (token != null) {\n return token;\n }\n if (typeof window === 'undefined') {\n return '';\n }\n const params = new URLSearchParams(window.location.search);\n return params.get('token') ?? '';\n }, [token]);\n\n useEffect(() => {\n if (resolvedToken === '') {\n setState('error');\n setError(t('auth.verifyEmail.errors.missingToken'));\n return;\n }\n\n const verifyEmail = async (): Promise<void> => {\n try {\n const success = await onVerifyEmail({ token: resolvedToken });\n if (success) {\n setState('success');\n } else {\n setState('error');\n setError(t('auth.verifyEmail.errors.invalid'));\n }\n } catch (mutationError) {\n setState('error');\n setError(\n mutationError instanceof Error\n ? mutationError.message\n : t('auth.verifyEmail.errors.invalid'),\n );\n }\n };\n\n verifyEmail().catch(() => {\n return undefined;\n });\n }, [onVerifyEmail, resolvedToken, t]);\n\n let content: JSX.Element;\n if (state === 'success') {\n content = (\n <div className={styles.stack}>\n <p className={styles.helper}>{t('auth.verifyEmail.status.success')}</p>\n <Button type=\"button\" variant=\"secondary\" onClick={onBackToLogin}>\n {t('auth.verifyEmail.actions.continue')}\n </Button>\n </div>\n );\n } else if (state === 'error') {\n content = (\n <div className={styles.stack}>\n {error != null ? <FormError>{error}</FormError> : null}\n <Button type=\"button\" variant=\"secondary\" onClick={onBackToLogin}>\n {t('auth.verifyEmail.actions.return')}\n </Button>\n </div>\n );\n } else {\n content = (\n <div className={styles.stack}>\n <p className={styles.helper}>\n {t('auth.verifyEmail.status.verifying')}\n </p>\n <Button type=\"button\" isLoading>\n {t('auth.verifyEmail.status.verifyingButton')}\n </Button>\n </div>\n );\n }\n\n return (\n <AuthLayout\n title={t('auth.verifyEmail.title')}\n subtitle={t('auth.verifyEmail.subtitle')}\n >\n {content}\n </AuthLayout>\n );\n};\n"],"mappings":";;;;;;AAgBA,IAAa,KAAqB,EAChC,kBACA,kBACA,eACwB;CACxB,IAAM,EAAE,SAAM,GAA+B,EACvC,CAAC,GAAO,KAAY,EAA4B,UAAU,EAC1D,CAAC,GAAO,KAAY,EAAwB,KAAK,EAEjD,IAAgB,QAChB,MAGA,OAAO,SAAW,MACb,KAGF,IADY,gBAAgB,OAAO,SAAS,OAC5C,CAAO,IAAI,QAAQ,IAAI,KAC7B,CAAC,EAAM,CAAC;CAEX,QAAgB;EACd,IAAI,MAAkB,IAAI;GAExB,AADA,EAAS,QAAQ,EACjB,EAAS,EAAE,uCAAuC,CAAC;GACnD;;EAsBF,aAnB+C;GAC7C,IAAI;IAEF,AAAI,MADkB,EAAc,EAAE,OAAO,GAAe,CAAC,GAE3D,EAAS,UAAU,IAEnB,EAAS,QAAQ,EACjB,EAAS,EAAE,kCAAkC,CAAC;YAEzC,GAAe;IAEtB,AADA,EAAS,QAAQ,EACjB,EACE,aAAyB,QACrB,EAAc,UACd,EAAE,kCAAkC,CACzC;;MAIQ,CAAC,YAAY,GAExB;IACD;EAAC;EAAe;EAAe;EAAE,CAAC;CAErC,IAAI;CAgCJ,OA/BA,AAmBE,IAnBE,MAAU,YAEV,kBAAC,OAAD;EAAK,WAAW;YAAhB,CACE,kBAAC,KAAD;GAAG,WAAW;aAAgB,EAAE,kCAAkC;GAAK,CAAA,EACvE,kBAAC,GAAD;GAAQ,MAAK;GAAS,SAAQ;GAAY,SAAS;aAChD,EAAE,oCAAoC;GAChC,CAAA,CACL;MAEC,MAAU,UAEjB,kBAAC,OAAD;EAAK,WAAW;YAAhB,CACG,KAAS,OAAwC,OAAjC,kBAAC,GAAD,EAAA,UAAY,GAAkB,CAAA,EAC/C,kBAAC,GAAD;GAAQ,MAAK;GAAS,SAAQ;GAAY,SAAS;aAChD,EAAE,kCAAkC;GAC9B,CAAA,CACL;MAIN,kBAAC,OAAD;EAAK,WAAW;YAAhB,CACE,kBAAC,KAAD;GAAG,WAAW;aACX,EAAE,oCAAoC;GACrC,CAAA,EACJ,kBAAC,GAAD;GAAQ,MAAK;GAAS,WAAA;aACnB,EAAE,0CAA0C;GACtC,CAAA,CACL;KAKR,kBAAC,GAAD;EACE,OAAO,EAAE,yBAAyB;EAClC,UAAU,EAAE,4BAA4B;YAEvC;EACU,CAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./environment-DQfVyWHJ.js";
|
|
2
2
|
import { t as s } from "./useRelayEnvironment-vQ86aW-n.js";
|
|
3
3
|
import { n as c, r as l, t as u } from "./useBackofficeReactTranslation-Btt58EIo.js";
|
|
4
|
-
import {
|
|
4
|
+
import { o as d, t as f } from "./sidebarUtils-DVkLmFbS.js";
|
|
5
5
|
import { a as p, i as m, n as h, r as g, t as _ } from "./useAuth-CheTnq60.js";
|
|
6
6
|
import { n as v, t as y } from "./synchronizeAuthStatusQuery-BoPKMrP1.js";
|
|
7
7
|
import { t as b } from "./AcceptInvitationScreen-B1IPafwD.js";
|
|
@@ -15,7 +15,7 @@ import { a as se, i as ce, r as le, t as ue } from "./BackofficeDetailPayload-P6
|
|
|
15
15
|
import { t as de } from "./useBackofficeListUrlState-D4fx5O7u.js";
|
|
16
16
|
import { i as fe, n as pe, r as me, t as he } from "./mutationResult-CcQMY13J.js";
|
|
17
17
|
import { t as ge } from "./pageResolution-hAQA5C6S.js";
|
|
18
|
-
import { n as _e, t as ve } from "./BackofficeRightPageLayout-
|
|
18
|
+
import { n as _e, t as ve } from "./BackofficeRightPageLayout-hexJmpam.js";
|
|
19
19
|
import { StrictMode as ye, useCallback as C, useContext as be, useEffect as w, useMemo as T, useRef as xe, useState as E, useSyncExternalStore as Se } from "react";
|
|
20
20
|
import { createInstance as D } from "i18next";
|
|
21
21
|
import { I18nextProvider as Ce, initReactI18next as we, useTranslation as Te } from "react-i18next";
|
|
@@ -441,7 +441,10 @@ var Ye = {
|
|
|
441
441
|
unknownUser: "Unknown user"
|
|
442
442
|
},
|
|
443
443
|
search: { placeholder: "Search…" },
|
|
444
|
-
sections: {
|
|
444
|
+
sections: {
|
|
445
|
+
pinned: "Pinned",
|
|
446
|
+
recent: "Recent"
|
|
447
|
+
}
|
|
445
448
|
},
|
|
446
449
|
tools: { output: "Output" }
|
|
447
450
|
}, Xe = {
|
|
@@ -803,7 +806,10 @@ var Ye = {
|
|
|
803
806
|
unknownUser: "Utilisateur inconnu"
|
|
804
807
|
},
|
|
805
808
|
search: { placeholder: "Rechercher..." },
|
|
806
|
-
sections: {
|
|
809
|
+
sections: {
|
|
810
|
+
pinned: "Épinglés",
|
|
811
|
+
recent: "Récents"
|
|
812
|
+
}
|
|
807
813
|
},
|
|
808
814
|
tools: { output: "Résultat" }
|
|
809
815
|
}, I = (e) => typeof e == "object" && !!e && !Array.isArray(e), Ze = (e) => I(e) ? e : {};
|
|
@@ -842,7 +848,7 @@ function tt(e = {}) {
|
|
|
842
848
|
var { RelayEnvironmentProvider: nt } = k, R = ({ children: e }) => (Se(a, () => t().generation, () => t().generation), /* @__PURE__ */ A(nt, {
|
|
843
849
|
environment: n(),
|
|
844
850
|
children: e
|
|
845
|
-
})), { loadQuery: z, usePreloadedQuery: rt } = k, it = O("WrapperPage", async () => ({ default: (await import("@plumile/ui")).WrapperPage })), at = O("BackofficeLayoutPage", async () => import("./BackofficeLayoutPage-
|
|
851
|
+
})), { loadQuery: z, usePreloadedQuery: rt } = k, it = O("WrapperPage", async () => ({ default: (await import("@plumile/ui")).WrapperPage })), at = O("BackofficeLayoutPage", async () => import("./BackofficeLayoutPage-DQ0sVv24.js")), ot = O("BackofficeEntityListPage", async () => import("./BackofficeEntityListPage-DVT3rrfa.js")), st = O("BackofficeEntityDetailPage", async () => import("./BackofficeEntityDetailPage-CwzKp_Yw.js")), ct = O("BackofficeEntityDetailLayoutPage", async () => import("./BackofficeEntityDetailLayoutPage-DXjRqvcZ.js")), lt = O("BackofficeEntityDetailUnknownPageRedirect", async () => import("./BackofficeEntityDetailUnknownPageRedirect-DRWTeox-.js")), ut = O("BackofficeDashboardPage", async () => import("./BackofficeDashboardPage-r8vK_JA6.js")), dt = O("BackofficeLoginPage", async () => import("./BackofficeLoginPage-Cc3kcOQV.js")), ft = O("BackofficePasswordResetRequestPage", async () => import("./BackofficePasswordResetRequestPage-BJOrQXcy.js")), pt = O("BackofficePasswordResetCompletePage", async () => import("./BackofficePasswordResetCompletePage-CF_0t3Nq.js")), mt = O("BackofficeVerifyEmailPage", async () => import("./BackofficeVerifyEmailPage-C81LlsNM.js")), ht = O("BackofficeAcceptInvitationPage", async () => import("./BackofficeAcceptInvitationPage-CEtApVwL.js")), gt = (e) => {
|
|
846
852
|
let t = e.trim();
|
|
847
853
|
return t === "" || t === "/" ? "" : t.replace(/^\/+|\/+$/g, "");
|
|
848
854
|
}, _t = (e) => {
|