@plumile/backoffice-react 0.1.99 → 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
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LazyBackofficeEntityActionFormDialog-DVPQyWlr.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 BackofficeVirtualizedConnectionTable,\n Button,\n FilterChipRow,\n GlobalSearchInput,\n InlineBanner,\n ListPageTemplate,\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 virtualize = true,\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 virtualizationConfig = useMemo(() => {\n if (!virtualize) {\n return { enabled: false, rowHeightPx: 0, overscan: 0 };\n }\n\n return { enabled: true, rowHeightPx: 52, overscan: 10 };\n }, [virtualize]);\n\n const tableInnerNode = (\n <BackofficeVirtualizedConnectionTable\n columns={columnsWithPrimary}\n rows={rows}\n getRowId={getRowId}\n emptyState={resolvedEmptyState}\n className={denseTableClass}\n gridTemplateColumns={gridTemplateColumns}\n virtualization={virtualizationConfig}\n infiniteScroll={{\n enabled: true,\n thresholdPx: 800,\n autoLoad: true,\n }}\n hasNextPage={hasNextPage}\n isLoadingMore={isLoadingMore}\n onLoadMore={onLoadMore}\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 />\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,34 +0,0 @@
|
|
|
1
|
-
//#region src/components/backoffice/layout/sidebarUtils.ts
|
|
2
|
-
var e = (e, t) => e(t), t = (e, t) => !!(e === t || t !== "/" && e.startsWith(`${t}/`)), n = (e) => ({ main: { entities: Object.keys(e) } }), r = (e, t) => t?.groups ?? n(e), i = (e) => {
|
|
3
|
-
let t = /* @__PURE__ */ new Map();
|
|
4
|
-
return Object.entries(e).forEach(([e, n]) => {
|
|
5
|
-
n.entities != null && n.entities.forEach((r) => {
|
|
6
|
-
t.has(r) || t.set(r, {
|
|
7
|
-
groupId: e,
|
|
8
|
-
icon: n.icon
|
|
9
|
-
});
|
|
10
|
-
});
|
|
11
|
-
}), t;
|
|
12
|
-
}, a = (e, t, n, r) => {
|
|
13
|
-
let i = t[e];
|
|
14
|
-
if (i == null) return !1;
|
|
15
|
-
let a = {
|
|
16
|
-
kind: "entity",
|
|
17
|
-
id: e
|
|
18
|
-
};
|
|
19
|
-
return i.kind === "tool" && (a = {
|
|
20
|
-
kind: "tool",
|
|
21
|
-
id: e
|
|
22
|
-
}), n?.isItemVisible == null ? i.kind === "tool" ? !0 : i.hasList : n.isItemVisible(a, r);
|
|
23
|
-
}, o = (e, t, n, r) => {
|
|
24
|
-
let i = [], o = /* @__PURE__ */ new Set();
|
|
25
|
-
return Object.entries(e).forEach(([, e]) => {
|
|
26
|
-
e.isVisible != null && !e.isVisible(r) || e.entities != null && e.entities.forEach((e) => {
|
|
27
|
-
o.has(e) || a(e, t, n, r) && (o.add(e), i.push(e));
|
|
28
|
-
});
|
|
29
|
-
}), i;
|
|
30
|
-
};
|
|
31
|
-
//#endregion
|
|
32
|
-
export { o as a, r as i, t as n, e as r, i as t };
|
|
33
|
-
|
|
34
|
-
//# sourceMappingURL=sidebarUtils-CuwJ_3mD.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sidebarUtils-CuwJ_3mD.js","names":[],"sources":["../../src/components/backoffice/layout/sidebarUtils.ts"],"sourcesContent":["import type { TFunction } from 'i18next';\n\nimport type {\n BackofficeEntityManifestMap,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport type {\n BackofficeSidebarConfig,\n BackofficeIconComponent,\n BackofficeSidebarGroupConfig,\n BackofficeSidebarItemDescriptor,\n} from '../../../provider/types.js';\n\nexport const resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nexport const isActivePath = (pathname: string, href: string): boolean => {\n if (pathname === href) {\n return true;\n }\n if (href !== '/' && pathname.startsWith(`${href}/`)) {\n return true;\n }\n return false;\n};\n\nexport const buildDefaultGroups = (\n entities: BackofficeEntityManifestMap,\n): Record<string, BackofficeSidebarGroupConfig> => {\n const entityIds = Object.keys(entities);\n\n return {\n main: {\n entities: entityIds,\n },\n };\n};\n\nexport const resolveSidebarGroups = (\n entities: BackofficeEntityManifestMap,\n sidebar: BackofficeSidebarConfig | undefined,\n): Record<string, BackofficeSidebarGroupConfig> => {\n return sidebar?.groups ?? buildDefaultGroups(entities);\n};\n\nexport type EntityGroupLookup = Map<\n string,\n { groupId: string; icon?: BackofficeIconComponent }\n>;\n\nexport const buildEntityGroupLookup = (\n groups: Record<string, BackofficeSidebarGroupConfig>,\n): EntityGroupLookup => {\n const lookup: EntityGroupLookup = new Map();\n\n Object.entries(groups).forEach(([groupId, group]) => {\n if (group.entities == null) {\n return;\n }\n group.entities.forEach((entityId) => {\n if (!lookup.has(entityId)) {\n lookup.set(entityId, { groupId, icon: group.icon });\n }\n });\n });\n\n return lookup;\n};\n\nconst isEntityVisible = (\n entityId: string,\n entities: BackofficeEntityManifestMap,\n sidebar: BackofficeSidebarConfig | undefined,\n permissions: unknown,\n): boolean => {\n const config = entities[entityId];\n if (config == null) {\n return false;\n }\n\n let descriptor: BackofficeSidebarItemDescriptor = {\n kind: 'entity',\n id: entityId,\n };\n if (config.kind === 'tool') {\n descriptor = { kind: 'tool', id: entityId };\n }\n\n if (sidebar?.isItemVisible != null) {\n return sidebar.isItemVisible(descriptor, permissions);\n }\n\n if (config.kind === 'tool') {\n return true;\n }\n return config.hasList;\n};\n\nexport const resolveVisibleEntityIds = (\n groups: Record<string, BackofficeSidebarGroupConfig>,\n entities: BackofficeEntityManifestMap,\n sidebar: BackofficeSidebarConfig | undefined,\n permissions: unknown,\n): string[] => {\n const output: string[] = [];\n const seen = new Set<string>();\n\n Object.entries(groups).forEach(([, group]) => {\n if (group.isVisible != null && !group.isVisible(permissions)) {\n return;\n }\n if (group.entities == null) {\n return;\n }\n group.entities.forEach((entityId) => {\n if (seen.has(entityId)) {\n return;\n }\n if (!isEntityVisible(entityId, entities, sidebar, permissions)) {\n return;\n }\n seen.add(entityId);\n output.push(entityId);\n });\n });\n\n return output;\n};\n\nexport const resolveActiveEntityId = (\n pathname: string,\n entities: BackofficeEntityManifestMap,\n): string | null => {\n const entries = Object.entries(entities);\n for (const [entityId, config] of entries) {\n if (config.kind === 'tool') {\n if (isActivePath(pathname, config.routes.list)) {\n return entityId;\n }\n } else if (config.hasList && isActivePath(pathname, config.routes.list)) {\n return entityId;\n }\n }\n return null;\n};\n\nexport const resolveActiveGroupId = (\n groups: Record<string, BackofficeSidebarGroupConfig>,\n activeEntityId: string | null,\n entities: BackofficeEntityManifestMap,\n sidebar: BackofficeSidebarConfig | undefined,\n permissions: unknown,\n): string | null => {\n if (activeEntityId == null) {\n return null;\n }\n\n if (!isEntityVisible(activeEntityId, entities, sidebar, permissions)) {\n return null;\n }\n\n for (const [groupId, group] of Object.entries(groups)) {\n const isVisible = group.isVisible == null || group.isVisible(permissions);\n if (isVisible && group.entities?.includes(activeEntityId) === true) {\n return groupId;\n }\n }\n\n return null;\n};\n"],"mappings":";AAaA,IAAa,KAAgB,GAAkB,MACtC,EAAM,EAAK,EAGP,KAAgB,GAAkB,MAI7C,GAHI,MAAa,KAGb,MAAS,OAAO,EAAS,WAAW,GAAG,EAAK,GAAG,GAMxC,KACX,OAIO,EACL,MAAM,EACJ,UAJc,OAAO,KAAK,EAIhB,EACX,EACF,GAGU,KACX,GACA,MAEO,GAAS,UAAU,EAAmB,EAAS,EAQ3C,KACX,MACsB;CACtB,IAAM,oBAA4B,IAAI,KAAK;AAa3C,QAXA,OAAO,QAAQ,EAAO,CAAC,SAAS,CAAC,GAAS,OAAW;AAC/C,IAAM,YAAY,QAGtB,EAAM,SAAS,SAAS,MAAa;AACnC,GAAK,EAAO,IAAI,EAAS,IACvB,EAAO,IAAI,GAAU;IAAE;IAAS,MAAM,EAAM;IAAM,CAAC;IAErD;GACF,EAEK;GAGH,KACJ,GACA,GACA,GACA,MACY;CACZ,IAAM,IAAS,EAAS;AACxB,KAAI,KAAU,KACZ,QAAO;CAGT,IAAI,IAA8C;EAChD,MAAM;EACN,IAAI;EACL;AAYD,QAXI,EAAO,SAAS,WAClB,IAAa;EAAE,MAAM;EAAQ,IAAI;EAAU,GAGzC,GAAS,iBAAiB,OAI1B,EAAO,SAAS,SACX,KAEF,EAAO,UANL,EAAQ,cAAc,GAAY,EAAY;GAS5C,KACX,GACA,GACA,GACA,MACa;CACb,IAAM,IAAmB,EAAE,EACrB,oBAAO,IAAI,KAAa;AAqB9B,QAnBA,OAAO,QAAQ,EAAO,CAAC,SAAS,GAAG,OAAW;AACxC,IAAM,aAAa,QAAQ,CAAC,EAAM,UAAU,EAAY,IAGxD,EAAM,YAAY,QAGtB,EAAM,SAAS,SAAS,MAAa;AAC/B,KAAK,IAAI,EAAS,IAGjB,EAAgB,GAAU,GAAU,GAAS,EAAY,KAG9D,EAAK,IAAI,EAAS,EAClB,EAAO,KAAK,EAAS;IACrB;GACF,EAEK"}
|