@burojs/ui-shadcn 0.5.0 → 0.7.0
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/README.md +9 -0
- package/dist/bulk-summary-BWSAS7k2.js +143 -0
- package/dist/bulk-summary-BWSAS7k2.js.map +1 -0
- package/dist/bulk-summary-CrEij5vq.cjs +143 -0
- package/dist/bulk-summary-CrEij5vq.cjs.map +1 -0
- package/dist/candidates-relation-picker-CS_JZ4Fd.js +31 -0
- package/dist/candidates-relation-picker-CS_JZ4Fd.js.map +1 -0
- package/dist/candidates-relation-picker-y5M6_oe4.cjs +31 -0
- package/dist/candidates-relation-picker-y5M6_oe4.cjs.map +1 -0
- package/dist/{check-confirm-dialog-CkaVTPT9.js → check-confirm-dialog-2j0gOd7x.js} +392 -103
- package/dist/check-confirm-dialog-2j0gOd7x.js.map +1 -0
- package/dist/{check-confirm-dialog-BRByTFpg.cjs → check-confirm-dialog-C-NHgMST.cjs} +476 -102
- package/dist/check-confirm-dialog-C-NHgMST.cjs.map +1 -0
- package/dist/{dialog-B_rt9S1c.js → dialog-C123sVQ8.js} +4 -4
- package/dist/dialog-C123sVQ8.js.map +1 -0
- package/dist/{dialog-DRNUq9EA.cjs → dialog-vmMdfUWs.cjs} +3 -3
- package/dist/dialog-vmMdfUWs.cjs.map +1 -0
- package/dist/{filter-builder-B3mZFL-K.cjs → filter-builder-DFu0JP-1.cjs} +959 -128
- package/dist/filter-builder-DFu0JP-1.cjs.map +1 -0
- package/dist/{filter-builder-DOnaXNfP.js → filter-builder-DaWHUZuV.js} +863 -116
- package/dist/filter-builder-DaWHUZuV.js.map +1 -0
- package/dist/{flow-runtime-B6zOHYqI.cjs → flow-runtime-BpmrIUb6.cjs} +61 -29
- package/dist/flow-runtime-BpmrIUb6.cjs.map +1 -0
- package/dist/{flow-runtime-D8h99FSg.js → flow-runtime-DyqTmK3H.js} +62 -30
- package/dist/flow-runtime-DyqTmK3H.js.map +1 -0
- package/dist/{flow-screen-CX05b3G9.cjs → flow-screen-Bcz9NF2V.cjs} +132 -88
- package/dist/flow-screen-Bcz9NF2V.cjs.map +1 -0
- package/dist/{flow-screen-CmbARSqg.js → flow-screen-DCdli6Ha.js} +132 -88
- package/dist/flow-screen-DCdli6Ha.js.map +1 -0
- package/dist/index.cjs +951 -605
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +618 -332
- package/dist/index.d.ts +618 -332
- package/dist/index.js +863 -522
- package/dist/index.js.map +1 -1
- package/dist/{inline-flow-host-B7U1OJUe.cjs → inline-flow-host-3vw7LzzD.cjs} +5 -5
- package/dist/inline-flow-host-3vw7LzzD.cjs.map +1 -0
- package/dist/{inline-flow-host-C3H2UpSA.js → inline-flow-host-C0rI9B7f.js} +5 -5
- package/dist/inline-flow-host-C0rI9B7f.js.map +1 -0
- package/dist/label-66W1qbke.js.map +1 -1
- package/dist/label-w6JYf2cF.cjs.map +1 -1
- package/dist/lazy-relation-picker-dialog-Bt8lrEIu.cjs +153 -0
- package/dist/lazy-relation-picker-dialog-Bt8lrEIu.cjs.map +1 -0
- package/dist/lazy-relation-picker-dialog-CAScLPb2.js +135 -0
- package/dist/lazy-relation-picker-dialog-CAScLPb2.js.map +1 -0
- package/dist/markdown/index.d.cts +2 -3
- package/dist/markdown/index.d.ts +2 -3
- package/dist/{page-flow-route-CyXSvXSE.js → page-flow-route-BHUEpn0I.js} +36 -23
- package/dist/page-flow-route-BHUEpn0I.js.map +1 -0
- package/dist/{page-flow-route-CQ7HsbBm.cjs → page-flow-route-DS8IVTVH.cjs} +41 -28
- package/dist/page-flow-route-DS8IVTVH.cjs.map +1 -0
- package/dist/{place-node-SIp4XYQH.cjs → place-node-CNb3w-c7.cjs} +2227 -999
- package/dist/place-node-CNb3w-c7.cjs.map +1 -0
- package/dist/{place-node--GdsP688.js → place-node-CfzQvh4Y.js} +2164 -984
- package/dist/place-node-CfzQvh4Y.js.map +1 -0
- package/dist/{related-list-cards-B6x9HQQp.js → related-list-cards-BIqqY69Y.js} +9 -4
- package/dist/{related-list-cards-B6x9HQQp.js.map → related-list-cards-BIqqY69Y.js.map} +1 -1
- package/dist/{related-list-cards-nxuODlIA.cjs → related-list-cards-CelMxl4q.cjs} +9 -4
- package/dist/{related-list-cards-nxuODlIA.cjs.map → related-list-cards-CelMxl4q.cjs.map} +1 -1
- package/dist/{related-list-timeline-DEdfd-rr.js → related-list-timeline-CRh7xwLD.js} +6 -7
- package/dist/related-list-timeline-CRh7xwLD.js.map +1 -0
- package/dist/{related-list-timeline-BYJKEbmA.cjs → related-list-timeline-DsLdi8sv.cjs} +5 -6
- package/dist/related-list-timeline-DsLdi8sv.cjs.map +1 -0
- package/dist/{related-rows-B4levHcR.js → related-rows--uP2iKQC.js} +27 -17
- package/dist/related-rows--uP2iKQC.js.map +1 -0
- package/dist/{related-rows-zh5f_4QR.cjs → related-rows-MPnLCmPF.cjs} +32 -22
- package/dist/related-rows-MPnLCmPF.cjs.map +1 -0
- package/dist/{search-access-CURsWn-U.js → relation-create-C43cdPQt.js} +596 -29
- package/dist/relation-create-C43cdPQt.js.map +1 -0
- package/dist/{search-access-B7G5oR8n.cjs → relation-create-DDEYcKfw.cjs} +630 -32
- package/dist/relation-create-DDEYcKfw.cjs.map +1 -0
- package/dist/{relation-many-picker-gdAOD-qK.js → relation-many-picker-BJhaEqxz.js} +210 -107
- package/dist/relation-many-picker-BJhaEqxz.js.map +1 -0
- package/dist/{relation-many-picker-B-NCEUgX.cjs → relation-many-picker-DzuGJpEl.cjs} +218 -115
- package/dist/relation-many-picker-DzuGJpEl.cjs.map +1 -0
- package/dist/{relation-picker-BAY77ivO.js → relation-picker-D-tBBZW_.js} +40 -45
- package/dist/relation-picker-D-tBBZW_.js.map +1 -0
- package/dist/{relation-picker-Da_uhFvA.cjs → relation-picker-DaIMzf2H.cjs} +45 -50
- package/dist/relation-picker-DaIMzf2H.cjs.map +1 -0
- package/dist/{relation-picker-dialog-M0pQaWlp.cjs → relation-picker-dialog-9Vg5vvR1.cjs} +142 -40
- package/dist/relation-picker-dialog-9Vg5vvR1.cjs.map +1 -0
- package/dist/{relation-picker-dialog-hA9rYrZB.js → relation-picker-dialog-DoEY8EkH.js} +143 -41
- package/dist/relation-picker-dialog-DoEY8EkH.js.map +1 -0
- package/dist/relation-select-B8Fq4o-t.js +48 -0
- package/dist/relation-select-B8Fq4o-t.js.map +1 -0
- package/dist/relation-select-Cr3CfNLy.cjs +55 -0
- package/dist/relation-select-Cr3CfNLy.cjs.map +1 -0
- package/dist/{resource-page-router-OSQyRA5b.cjs → resource-page-router-C_kGW2o_.cjs} +552 -303
- package/dist/resource-page-router-C_kGW2o_.cjs.map +1 -0
- package/dist/{resource-page-router-T4vS5gbJ.js → resource-page-router-Diw6S6TK.js} +507 -258
- package/dist/resource-page-router-Diw6S6TK.js.map +1 -0
- package/dist/{rich-text-vTyVjDoa.cjs → rich-text-C_7JCvRo.cjs} +2 -2
- package/dist/{rich-text-vTyVjDoa.cjs.map → rich-text-C_7JCvRo.cjs.map} +1 -1
- package/dist/{rich-text-DFerywgz.js → rich-text-RcPBf6hr.js} +2 -2
- package/dist/{rich-text-DFerywgz.js.map → rich-text-RcPBf6hr.js.map} +1 -1
- package/dist/success-notices-Dl3M1fZP.cjs +46 -0
- package/dist/success-notices-Dl3M1fZP.cjs.map +1 -0
- package/dist/success-notices-LDEgEkc4.js +41 -0
- package/dist/success-notices-LDEgEkc4.js.map +1 -0
- package/dist/{toaster-C7CiYA4Z.cjs → toaster-BbByOytP.cjs} +72 -80
- package/dist/toaster-BbByOytP.cjs.map +1 -0
- package/dist/{toaster-CfCRLgR-.js → toaster-Ct_YHGs6.js} +66 -68
- package/dist/toaster-Ct_YHGs6.js.map +1 -0
- package/dist/{use-dialog-filter-state-BDcgS5Oz.js → use-dialog-filter-state-B_MqzHaT.js} +5 -4
- package/dist/use-dialog-filter-state-B_MqzHaT.js.map +1 -0
- package/dist/{use-dialog-filter-state-BBCC0OEK.cjs → use-dialog-filter-state-tNvqAAjh.cjs} +6 -5
- package/dist/use-dialog-filter-state-tNvqAAjh.cjs.map +1 -0
- package/dist/use-theme-DFlpXils.cjs.map +1 -1
- package/dist/use-theme-dnE3Od3I.js.map +1 -1
- package/package.json +11 -11
- package/dist/bulk-summary-CwSd6Yjb.cjs +0 -108
- package/dist/bulk-summary-CwSd6Yjb.cjs.map +0 -1
- package/dist/bulk-summary-GxMDP4bw.js +0 -108
- package/dist/bulk-summary-GxMDP4bw.js.map +0 -1
- package/dist/candidates-gate-CX2PBu6l.js +0 -63
- package/dist/candidates-gate-CX2PBu6l.js.map +0 -1
- package/dist/candidates-gate-DiFI52r7.cjs +0 -70
- package/dist/candidates-gate-DiFI52r7.cjs.map +0 -1
- package/dist/candidates-relation-picker-CBsVcnPR.js +0 -82
- package/dist/candidates-relation-picker-CBsVcnPR.js.map +0 -1
- package/dist/candidates-relation-picker-Dd_GVLlu.cjs +0 -84
- package/dist/candidates-relation-picker-Dd_GVLlu.cjs.map +0 -1
- package/dist/check-confirm-dialog-BRByTFpg.cjs.map +0 -1
- package/dist/check-confirm-dialog-CkaVTPT9.js.map +0 -1
- package/dist/dialog-B_rt9S1c.js.map +0 -1
- package/dist/dialog-DRNUq9EA.cjs.map +0 -1
- package/dist/filter-builder-B3mZFL-K.cjs.map +0 -1
- package/dist/filter-builder-DOnaXNfP.js.map +0 -1
- package/dist/flow-runtime-B6zOHYqI.cjs.map +0 -1
- package/dist/flow-runtime-D8h99FSg.js.map +0 -1
- package/dist/flow-screen-CX05b3G9.cjs.map +0 -1
- package/dist/flow-screen-CmbARSqg.js.map +0 -1
- package/dist/inline-flow-host-B7U1OJUe.cjs.map +0 -1
- package/dist/inline-flow-host-C3H2UpSA.js.map +0 -1
- package/dist/lazy-relation-picker-dialog-2oxnA6IR.js +0 -14
- package/dist/lazy-relation-picker-dialog-2oxnA6IR.js.map +0 -1
- package/dist/lazy-relation-picker-dialog-BfAGKzUG.cjs +0 -19
- package/dist/lazy-relation-picker-dialog-BfAGKzUG.cjs.map +0 -1
- package/dist/page-flow-route-CQ7HsbBm.cjs.map +0 -1
- package/dist/page-flow-route-CyXSvXSE.js.map +0 -1
- package/dist/peek-filter-CnqHwTMU.cjs +0 -51
- package/dist/peek-filter-CnqHwTMU.cjs.map +0 -1
- package/dist/peek-filter-ErLfO153.js +0 -28
- package/dist/peek-filter-ErLfO153.js.map +0 -1
- package/dist/place-node--GdsP688.js.map +0 -1
- package/dist/place-node-SIp4XYQH.cjs.map +0 -1
- package/dist/related-list-timeline-BYJKEbmA.cjs.map +0 -1
- package/dist/related-list-timeline-DEdfd-rr.js.map +0 -1
- package/dist/related-rows-B4levHcR.js.map +0 -1
- package/dist/related-rows-zh5f_4QR.cjs.map +0 -1
- package/dist/relation-create-BOaUe12G.cjs +0 -362
- package/dist/relation-create-BOaUe12G.cjs.map +0 -1
- package/dist/relation-create-Bg-eEJLs.js +0 -337
- package/dist/relation-create-Bg-eEJLs.js.map +0 -1
- package/dist/relation-many-picker-B-NCEUgX.cjs.map +0 -1
- package/dist/relation-many-picker-gdAOD-qK.js.map +0 -1
- package/dist/relation-picker-BAY77ivO.js.map +0 -1
- package/dist/relation-picker-Da_uhFvA.cjs.map +0 -1
- package/dist/relation-picker-dialog-M0pQaWlp.cjs.map +0 -1
- package/dist/relation-picker-dialog-hA9rYrZB.js.map +0 -1
- package/dist/resource-page-router-OSQyRA5b.cjs.map +0 -1
- package/dist/resource-page-router-T4vS5gbJ.js.map +0 -1
- package/dist/search-access-B7G5oR8n.cjs.map +0 -1
- package/dist/search-access-CURsWn-U.js.map +0 -1
- package/dist/shell-BPlk8hEa.js +0 -205
- package/dist/shell-BPlk8hEa.js.map +0 -1
- package/dist/shell-DxhlsPwm.cjs +0 -271
- package/dist/shell-DxhlsPwm.cjs.map +0 -1
- package/dist/toaster-C7CiYA4Z.cjs.map +0 -1
- package/dist/toaster-CfCRLgR-.js.map +0 -1
- package/dist/use-dialog-filter-state-BBCC0OEK.cjs.map +0 -1
- package/dist/use-dialog-filter-state-BDcgS5Oz.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
import { c as scrollToDocAnchor, l as cn, n as useTheme, s as readDocHash, t as THEME_CHOICES } from "./use-theme-dnE3Od3I.js";
|
|
2
|
-
import { a as
|
|
3
|
-
import { A as
|
|
2
|
+
import { a as technicalText, c as LinkComponentProvider, d as PopoverAnchor, f as PopoverClose, l as useLinkComponent, m as PopoverTrigger, n as toast, p as PopoverContent, r as friendlyStringsFrom, s as toFriendlyError, t as Toaster, u as Popover } from "./toaster-Ct_YHGs6.js";
|
|
3
|
+
import { $ as Tooltip, A as OwnTitleHeading, B as DropdownMenuContent, F as Icon, G as DropdownMenuRadioGroup, H as DropdownMenuItem, I as hasIcon, J as DropdownMenuShortcut, K as DropdownMenuRadioItem, L as registerIcons, M as DialogPresentationShell, N as OwnTitleContext, P as SheetPresentationShell, Q as DropdownMenuTrigger, R as DropdownMenu, T as loadFlowScreen, U as DropdownMenuLabel, V as DropdownMenuGroup, W as DropdownMenuPortal, X as DropdownMenuSubContent, Y as DropdownMenuSub, Z as DropdownMenuSubTrigger, _ as reasonText, a as modeForSurface, at as SheetContent, c as useListSlot, ct as SheetHeader, dt as DocInfo, et as TooltipContent, f as FlowActionButton, it as SheetClose, k as useLoaded, l as isExternalHref, lt as SheetTitle, n as ActionButton, nt as TooltipTrigger, o as canonicalResourceName, ot as SheetDescription, q as DropdownMenuSeparator, r as DisabledAction, rt as Sheet, s as listSlot, st as SheetFooter, t as CheckConfirmDialog, tt as TooltipProvider, u as openExternal, ut as SheetTrigger, v as FlowBoundary, y as FlowLoadFailed, z as DropdownMenuCheckboxItem } from "./check-confirm-dialog-2j0gOd7x.js";
|
|
4
4
|
import { n as buttonVariants, t as Button } from "./button-MWVeZaqj.js";
|
|
5
5
|
import { t as Input } from "./input-CUPStzZO.js";
|
|
6
|
-
import { a as DialogFooter, c as DialogTrigger, i as DialogDescription, n as DialogClose, o as DialogHeader, r as DialogContent, s as DialogTitle, t as Dialog } from "./dialog-
|
|
7
|
-
import { C as
|
|
8
|
-
import { a as SheetClose, c as SheetFooter, d as SheetTrigger, i as Sheet, l as SheetHeader, n as OwnTitleContext, o as SheetContent, r as SheetPresentationShell, s as SheetDescription, t as DialogPresentationShell, u as SheetTitle } from "./shell-BPlk8hEa.js";
|
|
6
|
+
import { a as DialogFooter, c as DialogTrigger, i as DialogDescription, n as DialogClose, o as DialogHeader, r as DialogContent, s as DialogTitle, t as Dialog } from "./dialog-C123sVQ8.js";
|
|
7
|
+
import { C as CommandEmpty, D as CommandList, E as CommandItem, O as CommandLoading, S as CommandDialog, T as CommandInput, b as RecordState, c as RelationField, d as peekAnchorOpener, f as PeekContext, h as recordDisplayName, k as CommandSeparator, l as relationLinkClassName, p as PeekHostContext, s as RelationDisplay, u as focusWithoutPeek, v as InvalidRouteId, w as CommandGroup, x as Command, y as LoadError } from "./relation-create-C43cdPQt.js";
|
|
9
8
|
import { t as Skeleton } from "./skeleton-U2noefj5.js";
|
|
10
|
-
import { $ as
|
|
9
|
+
import { $ as CursorLoadMore, A as ListSearchInput, At as EnumBadge, B as ExportDialog, Bt as usePaletteState, C as ListControls, D as ListFlows, E as ListLive, Et as ActionOverflow, F as ListColumns, Ft as i18nPrefixToRef, H as ScreenTree, I as ColumnsToggle, It as FieldValueFrame, L as DataTableViewOptions, Lt as toDisplayText, M as ExportButton, Mt as AppFlowButton, N as ListCreate, Nt as Field, O as ListFilters, Ot as useExportRunWatcher, P as CreateButton, Pt as FieldDisplay, Q as ResourceList, R as ListBulkBar, Rt as ShellProvider, T as SavedViewsDropdown, V as DeclarativeForm, Vt as useShell, W as QuickScreenClaimContext, Y as useFormControl, Z as ListBody, _ as CopyId, _t as resolveResourceTitle, a as peekFieldDefinition, at as DataTable, b as RecordTitle, bt as typography, c as peekRow, ct as TabsContent, d as resolveFrameView, et as ListErrorState, f as shadcnFrameViews, gt as ShowPageHeader, ht as PageHeader, it as useBuroDataTable, j as ListExport, k as FilterRegion, kt as downloadArtifact, l as useRelationPicker, lt as TabsList, mt as EditPageHeader, nt as resolveUpdater, o as peekLeafAllowed, ot as Checkbox, r as shadcnBlockImplementations, rt as tanStackSortingToBuro, s as peekRecord, st as Tabs, tt as buroSortingToTanStack, ut as TabsTrigger, v as FormActions, vt as DocumentTitleProvider, w as ListSavedViews, wt as recordRouteAvailable, xt as isShowAvailable, y as RecordActions, yt as useDocumentTitle, z as BulkActionToolbar, zt as defaultUserMapper } from "./place-node-CfzQvh4Y.js";
|
|
11
10
|
import { THEME_STORAGE_KEY } from "./layout/theme-storage-key.js";
|
|
12
|
-
import { A as
|
|
11
|
+
import { A as TableRow, B as loadLocale, C as SelectValue, D as TableCell, E as TableCaption, M as badgeVariants, O as TableHead, P as ResolvedFieldDisplay, R as lowerLegacyField, S as SelectTrigger, T as TableBody, V as saveLocale, _ as SelectItem, a as PinnedFilterControls, b as SelectScrollUpButton, c as fromLocalDateTimeText, d as formatDate, f as formatDateTime, g as SelectGroup, h as SelectContent, i as FacetedFilterPicker, j as Badge, k as TableHeader, l as toLocalDateTimeText, m as Select, n as PresetFilterControls, o as FilterPanel, p as formatNumber, r as DataTableFacetedFilter, s as FilterValueControl, t as FilterBuilder, u as FilterBadges, v as SelectLabel, w as Table, x as SelectSeparator, y as SelectScrollDownButton, z as DEFAULT_LANGUAGE_STORAGE_KEY } from "./filter-builder-DaWHUZuV.js";
|
|
12
|
+
import { A as TabsLayout, C as usePageAllowed, D as useLayout, E as layoutSlot, M as canonicalNavKey, N as canonicalResourceKey$1, O as useLayoutResolver, S as useNavVisible, T as BUILTIN_LAYOUTS, _ as PlannedBody, a as useRecordVisit, b as useHref, c as headerTrail, d as useTrailContext, f as recordTrailKey, g as useResourceDimensionOptions, h as RecordScreen, i as RecordPage, j as SecondarySidebarLayout, k as useReportUnresolvedLayouts, l as recordTrail, m as usePublishedRecordTrail, n as NavAreaPage, o as RECENT_LABEL_KEYS, r as ResourcePageRouter, s as readRecentRecords, u as recordTrailRoute, v as ResourceListPage, w as useResourceVisible, x as useMatch, y as NavChromeMountedProvider } from "./resource-page-router-Diw6S6TK.js";
|
|
13
13
|
import { t as Label } from "./label-66W1qbke.js";
|
|
14
|
-
import {
|
|
15
|
-
import { n as RelationPicker, r as RelationPickerInput } from "./relation-picker-
|
|
16
|
-
import { t as
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import { IconAlertCircle, IconArrowLeft, IconArrowUpRight, IconBook2, IconCheck, IconChevronDown, IconChevronRight, IconCirclePlus, IconDeviceDesktop, IconDots, IconExternalLink, IconHelp, IconHelpHexagon, IconLayoutSidebar, IconLoader2, IconLogin, IconLogout, IconMaximize, IconMinimize, IconMoon, IconRefresh, IconRotate, IconSearch, IconSelector, IconSun, IconUpload, IconUser, IconX } from "@tabler/icons-react";
|
|
14
|
+
import { t as LazyRelationPickerDialog } from "./lazy-relation-picker-dialog-CAScLPb2.js";
|
|
15
|
+
import { n as RelationPicker, r as RelationPickerInput } from "./relation-picker-D-tBBZW_.js";
|
|
16
|
+
import { t as useDialogFilterState } from "./use-dialog-filter-state-B_MqzHaT.js";
|
|
17
|
+
import { useGlobalShortcut, webPlatform } from "@burojs/react/web";
|
|
18
|
+
import { ENUM_CONTROLS, builtinFrames, columnName, compilePageScreen, compiledScreenFor, declaredField, declaredText, dtoFields, effectiveFlow, enumFallbackKey, enumFallbackText, enumNamespaceOf, enumValueText, evaluateVisible, fieldOptionText, formatEntityRef, hasListPage, hasRecordPage, hrefFor, humanizeKey, isCustomPageDef, isEnumControl, isRelationField, isScreenFailure, linkOf, navHrefFor, nodeKind, normalizeDataError, normalizeEntityRef, projectDto, recordEntries, relationAmbiguousError, resolveConceptLabel, resolveContentSlot, resolveDoc, resolveEnumLabel, resolveFieldLabel, resolveNavLabel, resolveResourceLabel, resolveResourceNavLabel, resolveStaticAvailability, resourceCreateHref, resourceKey, resourceShowHref, routeResourceKey, snapshotAppFrames, snapshotBlockLookup, snapshotFrameLookup, taskRunFraction, taskRunOutcome } from "@burojs/core";
|
|
19
|
+
import { ComponentsContext, DispatcherProvider, I18nContext, NO_RECORD_SCOPE_FRAMES, QUICK_ANCHOR_ATTRIBUTE, QuickEntryContext, RecordScopeChain, RouteSourceContext, ScreenStateProvider, formatBytes, optionFieldName, resolveErrorText, resolveOptionLabel, retryRecordRead, useApp, useAppActions, useApplicationSnapshot, useAvailabilityGate, useBoundEnum, useCapabilityResolver, useChangeLocale, useChromeT, useCommandPalette, useCurrentUserId, useDebouncedValue, useDispatcherEffects, useDocPanel, useDocScopes, useDocTopics, useDocTrailScopes, useDocsConfig, useDocumentedScopes, useEntryGate, useEnumValues, useFieldAccess, useFileField, useFileUrls, useFormController, useFrameImplementations, useFrameT, useI18nCaps, useIdentity, useLanguageStorageKey, useLinkKeys, useList, useListAccess, useLocale, useLogout, useNavigationGuardText, useOne, useOptionCaps, useOptionalApp, useOptionalAuthController, useOptionalDataRuntime, useOptionalFileStorage, useOptionalLocale, useOptionalRouterAdapter, useOptionalT, usePlatformStorage, usePresentBlock, useProjectedRecord, useProjectedTitle, useQuick, useQuickEntry, useQuickEntryValue, useQuickOpener, useRecordTitle, useRefresh, useRegisterNavigationGuardDialog, useRelatedRecord, useRouteNavigate, useRouteRecordId, useRouterAdapter, useScope, useT, useTestIds, useUIInstance, useUIPresentationRuntime, useVisibilityCtx } from "@burojs/react";
|
|
20
|
+
import { IconAlertCircle, IconArrowLeft, IconArrowUpRight, IconBook2, IconCheck, IconChevronDown, IconChevronRight, IconDeviceDesktop, IconDots, IconExternalLink, IconHelp, IconHelpHexagon, IconLayoutSidebar, IconLoader2, IconLogin, IconLogout, IconMaximize, IconMinimize, IconMoon, IconRefresh, IconRotate, IconSearch, IconSelector, IconSun, IconUpload, IconUser, IconX } from "@tabler/icons-react";
|
|
22
21
|
import * as React from "react";
|
|
23
22
|
import { Children, Fragment, Suspense, cloneElement, createContext, createElement, isValidElement, lazy, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
24
23
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -30,6 +29,7 @@ import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
|
|
30
29
|
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
|
|
31
30
|
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
32
31
|
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
|
32
|
+
import { enumBindingKey } from "@burojs/core/internal";
|
|
33
33
|
import { Controller, FormProvider, useForm, useFormContext } from "react-hook-form";
|
|
34
34
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
35
35
|
import { z } from "zod";
|
|
@@ -490,7 +490,7 @@ function ScopeSummary({ scope, summary }) {
|
|
|
490
490
|
const caps = useI18nCaps();
|
|
491
491
|
const t = useOptionalT();
|
|
492
492
|
const links = (scope !== void 0 ? resolveDoc(caps, scope) : void 0)?.links ?? [];
|
|
493
|
-
const newTabNote = t("docPanel.
|
|
493
|
+
const newTabNote = t("docPanel.opensInNewTab", { defaultValue: "(opens in a new tab)" });
|
|
494
494
|
if (summary === void 0 && links.length === 0) return null;
|
|
495
495
|
return jsxs("div", {
|
|
496
496
|
className: "mt-2 flex flex-col items-start gap-3",
|
|
@@ -1112,7 +1112,7 @@ AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
|
|
|
1112
1112
|
function NavigationGuardDialog() {
|
|
1113
1113
|
const prompt = useRegisterNavigationGuardDialog();
|
|
1114
1114
|
const text = useNavigationGuardText();
|
|
1115
|
-
const unsavedAction = useOptionalT()("navigation.unsavedAction");
|
|
1115
|
+
const unsavedAction = useOptionalT()("navigation.unsavedAction", { defaultValue: "An action on this screen has unsaved input" });
|
|
1116
1116
|
const returnFocus = useRef(null);
|
|
1117
1117
|
const wasOpen = useRef(false);
|
|
1118
1118
|
const open = prompt !== null;
|
|
@@ -1135,7 +1135,7 @@ function NavigationGuardDialog() {
|
|
|
1135
1135
|
event.preventDefault();
|
|
1136
1136
|
element.focus();
|
|
1137
1137
|
},
|
|
1138
|
-
children: [jsxs(AlertDialogHeader, { children: [jsx(AlertDialogTitle, { children: text.title }), jsxs(AlertDialogDescription, { children: [text.body, prompt !== null && prompt.labels.length > 0 ? ` ${unsavedAction
|
|
1138
|
+
children: [jsxs(AlertDialogHeader, { children: [jsx(AlertDialogTitle, { children: text.title }), jsxs(AlertDialogDescription, { children: [text.body, prompt !== null && prompt.labels.length > 0 ? ` ${unsavedAction}: ${prompt.labels.join(", ")}.` : null] })] }), jsxs(AlertDialogFooter, { children: [jsx(AlertDialogCancel, {
|
|
1139
1139
|
"data-testid": "nav-guard-stay",
|
|
1140
1140
|
children: text.stay
|
|
1141
1141
|
}), jsx(AlertDialogAction, {
|
|
@@ -1695,14 +1695,14 @@ const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
|
|
|
1695
1695
|
const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
|
|
1696
1696
|
//#endregion
|
|
1697
1697
|
//#region src/shell/use-nav-icon.tsx
|
|
1698
|
-
const warned = new Set();
|
|
1698
|
+
const warned$1 = new Set();
|
|
1699
1699
|
function resolveNavIcon(name, components) {
|
|
1700
1700
|
if (name === void 0 || name === "") return void 0;
|
|
1701
1701
|
const slot = components(name);
|
|
1702
1702
|
if (typeof slot === "function" || typeof slot === "object" && slot !== null) return jsx(slot, { className: "h-4 w-4" });
|
|
1703
1703
|
if (hasIcon(name)) return jsx(Icon, { name });
|
|
1704
|
-
if (process.env.NODE_ENV !== "production" && !warned.has(name)) {
|
|
1705
|
-
warned.add(name);
|
|
1704
|
+
if (process.env.NODE_ENV !== "production" && !warned$1.has(name)) {
|
|
1705
|
+
warned$1.add(name);
|
|
1706
1706
|
console.warn(`[buro] unknown nav icon "${name}"`);
|
|
1707
1707
|
}
|
|
1708
1708
|
}
|
|
@@ -1711,6 +1711,53 @@ function useNavIcon() {
|
|
|
1711
1711
|
return useCallback((name) => resolveNavIcon(name, (key) => components[key]), [components]);
|
|
1712
1712
|
}
|
|
1713
1713
|
//#endregion
|
|
1714
|
+
//#region src/layout/build-nav-items.ts
|
|
1715
|
+
function buildNavItems(args) {
|
|
1716
|
+
const { registry, caps, groupName, match, isVisible, entryFilter, icons } = args;
|
|
1717
|
+
const chain = match?.groupChain ?? [];
|
|
1718
|
+
const qualifiedMatch = match;
|
|
1719
|
+
const activeLeaf = qualifiedMatch == null ? void 0 : qualifiedMatch.kind === "group-index" ? canonicalNavKey({
|
|
1720
|
+
name: qualifiedMatch.target ?? qualifiedMatch.name,
|
|
1721
|
+
ref: qualifiedMatch.targetRef
|
|
1722
|
+
}) : canonicalNavKey(qualifiedMatch);
|
|
1723
|
+
const isEligible = (node) => isVisible(node) && (entryFilter ? entryFilter(node) : true);
|
|
1724
|
+
const out = [];
|
|
1725
|
+
for (const child of registry.groups.childrenOf(groupName)) {
|
|
1726
|
+
if (!isEligible(child)) continue;
|
|
1727
|
+
const kind = nodeKind(child);
|
|
1728
|
+
const childKey = canonicalNavKey(child);
|
|
1729
|
+
const href = navHrefFor(registry, childKey, { isVisible: isEligible });
|
|
1730
|
+
if (kind === "group") {
|
|
1731
|
+
const label = resolveNavLabel(caps, `groups.${childKey}`, declaredText("chrome", child, "label"));
|
|
1732
|
+
const active = chain.some((g) => canonicalNavKey(g) === childKey);
|
|
1733
|
+
out.push({
|
|
1734
|
+
kind: "group",
|
|
1735
|
+
name: childKey,
|
|
1736
|
+
label,
|
|
1737
|
+
href,
|
|
1738
|
+
icon: icons?.group?.(childKey),
|
|
1739
|
+
active
|
|
1740
|
+
});
|
|
1741
|
+
} else if (kind === "custom-page") out.push({
|
|
1742
|
+
kind: "custom-page",
|
|
1743
|
+
name: childKey,
|
|
1744
|
+
label: resolveNavLabel(caps, `pages.${childKey}`, declaredText("chrome", child, "label")),
|
|
1745
|
+
href,
|
|
1746
|
+
icon: icons?.page?.(childKey),
|
|
1747
|
+
active: activeLeaf === childKey
|
|
1748
|
+
});
|
|
1749
|
+
else out.push({
|
|
1750
|
+
kind: "resource",
|
|
1751
|
+
name: childKey,
|
|
1752
|
+
label: resolveResourceNavLabel(caps, childKey, child),
|
|
1753
|
+
href,
|
|
1754
|
+
icon: icons?.resource?.(childKey),
|
|
1755
|
+
active: activeLeaf === childKey
|
|
1756
|
+
});
|
|
1757
|
+
}
|
|
1758
|
+
return out;
|
|
1759
|
+
}
|
|
1760
|
+
//#endregion
|
|
1714
1761
|
//#region src/layout/use-nav-tree.ts
|
|
1715
1762
|
function isActiveHref(href, currentPath) {
|
|
1716
1763
|
if (!currentPath) return false;
|
|
@@ -1724,8 +1771,7 @@ function useNavTree(opts = {}) {
|
|
|
1724
1771
|
const passesEntryFilter = (entry) => entryFilter ? entryFilter(entry) : true;
|
|
1725
1772
|
const app = useApp();
|
|
1726
1773
|
const caps = useI18nCaps();
|
|
1727
|
-
const
|
|
1728
|
-
const isResourceVisible = (r) => evaluateVisible(r.visible, visibilityCtx);
|
|
1774
|
+
const isResourceVisible = useResourceVisible();
|
|
1729
1775
|
const resolveLayout = useLayoutResolver();
|
|
1730
1776
|
const match = useMatch();
|
|
1731
1777
|
const isVisible = useNavVisible();
|
|
@@ -1735,6 +1781,7 @@ function useNavTree(opts = {}) {
|
|
|
1735
1781
|
const allCustomPages = app.registry.customPages.list();
|
|
1736
1782
|
const sections = app.registry.sections.list();
|
|
1737
1783
|
const groups = app.registry.groups.rootNodes().filter((n) => nodeKind(n) === "group");
|
|
1784
|
+
useReportUnresolvedLayouts(app.registry.groups.list(), resolveLayout);
|
|
1738
1785
|
const topLevelResources = allResources.filter((r) => hasListPage(r)).filter(isResourceVisible).filter(passesEntryFilter).filter((r) => !r.section && !r.group).map((r, idx) => ({
|
|
1739
1786
|
r,
|
|
1740
1787
|
idx
|
|
@@ -1744,11 +1791,11 @@ function useNavTree(opts = {}) {
|
|
|
1744
1791
|
return ao !== bo ? ao - bo : a.idx - b.idx;
|
|
1745
1792
|
}).map((x) => x.r);
|
|
1746
1793
|
const topLevelCustomPages = allCustomPages.filter((p) => !p.section && !p.group).filter(pageAllowed).filter(passesEntryFilter);
|
|
1747
|
-
const resourceHref = (def) => hrefFor(app.registry, canonicalResourceKey(def));
|
|
1748
|
-
const resourceLabel = (def) => resolveResourceNavLabel(caps, canonicalResourceKey(def), def);
|
|
1749
|
-
const pageLabel = (page) => resolveNavLabel(caps, `pages.${canonicalNavKey(page)}`, page
|
|
1750
|
-
const sectionLabel = (section) => resolveNavLabel(caps, `sections.${canonicalNavKey(section)}`, section
|
|
1751
|
-
const groupLabel = (group) => resolveNavLabel(caps, `groups.${canonicalNavKey(group)}`, group
|
|
1794
|
+
const resourceHref = (def) => hrefFor(app.registry, canonicalResourceKey$1(def));
|
|
1795
|
+
const resourceLabel = (def) => resolveResourceNavLabel(caps, canonicalResourceKey$1(def), def);
|
|
1796
|
+
const pageLabel = (page) => resolveNavLabel(caps, `pages.${canonicalNavKey(page)}`, declaredText("chrome", page, "label"));
|
|
1797
|
+
const sectionLabel = (section) => resolveNavLabel(caps, `sections.${canonicalNavKey(section)}`, declaredText("chrome", section, "label"));
|
|
1798
|
+
const groupLabel = (group) => resolveNavLabel(caps, `groups.${canonicalNavKey(group)}`, declaredText("chrome", group, "label"));
|
|
1752
1799
|
const pageEntry = (page) => {
|
|
1753
1800
|
const href = page.path;
|
|
1754
1801
|
return {
|
|
@@ -1764,7 +1811,7 @@ function useNavTree(opts = {}) {
|
|
|
1764
1811
|
const href = resourceHref(def);
|
|
1765
1812
|
return {
|
|
1766
1813
|
kind: "resource",
|
|
1767
|
-
key: canonicalResourceKey(def),
|
|
1814
|
+
key: canonicalResourceKey$1(def),
|
|
1768
1815
|
label: resourceLabel(def),
|
|
1769
1816
|
href,
|
|
1770
1817
|
icon: def.icon,
|
|
@@ -1972,7 +2019,7 @@ function NavMain({ topLabel, iconForResource, iconForCustomPage, iconForSection,
|
|
|
1972
2019
|
})
|
|
1973
2020
|
}) }, entry.key);
|
|
1974
2021
|
const [top, ...blocks] = tree;
|
|
1975
|
-
return jsxs(Fragment$1, { children: [jsxs(SidebarGroup, { children: [topLabel !== null && jsx(SidebarGroupLabel, { children: topLabel ?? t("nav.resources") }), jsx(SidebarGroupContent, { children: jsx(SidebarMenu, { children: top
|
|
2022
|
+
return jsxs(Fragment$1, { children: [top !== void 0 && top.entries.length > 0 && jsxs(SidebarGroup, { children: [topLabel !== null && jsx(SidebarGroupLabel, { children: topLabel ?? t("nav.resources") }), jsx(SidebarGroupContent, { children: jsx(SidebarMenu, { children: top.entries.map(menuItem) }) })] }), blocks.map((block) => {
|
|
1976
2023
|
const key = block.key ?? "";
|
|
1977
2024
|
if (block.label === null) return jsx(SidebarGroup, { children: jsx(SidebarGroupContent, { children: jsx(SidebarMenu, { children: block.entries.map(menuItem) }) }) }, key);
|
|
1978
2025
|
if (block.collapsible) return jsx(CollapsibleNavSection, {
|
|
@@ -2016,126 +2063,31 @@ function AppSidebar({ header, filters, nav, footer }) {
|
|
|
2016
2063
|
});
|
|
2017
2064
|
}
|
|
2018
2065
|
//#endregion
|
|
2019
|
-
//#region src/layout/
|
|
2020
|
-
function Row({ it }) {
|
|
2021
|
-
const RouterLink = useLinkComponent();
|
|
2022
|
-
return jsx("li", { children: jsxs(RouterLink, {
|
|
2023
|
-
href: it.href,
|
|
2024
|
-
"data-testid": `nav-secondary-item:${it.name}`,
|
|
2025
|
-
"aria-current": it.active ? "page" : void 0,
|
|
2026
|
-
className: cn("flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium outline-hidden ring-offset-background transition-colors", "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", it.active ? "bg-secondary text-secondary-foreground" : "text-muted-foreground hover:bg-secondary/50 hover:text-foreground"),
|
|
2027
|
-
children: [it.icon != null && jsx("span", {
|
|
2028
|
-
className: "inline-flex h-4 w-4 shrink-0 items-center justify-center",
|
|
2029
|
-
"aria-hidden": "true",
|
|
2030
|
-
children: it.icon
|
|
2031
|
-
}), jsx("span", {
|
|
2032
|
-
className: "truncate",
|
|
2033
|
-
title: it.label,
|
|
2034
|
-
children: it.label
|
|
2035
|
-
})]
|
|
2036
|
-
}) });
|
|
2037
|
-
}
|
|
2038
|
-
function SecondarySidebarLayout({ group, groupKey, items, children }) {
|
|
2039
|
-
const RouterLink = useLinkComponent();
|
|
2040
|
-
const caps = useI18nCaps();
|
|
2041
|
-
const id = groupKey ?? group.name;
|
|
2042
|
-
const label = resolveNavLabel(caps, `groups.${id}`, group.label);
|
|
2043
|
-
return jsxs("div", {
|
|
2044
|
-
className: "md:-m-6 md:flex md:min-h-[calc(100%+3rem)]",
|
|
2045
|
-
"data-testid": `nav-secondary:${id}`,
|
|
2046
|
-
children: [
|
|
2047
|
-
jsx("aside", {
|
|
2048
|
-
className: "hidden w-64 shrink-0 border-r bg-background text-foreground md:block",
|
|
2049
|
-
children: jsxs("div", {
|
|
2050
|
-
className: "space-y-4 p-4",
|
|
2051
|
-
children: [jsx("p", {
|
|
2052
|
-
className: "px-3 text-base font-semibold tracking-tight",
|
|
2053
|
-
children: label
|
|
2054
|
-
}), jsx("nav", {
|
|
2055
|
-
"aria-label": label,
|
|
2056
|
-
children: jsx("ul", {
|
|
2057
|
-
className: "space-y-0.5",
|
|
2058
|
-
children: items.map((it) => jsx(Row, { it }, it.name))
|
|
2059
|
-
})
|
|
2060
|
-
})]
|
|
2061
|
-
})
|
|
2062
|
-
}),
|
|
2063
|
-
jsx("nav", {
|
|
2064
|
-
"aria-label": label,
|
|
2065
|
-
"data-testid": `nav-secondary-select:${id}`,
|
|
2066
|
-
className: "-mx-1 mb-4 flex snap-x snap-proximity gap-1.5 overflow-x-auto scroll-smooth px-1 pb-1 [-ms-overflow-style:none] [mask-image:linear-gradient(to_right,transparent,black_8px,black_calc(100%-8px),transparent)] [scrollbar-width:none] md:hidden [&::-webkit-scrollbar]:hidden",
|
|
2067
|
-
children: items.map((it) => jsx(RouterLink, {
|
|
2068
|
-
href: it.href,
|
|
2069
|
-
"aria-current": it.active ? "page" : void 0,
|
|
2070
|
-
className: cn("snap-start whitespace-nowrap rounded-full border px-3 py-1.5 text-sm outline-hidden ring-offset-background transition-colors duration-150", "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", it.active ? "border-primary/40 bg-primary/10 font-medium text-foreground" : "border-border text-muted-foreground hover:bg-accent/60 hover:text-accent-foreground"),
|
|
2071
|
-
children: it.label
|
|
2072
|
-
}, it.name))
|
|
2073
|
-
}),
|
|
2074
|
-
jsx("div", {
|
|
2075
|
-
className: "min-w-0 flex-1 md:overflow-x-hidden md:p-6",
|
|
2076
|
-
children
|
|
2077
|
-
})
|
|
2078
|
-
]
|
|
2079
|
-
});
|
|
2080
|
-
}
|
|
2081
|
-
//#endregion
|
|
2082
|
-
//#region src/layout/layouts/tabs-layout.tsx
|
|
2083
|
-
function TabsLayout({ group, groupKey, items, children }) {
|
|
2084
|
-
const RouterLink = useLinkComponent();
|
|
2085
|
-
const caps = useI18nCaps();
|
|
2086
|
-
const id = groupKey ?? group.name;
|
|
2087
|
-
const label = resolveNavLabel(caps, `groups.${id}`, group.label);
|
|
2088
|
-
return jsxs("div", {
|
|
2089
|
-
className: "flex flex-col gap-4",
|
|
2090
|
-
"data-testid": `nav-tabs:${id}`,
|
|
2091
|
-
children: [jsx("nav", {
|
|
2092
|
-
"aria-label": label,
|
|
2093
|
-
className: "flex gap-1 overflow-x-auto scroll-smooth border-b border-border [-ms-overflow-style:none] [mask-image:linear-gradient(to_right,transparent,black_8px,black_calc(100%-8px),transparent)] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
2094
|
-
children: items.map((it) => jsxs(RouterLink, {
|
|
2095
|
-
href: it.href,
|
|
2096
|
-
"aria-current": it.active ? "page" : void 0,
|
|
2097
|
-
"data-testid": `nav-tab:${it.name}`,
|
|
2098
|
-
className: cn("group/tab relative flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-t-sm px-3 py-2.5 text-sm outline-hidden ring-offset-background transition-colors duration-150", "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", it.active ? "font-medium text-foreground" : "text-muted-foreground hover:text-foreground"),
|
|
2099
|
-
children: [
|
|
2100
|
-
it.icon != null && jsx("span", {
|
|
2101
|
-
className: "inline-flex h-4 w-4 shrink-0 items-center justify-center",
|
|
2102
|
-
"aria-hidden": "true",
|
|
2103
|
-
children: it.icon
|
|
2104
|
-
}),
|
|
2105
|
-
it.label,
|
|
2106
|
-
jsx("span", {
|
|
2107
|
-
"aria-hidden": "true",
|
|
2108
|
-
className: cn("pointer-events-none absolute inset-x-2 -bottom-px h-0.5 origin-center scale-x-0 rounded-full bg-primary opacity-0 transition-all duration-300 ease-out", it.active ? "scale-x-100 opacity-100" : "group-hover/tab:scale-x-100 group-hover/tab:opacity-30")
|
|
2109
|
-
})
|
|
2110
|
-
]
|
|
2111
|
-
}, it.name))
|
|
2112
|
-
}), jsx("div", {
|
|
2113
|
-
className: "min-w-0",
|
|
2114
|
-
children
|
|
2115
|
-
})]
|
|
2116
|
-
});
|
|
2117
|
-
}
|
|
2118
|
-
//#endregion
|
|
2119
|
-
//#region src/layout/nav-area-layout.tsx
|
|
2066
|
+
//#region src/layout/nav-chrome.tsx
|
|
2120
2067
|
const DETAIL_ACTIONS = new Set([
|
|
2121
2068
|
"show",
|
|
2122
2069
|
"edit",
|
|
2123
2070
|
"create"
|
|
2124
2071
|
]);
|
|
2125
|
-
function
|
|
2072
|
+
function NavChrome({ children, entryFilter, icons }) {
|
|
2126
2073
|
const app = useApp();
|
|
2127
2074
|
const caps = useI18nCaps();
|
|
2128
2075
|
const isVisible = useNavVisible();
|
|
2129
2076
|
const match = useMatch();
|
|
2130
2077
|
const resolveLayout = useLayoutResolver();
|
|
2131
|
-
|
|
2132
|
-
if (!
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
const Layout = resolveLayout(group.layout);
|
|
2078
|
+
useReportUnresolvedLayouts(match?.groupChain ?? [], resolveLayout);
|
|
2079
|
+
if (!match) return jsx(NavChromeMountedProvider, {
|
|
2080
|
+
value: true,
|
|
2081
|
+
children
|
|
2082
|
+
});
|
|
2137
2083
|
let content = children;
|
|
2138
|
-
|
|
2084
|
+
for (let i = match.groupChain.length - 1; i >= 0; i--) {
|
|
2085
|
+
const group = match.groupChain[i];
|
|
2086
|
+
if (!group) continue;
|
|
2087
|
+
const groupKey = canonicalNavKey(group);
|
|
2088
|
+
if (group.chromeOn === "list" && match.kind === "resource" && DETAIL_ACTIONS.has(match.action)) continue;
|
|
2089
|
+
const Layout = resolveLayout(group.layout);
|
|
2090
|
+
if (!Layout) continue;
|
|
2139
2091
|
const items = buildNavItems({
|
|
2140
2092
|
registry: app.registry,
|
|
2141
2093
|
caps,
|
|
@@ -2149,11 +2101,11 @@ function NavAreaLayout({ groupName, children, entryFilter, icons }) {
|
|
|
2149
2101
|
group,
|
|
2150
2102
|
groupKey,
|
|
2151
2103
|
items,
|
|
2152
|
-
children
|
|
2104
|
+
children: content
|
|
2153
2105
|
});
|
|
2154
2106
|
}
|
|
2155
|
-
return jsx(
|
|
2156
|
-
|
|
2107
|
+
return jsx(NavChromeMountedProvider, {
|
|
2108
|
+
value: true,
|
|
2157
2109
|
children: content
|
|
2158
2110
|
});
|
|
2159
2111
|
}
|
|
@@ -2166,10 +2118,12 @@ function Chevron() {
|
|
|
2166
2118
|
"aria-hidden": "true"
|
|
2167
2119
|
});
|
|
2168
2120
|
}
|
|
2169
|
-
function Breadcrumbs(
|
|
2121
|
+
function Breadcrumbs(input) {
|
|
2122
|
+
const props = input;
|
|
2170
2123
|
const { leadingSegments, className, docScopes, "data-testid": testId } = props;
|
|
2171
2124
|
const app = useApp();
|
|
2172
|
-
const
|
|
2125
|
+
const resource = props.resource === void 0 ? void 0 : routeResourceKey(props.resource);
|
|
2126
|
+
const def = resource === void 0 ? void 0 : app.registry.get(resource);
|
|
2173
2127
|
const tid = useTestIds();
|
|
2174
2128
|
const t = useOptionalT();
|
|
2175
2129
|
const RouterLink = useLinkComponent();
|
|
@@ -2214,7 +2168,7 @@ function Breadcrumbs(props) {
|
|
|
2214
2168
|
});
|
|
2215
2169
|
if (!def) return null;
|
|
2216
2170
|
const { recordId, pageLabel, middleSegments } = props;
|
|
2217
|
-
const resourceKey = canonicalResourceKey(def);
|
|
2171
|
+
const resourceKey = canonicalResourceKey$1(def);
|
|
2218
2172
|
const listHref = hrefFor(app.registry, resourceKey);
|
|
2219
2173
|
const resourceLabel = resolveResourceLabel(caps, resourceKey, "plural", def);
|
|
2220
2174
|
const resourceIsCurrent = !pageLabel && !(middleSegments && middleSegments.length > 0);
|
|
@@ -2224,7 +2178,12 @@ function Breadcrumbs(props) {
|
|
|
2224
2178
|
"data-testid": testId,
|
|
2225
2179
|
children: [
|
|
2226
2180
|
leading(resourceKey),
|
|
2227
|
-
resourceIsCurrent ? current(tid.navBreadcrumb(resourceKey), resourceLabel) : jsx(
|
|
2181
|
+
resourceIsCurrent ? current(tid.navBreadcrumb(resourceKey), resourceLabel) : !hasListPage(def) ? jsx("span", {
|
|
2182
|
+
"data-testid": tid.navBreadcrumb(resourceKey),
|
|
2183
|
+
className: "truncate",
|
|
2184
|
+
title: resourceLabel,
|
|
2185
|
+
children: resourceLabel
|
|
2186
|
+
}) : jsx(RouterLink, {
|
|
2228
2187
|
href: listHref,
|
|
2229
2188
|
"data-testid": tid.navBreadcrumb(resourceKey),
|
|
2230
2189
|
className: cn(LINK_CLASS, "truncate"),
|
|
@@ -2300,15 +2259,15 @@ function RecordBreadcrumbs() {
|
|
|
2300
2259
|
}
|
|
2301
2260
|
//#endregion
|
|
2302
2261
|
//#region src/layout/default-nav-layouts.ts
|
|
2303
|
-
const defaultNavLayouts = {
|
|
2304
|
-
[layoutSlot("secondary-sidebar")]: SecondarySidebarLayout,
|
|
2305
|
-
[layoutSlot("tabs")]: TabsLayout
|
|
2306
|
-
};
|
|
2262
|
+
const defaultNavLayouts = { ...BUILTIN_LAYOUTS };
|
|
2307
2263
|
//#endregion
|
|
2308
2264
|
//#region src/layout/context-picker.tsx
|
|
2309
|
-
|
|
2265
|
+
const ALL = "\0all";
|
|
2266
|
+
function ContextPicker({ sliceName, label, options, value, onChange, placeholder, disabled, className, hideLabel, allOption }) {
|
|
2310
2267
|
const tid = useTestIds();
|
|
2311
2268
|
const t = useOptionalT();
|
|
2269
|
+
const chromeT = useChromeT();
|
|
2270
|
+
const allLabel = typeof allOption === "string" ? allOption : chromeT("scope.all", { defaultValue: "All" });
|
|
2312
2271
|
const displayLabel = label ?? humanizeKey(sliceName);
|
|
2313
2272
|
return jsxs("div", {
|
|
2314
2273
|
className: cn("space-y-1", className),
|
|
@@ -2317,21 +2276,112 @@ function ContextPicker({ sliceName, label, options, value, onChange, placeholder
|
|
|
2317
2276
|
className: hideLabel ? "sr-only" : "text-xs font-medium text-muted-foreground uppercase tracking-wide",
|
|
2318
2277
|
children: displayLabel
|
|
2319
2278
|
}), jsxs(Select, {
|
|
2320
|
-
value: value ?? "",
|
|
2321
|
-
onValueChange:
|
|
2279
|
+
value: value ?? (allOption === void 0 ? "" : ALL),
|
|
2280
|
+
onValueChange: (next) => {
|
|
2281
|
+
if (allOption === void 0) onChange(next);
|
|
2282
|
+
else onChange(next === ALL ? null : next);
|
|
2283
|
+
},
|
|
2322
2284
|
disabled,
|
|
2323
2285
|
children: [jsx(SelectTrigger, {
|
|
2324
2286
|
id: `context-picker:${sliceName}`,
|
|
2325
2287
|
"data-testid": tid.contextPicker(sliceName),
|
|
2326
2288
|
className: cn("w-full", hideLabel ? "h-8 text-xs" : void 0),
|
|
2327
2289
|
children: jsx(SelectValue, { placeholder: placeholder ?? t("field.select", { defaultValue: "Select…" }) })
|
|
2328
|
-
}),
|
|
2290
|
+
}), jsxs(SelectContent, { children: [allOption === void 0 ? null : jsx(SelectItem, {
|
|
2291
|
+
value: ALL,
|
|
2292
|
+
"data-testid": tid.contextPickerOption(sliceName, "all"),
|
|
2293
|
+
children: allLabel
|
|
2294
|
+
}), options.map((o) => jsx(SelectItem, {
|
|
2329
2295
|
value: o.value,
|
|
2330
2296
|
"data-testid": tid.contextPickerOption(sliceName, o.value),
|
|
2331
2297
|
children: o.label
|
|
2332
|
-
}, o.value)) })]
|
|
2298
|
+
}, o.value))] })]
|
|
2299
|
+
})]
|
|
2300
|
+
});
|
|
2301
|
+
}
|
|
2302
|
+
//#endregion
|
|
2303
|
+
//#region src/layout/scope-dimension-picker.tsx
|
|
2304
|
+
function ScopeDimensionPicker(props) {
|
|
2305
|
+
const scope = useScope();
|
|
2306
|
+
const definition = scope.definition?.dimensions[props.dimension];
|
|
2307
|
+
if (definition === void 0) throw new Error(`ScopeDimensionPicker: '${props.dimension}' is not a dimension of the app's defineScope(...)`);
|
|
2308
|
+
if (definition.select === "none") return null;
|
|
2309
|
+
const source = definition.values;
|
|
2310
|
+
if (source === void 0) throw new Error(`ScopeDimensionPicker: dimension '${props.dimension}' declares no values; add values: { resource } or a { value, label } list`);
|
|
2311
|
+
const allowed = scope.access[props.dimension]?.allowed;
|
|
2312
|
+
const permitted = Array.isArray(allowed) ? allowed : void 0;
|
|
2313
|
+
const common = {
|
|
2314
|
+
...props,
|
|
2315
|
+
multiple: definition.select === "multiple",
|
|
2316
|
+
all: definition.all,
|
|
2317
|
+
selected: scope.selection[props.dimension] ?? null,
|
|
2318
|
+
select: (value) => scope.select(props.dimension, value)
|
|
2319
|
+
};
|
|
2320
|
+
if (Array.isArray(source)) {
|
|
2321
|
+
const options = source.filter((option) => permitted === void 0 || permitted.includes(option.value));
|
|
2322
|
+
return jsx(DimensionControl, {
|
|
2323
|
+
...common,
|
|
2324
|
+
options
|
|
2325
|
+
});
|
|
2326
|
+
}
|
|
2327
|
+
const { resource, label } = source;
|
|
2328
|
+
return jsx(ResourceDimension, {
|
|
2329
|
+
...common,
|
|
2330
|
+
resource,
|
|
2331
|
+
...label ? { labelField: label } : {}
|
|
2332
|
+
});
|
|
2333
|
+
}
|
|
2334
|
+
function ResourceDimension({ resource, labelField, ...rest }) {
|
|
2335
|
+
const options = useResourceDimensionOptions(rest.dimension, resource, labelField);
|
|
2336
|
+
return jsx(DimensionControl, {
|
|
2337
|
+
...rest,
|
|
2338
|
+
options
|
|
2339
|
+
});
|
|
2340
|
+
}
|
|
2341
|
+
function DimensionControl({ dimension, label, hideLabel, className, multiple, all, selected, select, options }) {
|
|
2342
|
+
const tid = useTestIds();
|
|
2343
|
+
const chromeT = useChromeT();
|
|
2344
|
+
const byText = useMemo(() => new Map(options.map((option) => [String(option.value), option.value])), [options]);
|
|
2345
|
+
const textOptions = useMemo(() => options.map((option) => ({
|
|
2346
|
+
value: String(option.value),
|
|
2347
|
+
label: option.label
|
|
2348
|
+
})), [options]);
|
|
2349
|
+
const picked = (Array.isArray(selected) ? selected : selected === null ? [] : [selected]).map(String);
|
|
2350
|
+
const text = label ?? humanizeKey(dimension);
|
|
2351
|
+
if (multiple) return jsxs("div", {
|
|
2352
|
+
className: cn("space-y-1", className),
|
|
2353
|
+
children: [jsx("span", {
|
|
2354
|
+
className: hideLabel ? "sr-only" : "text-xs font-medium text-muted-foreground uppercase tracking-wide",
|
|
2355
|
+
children: text
|
|
2356
|
+
}), jsx(FacetedFilterPicker, {
|
|
2357
|
+
title: text,
|
|
2358
|
+
options: textOptions,
|
|
2359
|
+
selected: picked,
|
|
2360
|
+
...all ? { emptyLabel: chromeT("scope.all", { defaultValue: "All" }) } : { clearable: false },
|
|
2361
|
+
onChange: (next) => {
|
|
2362
|
+
if (next.length === 0 && !all) return;
|
|
2363
|
+
select(next.length === 0 ? null : next.map((value) => byText.get(value) ?? value));
|
|
2364
|
+
},
|
|
2365
|
+
getTestId: (role, value) => role === "trigger" ? tid.contextPicker(dimension) : role === "option" ? tid.contextPickerOption(dimension, value ?? "") : role === "clear" ? tid.contextPickerOption(dimension, "all") : void 0
|
|
2333
2366
|
})]
|
|
2334
2367
|
});
|
|
2368
|
+
const common = {
|
|
2369
|
+
sliceName: dimension,
|
|
2370
|
+
...label === void 0 ? {} : { label },
|
|
2371
|
+
options: textOptions,
|
|
2372
|
+
value: picked[0] ?? null,
|
|
2373
|
+
...hideLabel === void 0 ? {} : { hideLabel },
|
|
2374
|
+
...className === void 0 ? {} : { className }
|
|
2375
|
+
};
|
|
2376
|
+
const choose = (value) => select(value === null ? null : byText.get(value) ?? value);
|
|
2377
|
+
return all ? jsx(ContextPicker, {
|
|
2378
|
+
...common,
|
|
2379
|
+
allOption: true,
|
|
2380
|
+
onChange: choose
|
|
2381
|
+
}) : jsx(ContextPicker, {
|
|
2382
|
+
...common,
|
|
2383
|
+
onChange: choose
|
|
2384
|
+
});
|
|
2335
2385
|
}
|
|
2336
2386
|
//#endregion
|
|
2337
2387
|
//#region src/layout/language-switch.tsx
|
|
@@ -2522,7 +2572,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
|
|
|
2522
2572
|
const navigate = useRouteNavigate();
|
|
2523
2573
|
const isVisible = useNavVisible();
|
|
2524
2574
|
const resolveLayout = useLayoutResolver();
|
|
2525
|
-
const isResourceVisible = (
|
|
2575
|
+
const isResourceVisible = useResourceVisible();
|
|
2526
2576
|
const pageAllowed = usePageAllowed();
|
|
2527
2577
|
const isPageVisible = (p) => evaluateVisible(p.visible, visibilityCtx) && pageAllowed(p);
|
|
2528
2578
|
const { topLevelResources, topLevelPages, sectionGroups } = useMemo(() => {
|
|
@@ -2550,13 +2600,13 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
|
|
|
2550
2600
|
onSelect?.();
|
|
2551
2601
|
navigate(href);
|
|
2552
2602
|
};
|
|
2553
|
-
const resourceLabel = (def) => resolveResourceLabel(caps, canonicalResourceKey(def), "plural", def);
|
|
2554
|
-
const pageLabel = (def) => resolveNavLabel(caps, `pages.${canonicalNavKey(def)}`, def
|
|
2603
|
+
const resourceLabel = (def) => resolveResourceLabel(caps, canonicalResourceKey$1(def), "plural", def);
|
|
2604
|
+
const pageLabel = (def) => resolveNavLabel(caps, `pages.${canonicalNavKey(def)}`, declaredText("chrome", def, "label"));
|
|
2555
2605
|
const groups = [];
|
|
2556
2606
|
if (topLevelResources.length > 0) groups.push(jsx(CommandGroup, {
|
|
2557
2607
|
heading: t("commandPalette.resources", { defaultValue: "Resources" }),
|
|
2558
2608
|
children: topLevelResources.map((def) => {
|
|
2559
|
-
const resource = canonicalResourceKey(def);
|
|
2609
|
+
const resource = canonicalResourceKey$1(def);
|
|
2560
2610
|
const label = resourceLabel(def);
|
|
2561
2611
|
const href = hrefFor(app.registry, resource, { isVisible });
|
|
2562
2612
|
return jsx(CommandItem, {
|
|
@@ -2583,7 +2633,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
|
|
|
2583
2633
|
}, "pages"));
|
|
2584
2634
|
for (const { section, children } of sectionGroups) {
|
|
2585
2635
|
const sectionKey = canonicalNavKey(section);
|
|
2586
|
-
const sectionLabel = resolveNavLabel(caps, `sections.${sectionKey}`, section
|
|
2636
|
+
const sectionLabel = resolveNavLabel(caps, `sections.${sectionKey}`, declaredText("chrome", section, "label"));
|
|
2587
2637
|
groups.push(jsxs(CommandGroup, {
|
|
2588
2638
|
heading: sectionLabel,
|
|
2589
2639
|
children: [jsx(CommandItem, {
|
|
@@ -2605,7 +2655,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
|
|
|
2605
2655
|
children: label
|
|
2606
2656
|
}, `section:${sectionKey}:page:${pageKey}`);
|
|
2607
2657
|
}
|
|
2608
|
-
const resource = canonicalResourceKey(child);
|
|
2658
|
+
const resource = canonicalResourceKey$1(child);
|
|
2609
2659
|
const label = resourceLabel(child);
|
|
2610
2660
|
const href = hrefFor(app.registry, resource, { isVisible });
|
|
2611
2661
|
return jsx(CommandItem, {
|
|
@@ -2622,7 +2672,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
|
|
|
2622
2672
|
const items = [];
|
|
2623
2673
|
if (!!resolveLayout(group.layout)) {
|
|
2624
2674
|
const groupKey = canonicalNavKey(group);
|
|
2625
|
-
const label = resolveNavLabel(caps, `groups.${groupKey}`, group
|
|
2675
|
+
const label = resolveNavLabel(caps, `groups.${groupKey}`, declaredText("chrome", group, "label"));
|
|
2626
2676
|
const href = navHrefFor(app.registry, groupKey, { isVisible });
|
|
2627
2677
|
items.push(jsx(CommandItem, {
|
|
2628
2678
|
value: `group:${idPath}:${label}`,
|
|
@@ -2657,7 +2707,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
|
|
|
2657
2707
|
const resource = child;
|
|
2658
2708
|
if (!hasListPage(resource)) continue;
|
|
2659
2709
|
if (!isResourceVisible(resource)) continue;
|
|
2660
|
-
const resourceId = canonicalResourceKey(resource);
|
|
2710
|
+
const resourceId = canonicalResourceKey$1(resource);
|
|
2661
2711
|
const label = resourceLabel(resource);
|
|
2662
2712
|
const href = hrefFor(app.registry, resourceId, { isVisible });
|
|
2663
2713
|
items.push(jsx(CommandItem, {
|
|
@@ -2676,7 +2726,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
|
|
|
2676
2726
|
const groupKey = canonicalNavKey(group);
|
|
2677
2727
|
const items = collectGroupItems(group, groupKey, 0);
|
|
2678
2728
|
if (items.length === 0) continue;
|
|
2679
|
-
const heading = resolveNavLabel(caps, `groups.${groupKey}`, group
|
|
2729
|
+
const heading = resolveNavLabel(caps, `groups.${groupKey}`, declaredText("chrome", group, "label"));
|
|
2680
2730
|
groups.push(jsx(CommandGroup, {
|
|
2681
2731
|
heading,
|
|
2682
2732
|
children: items
|
|
@@ -2696,10 +2746,10 @@ function opensInQuick(registry, resource, mode) {
|
|
|
2696
2746
|
}
|
|
2697
2747
|
//#endregion
|
|
2698
2748
|
//#region src/layout/command-palette-recent-group.tsx
|
|
2699
|
-
function entryHref(registry, entry,
|
|
2749
|
+
function entryHref(registry, entry, isResourceVisible) {
|
|
2700
2750
|
const def = registry.get(entry.canonicalRef);
|
|
2701
2751
|
if (def === void 0) return void 0;
|
|
2702
|
-
if (!
|
|
2752
|
+
if (!isResourceVisible(def)) return void 0;
|
|
2703
2753
|
for (const action of ["show", "edit"]) if (recordRouteAvailable(registry, entry.canonicalRef, action)) return hrefFor(registry, entry.canonicalRef, {
|
|
2704
2754
|
action,
|
|
2705
2755
|
id: entry.id
|
|
@@ -2713,27 +2763,39 @@ function CommandPaletteRecentGroup({ onSelect, getTestId, heading, refreshKey, w
|
|
|
2713
2763
|
const navigate = useRouteNavigate();
|
|
2714
2764
|
const quick = useQuick();
|
|
2715
2765
|
const userId = useCurrentUserId();
|
|
2716
|
-
const
|
|
2766
|
+
const isResourceVisible = useResourceVisible();
|
|
2717
2767
|
const resolvedHeading = heading ?? t("commandPalette.recent", { defaultValue: "Recent" });
|
|
2718
|
-
const
|
|
2768
|
+
const store = usePlatformStorage().local;
|
|
2769
|
+
const [stored, setStored] = useState([]);
|
|
2719
2770
|
useEffect(() => {
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2771
|
+
if (userId === null) {
|
|
2772
|
+
setStored([]);
|
|
2773
|
+
return;
|
|
2774
|
+
}
|
|
2775
|
+
let current = true;
|
|
2776
|
+
const read = readRecentRecords(store, userId);
|
|
2777
|
+
if (Array.isArray(read)) setStored(read);
|
|
2778
|
+
else read.then((entries) => {
|
|
2779
|
+
if (current) setStored(entries);
|
|
2780
|
+
}, () => void 0);
|
|
2781
|
+
return () => {
|
|
2782
|
+
current = false;
|
|
2783
|
+
};
|
|
2731
2784
|
}, [
|
|
2732
|
-
|
|
2785
|
+
store,
|
|
2733
2786
|
userId,
|
|
2734
|
-
refreshKey
|
|
2787
|
+
refreshKey
|
|
2788
|
+
]);
|
|
2789
|
+
const recents = useMemo(() => stored.flatMap((entry) => {
|
|
2790
|
+
const href = entryHref(app.registry, entry, isResourceVisible);
|
|
2791
|
+
return href === void 0 ? [] : [{
|
|
2792
|
+
entry,
|
|
2793
|
+
href
|
|
2794
|
+
}];
|
|
2795
|
+
}), [
|
|
2796
|
+
stored,
|
|
2735
2797
|
app.registry,
|
|
2736
|
-
|
|
2798
|
+
isResourceVisible
|
|
2737
2799
|
]);
|
|
2738
2800
|
if ((useCommandState((state) => state.search) ?? "").length > 0) return null;
|
|
2739
2801
|
if (recents.length === 0) return null;
|
|
@@ -2798,18 +2860,19 @@ function CommandPaletteRecordsGroup({ enabled = true, pageSize = 5, minQueryLeng
|
|
|
2798
2860
|
const t = useOptionalT();
|
|
2799
2861
|
const navigate = useRouteNavigate();
|
|
2800
2862
|
const quick = useQuick();
|
|
2863
|
+
const isResourceVisible = useResourceVisible();
|
|
2801
2864
|
const resolvedHeading = heading ?? t("commandPalette.records", { defaultValue: "Records" });
|
|
2802
2865
|
const liveQuery = useCommandState((state) => state.search) ?? "";
|
|
2803
2866
|
const debouncedQuery = useDebouncedValue(liveQuery, debounceMs);
|
|
2804
2867
|
const searchableResources = useMemo(() => {
|
|
2805
|
-
return app.registry.list().filter((r) => isShowAvailable(app.registry, canonicalResourceKey(r)) || opensInQuick(app.registry, canonicalResourceKey(r), "show")).map((def) => {
|
|
2868
|
+
return app.registry.list().filter((r) => isShowAvailable(app.registry, canonicalResourceKey$1(r)) || opensInQuick(app.registry, canonicalResourceKey$1(r), "show")).filter(isResourceVisible).map((def) => {
|
|
2806
2869
|
const displayField = resolveDisplayField(def);
|
|
2807
2870
|
return displayField ? {
|
|
2808
2871
|
def,
|
|
2809
2872
|
displayField
|
|
2810
2873
|
} : null;
|
|
2811
2874
|
}).filter((entry) => entry !== null);
|
|
2812
|
-
}, [app.registry]);
|
|
2875
|
+
}, [app.registry, isResourceVisible]);
|
|
2813
2876
|
if (!(enabled && debouncedQuery.length >= minQueryLength && searchableResources.length > 0)) return null;
|
|
2814
2877
|
const goTo = (href, resource, id) => {
|
|
2815
2878
|
onSelect?.();
|
|
@@ -2828,12 +2891,12 @@ function CommandPaletteRecordsGroup({ enabled = true, pageSize = 5, minQueryLeng
|
|
|
2828
2891
|
recordHref,
|
|
2829
2892
|
registry: app.registry,
|
|
2830
2893
|
getTestId
|
|
2831
|
-
}, canonicalResourceKey(def)))
|
|
2894
|
+
}, canonicalResourceKey$1(def)))
|
|
2832
2895
|
}, "records");
|
|
2833
2896
|
}
|
|
2834
2897
|
function PerResourceSearchHits({ def, displayField, query, pageSize, goTo, recordHref, registry, getTestId }) {
|
|
2835
2898
|
const caps = useI18nCaps();
|
|
2836
|
-
const resource = canonicalResourceKey(def);
|
|
2899
|
+
const resource = canonicalResourceKey$1(def);
|
|
2837
2900
|
const access = useListAccess(resource);
|
|
2838
2901
|
const titleVisible = access.status === "ready" && access.fieldVisible(displayField);
|
|
2839
2902
|
const shouldFetch = query.length > 0 && titleVisible;
|
|
@@ -2848,6 +2911,7 @@ function PerResourceSearchHits({ def, displayField, query, pageSize, goTo, recor
|
|
|
2848
2911
|
page: 1,
|
|
2849
2912
|
pageSize
|
|
2850
2913
|
},
|
|
2914
|
+
scope: "session",
|
|
2851
2915
|
enabled: shouldFetch
|
|
2852
2916
|
});
|
|
2853
2917
|
const report = useCommandPaletteResults(`records:${resource}`);
|
|
@@ -2856,9 +2920,11 @@ function PerResourceSearchHits({ def, displayField, query, pageSize, goTo, recor
|
|
|
2856
2920
|
report(rows.length);
|
|
2857
2921
|
}, [report, rows.length]);
|
|
2858
2922
|
if (rows.length === 0) return null;
|
|
2859
|
-
const resourceLabel = resolveResourceLabel(caps, canonicalResourceKey(def), "single", def);
|
|
2923
|
+
const resourceLabel = resolveResourceLabel(caps, canonicalResourceKey$1(def), "single", def);
|
|
2924
|
+
const declaredIdField = def.data?.idField;
|
|
2925
|
+
const idField = typeof declaredIdField === "string" && declaredIdField.length > 0 ? declaredIdField : "id";
|
|
2860
2926
|
return jsx(Fragment$1, { children: rows.map((row) => {
|
|
2861
|
-
const idVal = row.id ?? row.event_id ?? row.job_id;
|
|
2927
|
+
const idVal = row[idField] ?? row.id ?? row.event_id ?? row.job_id;
|
|
2862
2928
|
const id = idVal == null ? "" : String(idVal);
|
|
2863
2929
|
if (!id) return null;
|
|
2864
2930
|
const display = titleVisible ? row[displayField] : void 0;
|
|
@@ -3003,7 +3069,7 @@ function CommandPaletteActionsGroup({ actions, onSelect, getTestId, heading }) {
|
|
|
3003
3069
|
function CommandPaletteCreateGroup({ resourceFilter, onSelect, getTestId, heading, createHref, prefix }) {
|
|
3004
3070
|
const caps = useI18nCaps();
|
|
3005
3071
|
const app = useApp();
|
|
3006
|
-
const
|
|
3072
|
+
const isResourceVisible = useResourceVisible();
|
|
3007
3073
|
const gate = useAvailabilityGate();
|
|
3008
3074
|
const t = useOptionalT();
|
|
3009
3075
|
const navigate = useRouteNavigate();
|
|
@@ -3011,11 +3077,11 @@ function CommandPaletteCreateGroup({ resourceFilter, onSelect, getTestId, headin
|
|
|
3011
3077
|
const resolvedHeading = heading ?? t("commandPalette.create", { defaultValue: "Create" });
|
|
3012
3078
|
const resolvedPrefix = prefix ?? t("commandPalette.createNew", { defaultValue: "Create new" });
|
|
3013
3079
|
const visibleResources = useMemo(() => {
|
|
3014
|
-
return app.registry.list().filter((r) => hasListPage(r)).filter((r) => gate(canonicalResourceKey(r), "create").state === "available").filter((r) => hasRecordPage(r, "create") || opensInQuick(app.registry, canonicalResourceKey(r), "create")).filter(
|
|
3080
|
+
return app.registry.list().filter((r) => hasListPage(r)).filter((r) => gate(canonicalResourceKey$1(r), "create").state === "available").filter((r) => hasRecordPage(r, "create") || opensInQuick(app.registry, canonicalResourceKey$1(r), "create")).filter(isResourceVisible).filter((r) => resourceFilter ? resourceFilter(r) : true);
|
|
3015
3081
|
}, [
|
|
3016
3082
|
app,
|
|
3017
3083
|
gate,
|
|
3018
|
-
|
|
3084
|
+
isResourceVisible,
|
|
3019
3085
|
resourceFilter
|
|
3020
3086
|
]);
|
|
3021
3087
|
if (visibleResources.length === 0) return null;
|
|
@@ -3029,13 +3095,13 @@ function CommandPaletteCreateGroup({ resourceFilter, onSelect, getTestId, headin
|
|
|
3029
3095
|
return;
|
|
3030
3096
|
}
|
|
3031
3097
|
onSelect?.();
|
|
3032
|
-
quick.create(canonicalResourceKey(def));
|
|
3098
|
+
quick.create(canonicalResourceKey$1(def));
|
|
3033
3099
|
};
|
|
3034
|
-
const resourceLabel = (def) => resolveResourceLabel(caps, canonicalResourceKey(def), "single", def);
|
|
3100
|
+
const resourceLabel = (def) => resolveResourceLabel(caps, canonicalResourceKey$1(def), "single", def);
|
|
3035
3101
|
return jsx(CommandGroup, {
|
|
3036
3102
|
heading: resolvedHeading,
|
|
3037
3103
|
children: visibleResources.map((def) => {
|
|
3038
|
-
const resource = canonicalResourceKey(def);
|
|
3104
|
+
const resource = canonicalResourceKey$1(def);
|
|
3039
3105
|
const label = resourceLabel(def);
|
|
3040
3106
|
const href = createHref?.(def) ?? resourceCreateHref(app.registry, def, resource);
|
|
3041
3107
|
const value = `create:${resource}:${resolvedPrefix}:${label}`;
|
|
@@ -3097,7 +3163,7 @@ function AppActions() {
|
|
|
3097
3163
|
variant: "outline",
|
|
3098
3164
|
size: "sm",
|
|
3099
3165
|
disabled: action.disabledReason !== void 0,
|
|
3100
|
-
title: action.disabledReason,
|
|
3166
|
+
title: action.disabledReason === void 0 ? void 0 : reasonText(caps, action.disabledReason),
|
|
3101
3167
|
"data-testid": `app-action:${action.name}`,
|
|
3102
3168
|
children: action.disabledReason === void 0 ? jsx(RouterLink, {
|
|
3103
3169
|
href,
|
|
@@ -3219,7 +3285,7 @@ function localizedSchema(t) {
|
|
|
3219
3285
|
function LoginForm({ onSubmit, title, description, className }) {
|
|
3220
3286
|
const tid = useTestIds();
|
|
3221
3287
|
const t = useOptionalT();
|
|
3222
|
-
const
|
|
3288
|
+
const caps = useI18nCaps();
|
|
3223
3289
|
const resolvedTitle = title ?? t("auth.signIn", { defaultValue: "Sign in" });
|
|
3224
3290
|
const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm({
|
|
3225
3291
|
resolver: zodResolver(localizedSchema(t)),
|
|
@@ -3234,9 +3300,11 @@ function LoginForm({ onSubmit, title, description, className }) {
|
|
|
3234
3300
|
try {
|
|
3235
3301
|
await onSubmit(values);
|
|
3236
3302
|
} catch (e) {
|
|
3237
|
-
const
|
|
3238
|
-
const
|
|
3239
|
-
|
|
3303
|
+
const dataCode = e !== null && typeof e === "object" && !(e instanceof Error) ? e.code : void 0;
|
|
3304
|
+
const raw = e instanceof Error ? e.message : technicalText(e) ?? (dataCode === void 0 ? String(e) : "");
|
|
3305
|
+
const friendly = toFriendlyError(raw, "", friendlyStringsFrom(t));
|
|
3306
|
+
const credentials = credentialsMessage(raw, t);
|
|
3307
|
+
setSubmitError(friendly.replaced ? `${friendly.title}. ${friendly.detail}` : typeof dataCode === "string" && credentials === raw ? resolveErrorText(e, caps) : credentials);
|
|
3240
3308
|
}
|
|
3241
3309
|
});
|
|
3242
3310
|
return jsxs(Card, {
|
|
@@ -3361,9 +3429,108 @@ function AuthPage({ children, brand, footer, className }) {
|
|
|
3361
3429
|
});
|
|
3362
3430
|
}
|
|
3363
3431
|
//#endregion
|
|
3432
|
+
//#region src/enum/enum-choice-group.tsx
|
|
3433
|
+
const NONE = "__none__";
|
|
3434
|
+
function isEmpty$1(value) {
|
|
3435
|
+
return value === null || value === void 0 || value === "";
|
|
3436
|
+
}
|
|
3437
|
+
function EnumChoiceGroup({ control, options, value, onChange, testid, name, id, required, disabled, ariaInvalid, ariaDescribedBy, ariaErrorMessage, ariaLabelledBy, className }) {
|
|
3438
|
+
const t = useOptionalT();
|
|
3439
|
+
const generatedName = React.useId();
|
|
3440
|
+
const groupName = name ?? generatedName;
|
|
3441
|
+
const empty = isEmpty$1(value);
|
|
3442
|
+
const noneLabel = t("field.none", { defaultValue: "None" });
|
|
3443
|
+
const pick = (next) => {
|
|
3444
|
+
if (!disabled) onChange(next);
|
|
3445
|
+
};
|
|
3446
|
+
const ariaProps = {
|
|
3447
|
+
"aria-invalid": ariaInvalid || void 0,
|
|
3448
|
+
"aria-describedby": ariaDescribedBy,
|
|
3449
|
+
...ariaErrorMessage ? { "aria-errormessage": ariaErrorMessage } : {}
|
|
3450
|
+
};
|
|
3451
|
+
if (control === "segmented") {
|
|
3452
|
+
const segment = (key, label, active, select) => jsx("button", {
|
|
3453
|
+
type: "button",
|
|
3454
|
+
"aria-pressed": active,
|
|
3455
|
+
"data-state": active ? "active" : "inactive",
|
|
3456
|
+
"data-testid": `${testid}:option:${key}`,
|
|
3457
|
+
disabled,
|
|
3458
|
+
onClick: select,
|
|
3459
|
+
className: cn("inline-flex items-center justify-center gap-1.5 whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all", "data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-xs", "disabled:pointer-events-none disabled:opacity-50", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring"),
|
|
3460
|
+
children: label
|
|
3461
|
+
}, key);
|
|
3462
|
+
return jsxs("div", {
|
|
3463
|
+
role: "group",
|
|
3464
|
+
id,
|
|
3465
|
+
"aria-labelledby": ariaLabelledBy,
|
|
3466
|
+
"data-testid": testid,
|
|
3467
|
+
className: cn("inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground", className),
|
|
3468
|
+
...ariaProps,
|
|
3469
|
+
children: [required ? null : segment(NONE, noneLabel, empty, () => pick(void 0)), options.map((option) => segment(option.value, jsxs(Fragment$1, { children: [option.icon ? jsx("span", {
|
|
3470
|
+
"data-testid": `${testid}:option:${option.value}:icon`,
|
|
3471
|
+
className: "contents",
|
|
3472
|
+
children: jsx(Icon, {
|
|
3473
|
+
name: option.icon,
|
|
3474
|
+
className: "size-3.5 shrink-0"
|
|
3475
|
+
})
|
|
3476
|
+
}) : null, option.label] }), value === option.value, () => pick(option.value)))]
|
|
3477
|
+
});
|
|
3478
|
+
}
|
|
3479
|
+
const cards = control === "cards";
|
|
3480
|
+
const choice = (key, option, label, checked, select) => {
|
|
3481
|
+
const inputId = `${id ?? groupName}:${key}`;
|
|
3482
|
+
return jsxs("label", {
|
|
3483
|
+
htmlFor: inputId,
|
|
3484
|
+
className: cn("flex items-start gap-2.5", cards && "cursor-pointer rounded-lg border px-3 py-2.5 transition-colors hover:bg-accent/50 has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-ring", cards && (checked ? "border-primary" : "border-input"), disabled && "cursor-not-allowed opacity-60"),
|
|
3485
|
+
children: [jsx("input", {
|
|
3486
|
+
type: "radio",
|
|
3487
|
+
id: inputId,
|
|
3488
|
+
name: groupName,
|
|
3489
|
+
value: key,
|
|
3490
|
+
checked,
|
|
3491
|
+
onChange: select,
|
|
3492
|
+
disabled,
|
|
3493
|
+
...ariaProps,
|
|
3494
|
+
"data-testid": `${testid}:option:${key}`,
|
|
3495
|
+
className: cn("h-4 w-4 shrink-0 accent-primary", cards ? "mt-0.5" : "mt-1")
|
|
3496
|
+
}), jsxs("span", {
|
|
3497
|
+
className: "flex min-w-0 flex-col gap-0.5",
|
|
3498
|
+
children: [jsxs("span", {
|
|
3499
|
+
className: cn("flex items-center gap-1.5", cards && "font-medium"),
|
|
3500
|
+
children: [option?.icon ? jsx("span", {
|
|
3501
|
+
"data-testid": `${testid}:option:${key}:icon`,
|
|
3502
|
+
className: "contents",
|
|
3503
|
+
children: jsx(Icon, {
|
|
3504
|
+
name: option.icon,
|
|
3505
|
+
className: "size-4 shrink-0"
|
|
3506
|
+
})
|
|
3507
|
+
}) : null, jsx("span", { children: label })]
|
|
3508
|
+
}), option?.summary === void 0 || option.summary === "" ? null : jsx("span", {
|
|
3509
|
+
"data-testid": `${testid}:option:${key}:doc`,
|
|
3510
|
+
className: "text-sm text-muted-foreground",
|
|
3511
|
+
children: option.summary
|
|
3512
|
+
})]
|
|
3513
|
+
})]
|
|
3514
|
+
}, key);
|
|
3515
|
+
};
|
|
3516
|
+
return jsxs("div", {
|
|
3517
|
+
role: "radiogroup",
|
|
3518
|
+
id,
|
|
3519
|
+
"aria-labelledby": ariaLabelledBy,
|
|
3520
|
+
"data-testid": testid,
|
|
3521
|
+
"aria-required": required,
|
|
3522
|
+
className: cn("flex flex-col", cards ? "gap-2" : "gap-1.5", className),
|
|
3523
|
+
children: [required ? null : choice(NONE, void 0, noneLabel, empty, () => pick(void 0)), options.map((option) => choice(option.value, option, option.label, value === option.value, () => pick(option.value)))]
|
|
3524
|
+
});
|
|
3525
|
+
}
|
|
3526
|
+
//#endregion
|
|
3364
3527
|
//#region src/enum/enum-picker.tsx
|
|
3365
3528
|
const ENUM_PICKER_CLEAR_SENTINEL = "__buro_clear__";
|
|
3366
|
-
function
|
|
3529
|
+
function withSummary(summary) {
|
|
3530
|
+
return summary === void 0 ? {} : { summary };
|
|
3531
|
+
}
|
|
3532
|
+
function EnumPicker({ enumName: enumInput, value, onChange, control = "select", name, id, testid, placeholder, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage, ariaLabelledBy, className, clearable = false, clearLabel = "All" }) {
|
|
3533
|
+
const enumName = enumBindingKey(enumInput) ?? "";
|
|
3367
3534
|
const app = useApp();
|
|
3368
3535
|
const t = useOptionalT();
|
|
3369
3536
|
const def = app.registry.enums.get(enumName);
|
|
@@ -3394,63 +3561,43 @@ function EnumPicker({ enumName, value, onChange, renderAs = "select", name, id,
|
|
|
3394
3561
|
children: jsx(SelectValue, { placeholder: t("field.loading", { defaultValue: "Loading…" }) })
|
|
3395
3562
|
}), jsx(SelectContent, {})]
|
|
3396
3563
|
});
|
|
3397
|
-
if (error || !values) return jsxs(
|
|
3398
|
-
"
|
|
3564
|
+
if (error || !values) return jsxs(LoadError, {
|
|
3565
|
+
surface: "picker",
|
|
3566
|
+
error,
|
|
3567
|
+
testId: `${tid}:error`,
|
|
3399
3568
|
className: "text-muted-foreground",
|
|
3400
|
-
|
|
3569
|
+
fallback: {
|
|
3570
|
+
key: "relation.failed",
|
|
3571
|
+
default: "Failed to load options."
|
|
3572
|
+
},
|
|
3401
3573
|
children: [
|
|
3402
3574
|
"(failed to load enum ‘",
|
|
3403
3575
|
enumName,
|
|
3404
3576
|
"’)"
|
|
3405
3577
|
]
|
|
3406
3578
|
});
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
className: "h-4 w-4"
|
|
3430
|
-
}), jsx("span", { children: resolveEnumLabel(caps, ns, entry.value, entry.label) })]
|
|
3431
|
-
}, entry.value);
|
|
3432
|
-
})
|
|
3433
|
-
});
|
|
3434
|
-
if (renderAs === "segmented") return jsx("div", {
|
|
3435
|
-
role: "group",
|
|
3436
|
-
"data-testid": tid,
|
|
3437
|
-
className: cn("inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground", className),
|
|
3438
|
-
"aria-invalid": ariaInvalid || void 0,
|
|
3439
|
-
"aria-describedby": ariaDescribedBy,
|
|
3440
|
-
...ariaErrorMessage ? { "aria-errormessage": ariaErrorMessage } : {},
|
|
3441
|
-
children: values.map((entry) => {
|
|
3442
|
-
const isActive = value === entry.value;
|
|
3443
|
-
return jsx("button", {
|
|
3444
|
-
type: "button",
|
|
3445
|
-
"aria-pressed": isActive,
|
|
3446
|
-
"data-state": isActive ? "active" : "inactive",
|
|
3447
|
-
"data-testid": `${tid}:option:${entry.value}`,
|
|
3448
|
-
disabled,
|
|
3449
|
-
onClick: () => onChange(entry.value),
|
|
3450
|
-
className: cn("inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all", "data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-xs", "disabled:pointer-events-none disabled:opacity-50", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring"),
|
|
3451
|
-
children: resolveEnumLabel(caps, ns, entry.value, entry.label)
|
|
3452
|
-
}, entry.value);
|
|
3453
|
-
})
|
|
3579
|
+
const labelOf = (entry) => resolveEnumLabel(caps, ns, entry.value, enumValueText(def, entry.value) ?? entry.label);
|
|
3580
|
+
const summaryOf = (entry) => resolveDoc(caps, `enum/${ns}/${entry.value}`)?.summary || void 0;
|
|
3581
|
+
if (control !== "select") return jsx(EnumChoiceGroup, {
|
|
3582
|
+
control,
|
|
3583
|
+
options: values.map((entry) => ({
|
|
3584
|
+
value: entry.value,
|
|
3585
|
+
label: labelOf(entry),
|
|
3586
|
+
...entry.icon === void 0 ? {} : { icon: entry.icon },
|
|
3587
|
+
...withSummary(summaryOf(entry))
|
|
3588
|
+
})),
|
|
3589
|
+
value,
|
|
3590
|
+
onChange,
|
|
3591
|
+
testid: tid,
|
|
3592
|
+
name,
|
|
3593
|
+
id,
|
|
3594
|
+
required,
|
|
3595
|
+
disabled,
|
|
3596
|
+
ariaInvalid,
|
|
3597
|
+
ariaDescribedBy,
|
|
3598
|
+
ariaErrorMessage,
|
|
3599
|
+
ariaLabelledBy,
|
|
3600
|
+
className
|
|
3454
3601
|
});
|
|
3455
3602
|
const selectValue = value == null ? clearable ? ENUM_PICKER_CLEAR_SENTINEL : "" : value;
|
|
3456
3603
|
const handleValueChange = (next) => {
|
|
@@ -3480,36 +3627,49 @@ function EnumPicker({ enumName, value, onChange, renderAs = "select", name, id,
|
|
|
3480
3627
|
"data-testid": `${tid}:option:__clear__`,
|
|
3481
3628
|
children: clearLabel
|
|
3482
3629
|
}), values.map((entry) => {
|
|
3483
|
-
const optionLabel =
|
|
3484
|
-
const optionDoc =
|
|
3630
|
+
const optionLabel = labelOf(entry);
|
|
3631
|
+
const optionDoc = summaryOf(entry);
|
|
3485
3632
|
return jsx(SelectItem, {
|
|
3486
3633
|
value: entry.value,
|
|
3487
3634
|
"data-testid": `${tid}:option:${entry.value}`,
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
children:
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
children: optionDoc
|
|
3494
|
-
})]
|
|
3495
|
-
})
|
|
3635
|
+
description: optionDoc === void 0 ? void 0 : jsx("span", {
|
|
3636
|
+
"data-testid": `${tid}:option:${entry.value}:doc`,
|
|
3637
|
+
children: optionDoc
|
|
3638
|
+
}),
|
|
3639
|
+
children: optionLabel
|
|
3496
3640
|
}, entry.value);
|
|
3497
3641
|
})] })]
|
|
3498
3642
|
});
|
|
3499
3643
|
}
|
|
3500
3644
|
//#endregion
|
|
3645
|
+
//#region src/enum/resolve-enum-control.ts
|
|
3646
|
+
const warned = new Set();
|
|
3647
|
+
function resolveEnumControl(fieldControl, enumDef, where) {
|
|
3648
|
+
if (isEnumControl(fieldControl)) return fieldControl;
|
|
3649
|
+
if (fieldControl !== void 0) {
|
|
3650
|
+
const shown = typeof fieldControl === "string" ? `'${fieldControl}'` : String(fieldControl);
|
|
3651
|
+
const key = `${where}\u0000${shown}`;
|
|
3652
|
+
if (!warned.has(key)) {
|
|
3653
|
+
warned.add(key);
|
|
3654
|
+
console.warn(`[buro/ui-shadcn] ${where}: unknown enum control ${shown}; expected one of ${ENUM_CONTROLS.map((control) => `'${control}'`).join(", ")}. Using the enum's control, else 'select'.`);
|
|
3655
|
+
}
|
|
3656
|
+
}
|
|
3657
|
+
return enumDef?.control ?? "select";
|
|
3658
|
+
}
|
|
3659
|
+
//#endregion
|
|
3501
3660
|
//#region src/forms/issue-severity.ts
|
|
3502
3661
|
function isErrorIssue(issue) {
|
|
3503
3662
|
return issue.severity === "error";
|
|
3504
3663
|
}
|
|
3505
3664
|
//#endregion
|
|
3506
3665
|
//#region src/fields/boolean.tsx
|
|
3507
|
-
function BooleanDisplay({ value }) {
|
|
3666
|
+
function BooleanDisplay({ value, text }) {
|
|
3508
3667
|
const t = useOptionalT();
|
|
3509
3668
|
if (value == null) return jsx("span", {
|
|
3510
3669
|
className: "text-muted-foreground",
|
|
3511
3670
|
children: "—"
|
|
3512
3671
|
});
|
|
3672
|
+
if (text !== void 0) return jsx("span", { children: text });
|
|
3513
3673
|
return jsx("span", { children: value ? t("boolean.yes", { defaultValue: "Yes" }) : t("boolean.no", { defaultValue: "No" }) });
|
|
3514
3674
|
}
|
|
3515
3675
|
function BooleanInput({ name, id, value, onChange, testid, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage }) {
|
|
@@ -3528,17 +3688,32 @@ function BooleanInput({ name, id, value, onChange, testid, disabled, required, a
|
|
|
3528
3688
|
}
|
|
3529
3689
|
//#endregion
|
|
3530
3690
|
//#region src/fields/date.tsx
|
|
3531
|
-
function DateDisplay({ value }) {
|
|
3691
|
+
function DateDisplay({ value, text }) {
|
|
3692
|
+
return jsx(TemporalDisplay, {
|
|
3693
|
+
value,
|
|
3694
|
+
text,
|
|
3695
|
+
format: formatDate
|
|
3696
|
+
});
|
|
3697
|
+
}
|
|
3698
|
+
function DateTimeDisplay({ value, text }) {
|
|
3699
|
+
return jsx(TemporalDisplay, {
|
|
3700
|
+
value,
|
|
3701
|
+
text,
|
|
3702
|
+
format: formatDateTime
|
|
3703
|
+
});
|
|
3704
|
+
}
|
|
3705
|
+
function TemporalDisplay({ value, text, format }) {
|
|
3532
3706
|
const locale = useOptionalLocale();
|
|
3533
3707
|
if (value == null || value === "") return jsx("span", {
|
|
3534
3708
|
className: "text-muted-foreground",
|
|
3535
3709
|
children: "—"
|
|
3536
3710
|
});
|
|
3711
|
+
if (text !== void 0) return jsx("span", { children: text });
|
|
3537
3712
|
const d = new Date(String(value));
|
|
3538
3713
|
if (Number.isNaN(d.getTime())) return jsx("span", { children: String(value) });
|
|
3539
3714
|
return jsx("span", {
|
|
3540
3715
|
className: "whitespace-nowrap",
|
|
3541
|
-
children:
|
|
3716
|
+
children: format(d, locale)
|
|
3542
3717
|
});
|
|
3543
3718
|
}
|
|
3544
3719
|
function toIsoDate(v) {
|
|
@@ -3549,13 +3724,29 @@ function toIsoDate(v) {
|
|
|
3549
3724
|
if (Number.isNaN(d.getTime())) return "";
|
|
3550
3725
|
return d.toISOString().slice(0, 10);
|
|
3551
3726
|
}
|
|
3552
|
-
function DateInput(
|
|
3727
|
+
function DateInput(props) {
|
|
3728
|
+
return jsx(TemporalInput, {
|
|
3729
|
+
...props,
|
|
3730
|
+
type: "date",
|
|
3731
|
+
toText: toIsoDate,
|
|
3732
|
+
fromText: (text) => text || null
|
|
3733
|
+
});
|
|
3734
|
+
}
|
|
3735
|
+
function DateTimeInput(props) {
|
|
3736
|
+
return jsx(TemporalInput, {
|
|
3737
|
+
...props,
|
|
3738
|
+
type: "datetime-local",
|
|
3739
|
+
toText: toLocalDateTimeText,
|
|
3740
|
+
fromText: (text) => fromLocalDateTimeText(text) ?? null
|
|
3741
|
+
});
|
|
3742
|
+
}
|
|
3743
|
+
function TemporalInput({ type, toText, fromText, name, id, value, onChange, testid, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage }) {
|
|
3553
3744
|
return jsx(Input, {
|
|
3554
3745
|
name,
|
|
3555
3746
|
id,
|
|
3556
|
-
type
|
|
3557
|
-
value:
|
|
3558
|
-
onChange: (e) => onChange(e.target.value
|
|
3747
|
+
type,
|
|
3748
|
+
value: toText(value),
|
|
3749
|
+
onChange: (e) => onChange(fromText(e.target.value)),
|
|
3559
3750
|
"data-testid": testid,
|
|
3560
3751
|
disabled,
|
|
3561
3752
|
required,
|
|
@@ -3567,23 +3758,15 @@ function DateInput({ name, id, value, onChange, testid, disabled, required, aria
|
|
|
3567
3758
|
}
|
|
3568
3759
|
//#endregion
|
|
3569
3760
|
//#region src/fields/enum.tsx
|
|
3570
|
-
function optionLabel(caps, field, value, inline) {
|
|
3571
|
-
const ns = enumNamespaceOf(field);
|
|
3572
|
-
if (ns) return resolveEnumLabel(caps, ns, value, inline);
|
|
3573
|
-
return field ? resolveContentSlot(caps, [fieldOptionKey(field.name, value)], { default: inline }) : inline;
|
|
3574
|
-
}
|
|
3575
|
-
function useOptionCaps(resource) {
|
|
3576
|
-
return useI18nCaps(useContext(ResourceContext).resource ?? resource);
|
|
3577
|
-
}
|
|
3578
3761
|
function EnumDisplay({ value, options, field, resource }) {
|
|
3579
3762
|
const caps = useOptionCaps(resource);
|
|
3763
|
+
const enumDef = useBoundEnum(field);
|
|
3580
3764
|
if (value == null || value === "") return jsx("span", {
|
|
3581
3765
|
className: "text-muted-foreground",
|
|
3582
3766
|
children: "—"
|
|
3583
3767
|
});
|
|
3584
3768
|
const opt = options?.find((o) => o.value === String(value));
|
|
3585
|
-
const
|
|
3586
|
-
const label = optionLabel(caps, field, String(value), inline);
|
|
3769
|
+
const label = resolveOptionLabel(caps, field, String(value), opt, enumDef);
|
|
3587
3770
|
return jsxs("span", {
|
|
3588
3771
|
className: "inline-flex items-center gap-1",
|
|
3589
3772
|
children: [opt?.icon ? jsx(Icon, {
|
|
@@ -3592,9 +3775,36 @@ function EnumDisplay({ value, options, field, resource }) {
|
|
|
3592
3775
|
}) : null, label]
|
|
3593
3776
|
});
|
|
3594
3777
|
}
|
|
3595
|
-
function EnumInput({ name, id, value, onChange, testid, options, field, placeholder, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage, resource }) {
|
|
3778
|
+
function EnumInput({ name, id, value, onChange, testid, options, field, placeholder, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage, ariaLabelledBy, resource }) {
|
|
3596
3779
|
const t = useOptionalT();
|
|
3597
3780
|
const caps = useOptionCaps(resource);
|
|
3781
|
+
const enumDef = useBoundEnum(field);
|
|
3782
|
+
const ns = enumNamespaceOf(field);
|
|
3783
|
+
const control = resolveEnumControl(field?.ui?.control, enumDef, `field ${field?.name ?? name}`);
|
|
3784
|
+
const resolved = (options ?? []).map((o) => {
|
|
3785
|
+
const summary = ns === void 0 ? void 0 : resolveDoc(caps, `enum/${ns}/${o.value}`)?.summary;
|
|
3786
|
+
return {
|
|
3787
|
+
value: o.value,
|
|
3788
|
+
label: resolveOptionLabel(caps, field, o.value, o, enumDef),
|
|
3789
|
+
...o.icon === void 0 ? {} : { icon: o.icon },
|
|
3790
|
+
...summary === void 0 ? {} : { summary }
|
|
3791
|
+
};
|
|
3792
|
+
});
|
|
3793
|
+
if (control !== "select") return jsx(EnumChoiceGroup, {
|
|
3794
|
+
control,
|
|
3795
|
+
options: resolved,
|
|
3796
|
+
value,
|
|
3797
|
+
onChange,
|
|
3798
|
+
testid: testid ?? name,
|
|
3799
|
+
name,
|
|
3800
|
+
id,
|
|
3801
|
+
required,
|
|
3802
|
+
disabled,
|
|
3803
|
+
ariaInvalid,
|
|
3804
|
+
ariaDescribedBy,
|
|
3805
|
+
ariaErrorMessage,
|
|
3806
|
+
ariaLabelledBy
|
|
3807
|
+
});
|
|
3598
3808
|
return jsxs(Select, {
|
|
3599
3809
|
value: value ?? "",
|
|
3600
3810
|
onValueChange: onChange,
|
|
@@ -3609,14 +3819,19 @@ function EnumInput({ name, id, value, onChange, testid, options, field, placehol
|
|
|
3609
3819
|
"aria-describedby": ariaDescribedBy,
|
|
3610
3820
|
...ariaErrorMessage ? { "aria-errormessage": ariaErrorMessage } : {},
|
|
3611
3821
|
children: jsx(SelectValue, { placeholder: placeholder ?? t("field.select", { defaultValue: "Select…" }) })
|
|
3612
|
-
}), jsx(SelectContent, { children:
|
|
3822
|
+
}), jsx(SelectContent, { children: resolved.map((o) => jsx(SelectItem, {
|
|
3613
3823
|
value: o.value,
|
|
3824
|
+
"data-testid": testid === void 0 ? void 0 : `${testid}:option:${o.value}`,
|
|
3825
|
+
description: o.summary === void 0 ? void 0 : jsx("span", {
|
|
3826
|
+
"data-testid": testid === void 0 ? void 0 : `${testid}:option:${o.value}:doc`,
|
|
3827
|
+
children: o.summary
|
|
3828
|
+
}),
|
|
3614
3829
|
children: jsxs("span", {
|
|
3615
3830
|
className: "inline-flex items-center gap-1.5",
|
|
3616
3831
|
children: [o.icon ? jsx(Icon, {
|
|
3617
3832
|
name: o.icon,
|
|
3618
3833
|
className: "size-3.5 shrink-0 text-muted-foreground"
|
|
3619
|
-
}) : null,
|
|
3834
|
+
}) : null, o.label]
|
|
3620
3835
|
})
|
|
3621
3836
|
}, o.value)) })]
|
|
3622
3837
|
});
|
|
@@ -3989,6 +4204,7 @@ function JsonDisplay({ value, presentation, testid }) {
|
|
|
3989
4204
|
});
|
|
3990
4205
|
}
|
|
3991
4206
|
function JsonInput({ name, id, value, onChange, testid, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage }) {
|
|
4207
|
+
const t = useOptionalT();
|
|
3992
4208
|
const seed = React.useMemo(() => {
|
|
3993
4209
|
if (value == null || value === "") return "";
|
|
3994
4210
|
return toDisplayText(value).text;
|
|
@@ -4032,13 +4248,13 @@ function JsonInput({ name, id, value, onChange, testid, disabled, required, aria
|
|
|
4032
4248
|
}), invalid && jsx("p", {
|
|
4033
4249
|
className: "text-[13px] leading-snug text-destructive",
|
|
4034
4250
|
"data-testid": `${testid}-json-error`,
|
|
4035
|
-
children: "
|
|
4251
|
+
children: t("field.jsonInvalid", { defaultValue: "Invalid JSON. Changes will not be saved until it is valid." })
|
|
4036
4252
|
})]
|
|
4037
4253
|
});
|
|
4038
4254
|
}
|
|
4039
4255
|
//#endregion
|
|
4040
4256
|
//#region src/fields/lazy-relation-many.tsx
|
|
4041
|
-
const RelationManyPickerInput = lazy(() => import("./relation-many-picker-
|
|
4257
|
+
const RelationManyPickerInput = lazy(() => import("./relation-many-picker-BJhaEqxz.js").then((module) => ({ default: module.RelationManyPickerInput })));
|
|
4042
4258
|
function LazyRelationManyInput(props) {
|
|
4043
4259
|
return jsx(Suspense, {
|
|
4044
4260
|
fallback: jsx(Skeleton, {
|
|
@@ -4051,8 +4267,8 @@ function LazyRelationManyInput(props) {
|
|
|
4051
4267
|
}
|
|
4052
4268
|
//#endregion
|
|
4053
4269
|
//#region src/fields/lazy-rich-text.tsx
|
|
4054
|
-
const RichTextDisplay = lazy(() => import("./rich-text-
|
|
4055
|
-
const RichTextInput = lazy(() => import("./rich-text-
|
|
4270
|
+
const RichTextDisplay = lazy(() => import("./rich-text-RcPBf6hr.js").then((module) => ({ default: module.RichTextDisplay })));
|
|
4271
|
+
const RichTextInput = lazy(() => import("./rich-text-RcPBf6hr.js").then((module) => ({ default: module.RichTextInput })));
|
|
4056
4272
|
function RichTextDisplayLoading() {
|
|
4057
4273
|
const t = useOptionalT();
|
|
4058
4274
|
return jsx("div", {
|
|
@@ -4109,12 +4325,13 @@ function isIdentifier(field) {
|
|
|
4109
4325
|
const n = field?.name;
|
|
4110
4326
|
return n === "id" || typeof n === "string" && n.endsWith("_id");
|
|
4111
4327
|
}
|
|
4112
|
-
function NumberDisplay({ value, field }) {
|
|
4328
|
+
function NumberDisplay({ value, field, text }) {
|
|
4113
4329
|
const locale = useOptionalLocale();
|
|
4114
4330
|
if (value == null || value === "") return jsx("span", {
|
|
4115
4331
|
className: "text-muted-foreground",
|
|
4116
4332
|
children: "—"
|
|
4117
4333
|
});
|
|
4334
|
+
if (text !== void 0) return jsx("span", { children: text });
|
|
4118
4335
|
let raw = value;
|
|
4119
4336
|
if (typeof raw === "string") raw = unquote(raw);
|
|
4120
4337
|
const n = typeof raw === "number" ? raw : Number(raw);
|
|
@@ -4149,6 +4366,196 @@ function NumberInput({ name, id, value, onChange, testid, placeholder, disabled,
|
|
|
4149
4366
|
});
|
|
4150
4367
|
}
|
|
4151
4368
|
//#endregion
|
|
4369
|
+
//#region src/fields/link-keys-display.tsx
|
|
4370
|
+
const isRecord$1 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4371
|
+
function qualify(name) {
|
|
4372
|
+
try {
|
|
4373
|
+
const ref = normalizeEntityRef(name);
|
|
4374
|
+
return ref.namespace === "default" ? ref.id : `${ref.namespace}:${ref.id}`;
|
|
4375
|
+
} catch {
|
|
4376
|
+
return;
|
|
4377
|
+
}
|
|
4378
|
+
}
|
|
4379
|
+
function idFieldOf(def) {
|
|
4380
|
+
const declared = (def?.data)?.idField;
|
|
4381
|
+
return typeof declared === "string" && declared.length > 0 ? declared : "id";
|
|
4382
|
+
}
|
|
4383
|
+
function byOf(field) {
|
|
4384
|
+
const by = isRecord$1(field) && isRecord$1(field.meta) ? field.meta.by : void 0;
|
|
4385
|
+
return typeof by === "string" && by.length > 0 ? by : void 0;
|
|
4386
|
+
}
|
|
4387
|
+
const chipClassName = "inline-flex items-center rounded-md border border-border bg-muted/40 px-1.5 py-0.5 text-xs";
|
|
4388
|
+
function LinkKeysDisplay(props) {
|
|
4389
|
+
const { field, record } = props;
|
|
4390
|
+
const owner = props.owner ?? props.resource ?? "";
|
|
4391
|
+
const name = field?.name ?? "";
|
|
4392
|
+
const app = useApp();
|
|
4393
|
+
const t = useOptionalT();
|
|
4394
|
+
const tid = useTestIds();
|
|
4395
|
+
const ownerDef = owner === "" ? void 0 : app.registry.get(owner);
|
|
4396
|
+
const declaration = ownerDef === void 0 ? void 0 : declaredField(ownerDef, name);
|
|
4397
|
+
const link = isRecord$1(declaration) ? linkOf(declaration) : void 0;
|
|
4398
|
+
const junctionName = link === void 0 ? void 0 : qualify(link.junction);
|
|
4399
|
+
const junctionDef = junctionName === void 0 ? void 0 : app.registry.get(junctionName);
|
|
4400
|
+
const junctionField = (key) => junctionDef === void 0 ? void 0 : declaredField(junctionDef, key);
|
|
4401
|
+
const ownerField = link === void 0 ? idFieldOf(ownerDef) : byOf(junctionField(link.sourceKey)) ?? idFieldOf(ownerDef);
|
|
4402
|
+
const targetBy = link === void 0 ? void 0 : byOf(junctionField(link.targetKey));
|
|
4403
|
+
const ownerKey = record?.[ownerField];
|
|
4404
|
+
const { keys, complete, isLoading, error } = useLinkKeys(owner, name, ownerKey);
|
|
4405
|
+
const [missed, setMissed] = useState(() => new Set());
|
|
4406
|
+
const onMiss = useCallback((key, isMiss) => {
|
|
4407
|
+
setMissed((current) => {
|
|
4408
|
+
if (current.has(key) === isMiss) return current;
|
|
4409
|
+
const next = new Set(current);
|
|
4410
|
+
if (isMiss) next.add(key);
|
|
4411
|
+
else next.delete(key);
|
|
4412
|
+
return next;
|
|
4413
|
+
});
|
|
4414
|
+
}, []);
|
|
4415
|
+
const target = (isRecord$1(declaration) && isRecord$1(declaration.meta) ? declaration.meta.to : void 0) ?? field?.meta?.to;
|
|
4416
|
+
const chipField = useMemo(() => ({
|
|
4417
|
+
name,
|
|
4418
|
+
meta: {
|
|
4419
|
+
...target === void 0 ? {} : { to: target },
|
|
4420
|
+
...targetBy === void 0 ? {} : { by: targetBy }
|
|
4421
|
+
},
|
|
4422
|
+
...field?.ui === void 0 ? {} : { ui: field.ui }
|
|
4423
|
+
}), [
|
|
4424
|
+
name,
|
|
4425
|
+
target,
|
|
4426
|
+
field?.ui,
|
|
4427
|
+
targetBy
|
|
4428
|
+
]);
|
|
4429
|
+
const chipsId = tid.linkChips(owner, name);
|
|
4430
|
+
if (error) return jsx(LoadError, {
|
|
4431
|
+
surface: "relation",
|
|
4432
|
+
error,
|
|
4433
|
+
...typeof target === "string" ? { resource: target } : {},
|
|
4434
|
+
testId: tid.linkError(owner, name),
|
|
4435
|
+
className: "text-destructive text-xs",
|
|
4436
|
+
attributes: { role: "status" },
|
|
4437
|
+
fallback: {
|
|
4438
|
+
key: "field.link.failed",
|
|
4439
|
+
default: "Links could not be loaded"
|
|
4440
|
+
}
|
|
4441
|
+
});
|
|
4442
|
+
if (keys === void 0) {
|
|
4443
|
+
if (!isLoading) return jsx("span", {
|
|
4444
|
+
"data-testid": "relation-many-display:empty",
|
|
4445
|
+
className: "text-muted-foreground",
|
|
4446
|
+
children: "—"
|
|
4447
|
+
});
|
|
4448
|
+
return jsx("span", {
|
|
4449
|
+
"data-testid": `${chipsId}:loading`,
|
|
4450
|
+
className: "inline-block h-5 w-20 animate-pulse rounded bg-muted",
|
|
4451
|
+
"aria-busy": "true"
|
|
4452
|
+
});
|
|
4453
|
+
}
|
|
4454
|
+
if (!complete) return jsx("span", {
|
|
4455
|
+
"data-testid": chipsId,
|
|
4456
|
+
className: "inline-flex flex-wrap gap-1",
|
|
4457
|
+
children: jsx("span", {
|
|
4458
|
+
"data-testid": tid.linkIncomplete(owner, name),
|
|
4459
|
+
className: "text-muted-foreground",
|
|
4460
|
+
children: t("field.link.incomplete", {
|
|
4461
|
+
count: keys.length,
|
|
4462
|
+
defaultValue: "More than {{count}} links"
|
|
4463
|
+
})
|
|
4464
|
+
})
|
|
4465
|
+
});
|
|
4466
|
+
if (keys.length === 0) return jsx("span", {
|
|
4467
|
+
"data-testid": "relation-many-display:empty",
|
|
4468
|
+
className: "text-muted-foreground",
|
|
4469
|
+
children: "—"
|
|
4470
|
+
});
|
|
4471
|
+
const hidden = keys.filter((key) => missed.has(String(key))).length;
|
|
4472
|
+
return jsxs("span", {
|
|
4473
|
+
"data-testid": chipsId,
|
|
4474
|
+
className: "inline-flex flex-wrap gap-1",
|
|
4475
|
+
children: [keys.map((key) => jsx(LinkChip, {
|
|
4476
|
+
value: key,
|
|
4477
|
+
field: chipField,
|
|
4478
|
+
onMiss
|
|
4479
|
+
}, String(key))), hidden > 0 ? jsx("span", {
|
|
4480
|
+
"data-testid": tid.linkHidden(owner, name),
|
|
4481
|
+
className: `${chipClassName} text-muted-foreground`,
|
|
4482
|
+
children: t("field.link.hidden", {
|
|
4483
|
+
count: hidden,
|
|
4484
|
+
defaultValue: "{{count}} not visible"
|
|
4485
|
+
})
|
|
4486
|
+
}) : null]
|
|
4487
|
+
});
|
|
4488
|
+
}
|
|
4489
|
+
function LinkChip({ value, field, onMiss }) {
|
|
4490
|
+
const gate = useEntryGate();
|
|
4491
|
+
const meta = field.meta;
|
|
4492
|
+
let to;
|
|
4493
|
+
try {
|
|
4494
|
+
to = meta?.to === void 0 ? void 0 : resourceKey(meta.to);
|
|
4495
|
+
} catch {
|
|
4496
|
+
to = void 0;
|
|
4497
|
+
}
|
|
4498
|
+
const answer = to === void 0 ? void 0 : gate(to, "show");
|
|
4499
|
+
if (!(to !== void 0 && answer !== void 0 && answer.state !== "undecided" && answer.state !== "hidden" && answer.state !== "disabled")) return jsx("span", {
|
|
4500
|
+
className: chipClassName,
|
|
4501
|
+
children: jsx(RelationDisplay, {
|
|
4502
|
+
value,
|
|
4503
|
+
field
|
|
4504
|
+
})
|
|
4505
|
+
});
|
|
4506
|
+
return jsx(ReadChip, {
|
|
4507
|
+
to,
|
|
4508
|
+
value,
|
|
4509
|
+
field,
|
|
4510
|
+
onMiss
|
|
4511
|
+
});
|
|
4512
|
+
}
|
|
4513
|
+
function ReadChip({ to, value, field, onMiss }) {
|
|
4514
|
+
const app = useApp();
|
|
4515
|
+
const by = field.meta?.by;
|
|
4516
|
+
const { record, isLoading, error, ambiguous } = useRelatedRecord(to, value, typeof by === "string" ? { by } : void 0);
|
|
4517
|
+
const miss = app.registry.get(to) !== void 0 && !isLoading && !error && !ambiguous && !record;
|
|
4518
|
+
const key = String(value);
|
|
4519
|
+
useEffect(() => {
|
|
4520
|
+
onMiss(key, miss);
|
|
4521
|
+
}, [
|
|
4522
|
+
onMiss,
|
|
4523
|
+
key,
|
|
4524
|
+
miss
|
|
4525
|
+
]);
|
|
4526
|
+
useEffect(() => () => onMiss(key, false), [onMiss, key]);
|
|
4527
|
+
if (miss) return null;
|
|
4528
|
+
return jsx("span", {
|
|
4529
|
+
className: chipClassName,
|
|
4530
|
+
children: jsx(RelationDisplay, {
|
|
4531
|
+
value,
|
|
4532
|
+
field
|
|
4533
|
+
})
|
|
4534
|
+
});
|
|
4535
|
+
}
|
|
4536
|
+
function RelationManyDisplay(props) {
|
|
4537
|
+
const app = useApp();
|
|
4538
|
+
const owner = props.owner ?? props.resource ?? "";
|
|
4539
|
+
const ownerDef = owner === "" ? void 0 : app.registry.get(owner);
|
|
4540
|
+
const declared = ownerDef === void 0 || props.field?.name === void 0 ? void 0 : declaredField(ownerDef, props.field.name);
|
|
4541
|
+
if (isRecord$1(declared) && linkOf(declared) !== void 0) return jsx(LinkKeysDisplay, { ...props });
|
|
4542
|
+
const { value, field } = props;
|
|
4543
|
+
const keys = Array.isArray(value) ? value : [];
|
|
4544
|
+
if (keys.length === 0) return jsx("span", {
|
|
4545
|
+
"data-testid": "relation-many-display:empty",
|
|
4546
|
+
className: "text-muted-foreground",
|
|
4547
|
+
children: "—"
|
|
4548
|
+
});
|
|
4549
|
+
return jsx("span", {
|
|
4550
|
+
className: "inline-flex flex-wrap gap-x-2",
|
|
4551
|
+
"data-testid": "relation-many-display",
|
|
4552
|
+
children: keys.map((key, index) => jsx(RelationDisplay, {
|
|
4553
|
+
value: key,
|
|
4554
|
+
field
|
|
4555
|
+
}, `${String(key)}:${index}`))
|
|
4556
|
+
});
|
|
4557
|
+
}
|
|
4558
|
+
//#endregion
|
|
4152
4559
|
//#region src/fields/relation-meta-schema.ts
|
|
4153
4560
|
const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4154
4561
|
const relationMetaSchema = Object.freeze({ "~standard": Object.freeze({
|
|
@@ -4160,7 +4567,7 @@ const relationMetaSchema = Object.freeze({ "~standard": Object.freeze({
|
|
|
4160
4567
|
path: []
|
|
4161
4568
|
}] };
|
|
4162
4569
|
const issues = [];
|
|
4163
|
-
const { to, by, resolve, searchField, candidates } = value;
|
|
4570
|
+
const { to, by, resolve, searchField, candidates, scope } = value;
|
|
4164
4571
|
if (to !== void 0 && !(typeof to === "string" && to.length > 0) && !(isRecord(to) && (typeof to.id === "string" || isRecord(to.ref)))) issues.push({
|
|
4165
4572
|
message: "must be a resource name or reference",
|
|
4166
4573
|
path: ["to"]
|
|
@@ -4181,16 +4588,21 @@ const relationMetaSchema = Object.freeze({ "~standard": Object.freeze({
|
|
|
4181
4588
|
message: "must be an array of conditions",
|
|
4182
4589
|
path: ["candidates"]
|
|
4183
4590
|
});
|
|
4591
|
+
if (scope !== void 0 && scope !== "context" && scope !== "session" && scope !== "none") issues.push({
|
|
4592
|
+
message: "must be 'context', 'session' or 'none'",
|
|
4593
|
+
path: ["scope"]
|
|
4594
|
+
});
|
|
4184
4595
|
return issues.length > 0 ? { issues } : { value };
|
|
4185
4596
|
}
|
|
4186
4597
|
}) });
|
|
4187
4598
|
//#endregion
|
|
4188
4599
|
//#region src/fields/text.tsx
|
|
4189
|
-
function TextDisplay({ value }) {
|
|
4600
|
+
function TextDisplay({ value, text: formatted }) {
|
|
4190
4601
|
if (value == null || value === "") return jsx("span", {
|
|
4191
4602
|
className: "text-muted-foreground",
|
|
4192
4603
|
children: "—"
|
|
4193
4604
|
});
|
|
4605
|
+
if (formatted !== void 0) return jsx("span", { children: formatted });
|
|
4194
4606
|
const { text, isStructured } = toDisplayText(value);
|
|
4195
4607
|
return isStructured ? jsx("span", {
|
|
4196
4608
|
className: "font-mono text-xs break-all",
|
|
@@ -4219,23 +4631,26 @@ function TextInput({ name, id, value, onChange, testid, placeholder, disabled, r
|
|
|
4219
4631
|
}
|
|
4220
4632
|
//#endregion
|
|
4221
4633
|
//#region src/fields/textarea.tsx
|
|
4222
|
-
function TextareaDisplay({ value }) {
|
|
4634
|
+
function TextareaDisplay({ value, text: formatted }) {
|
|
4223
4635
|
if (value == null || value === "") return jsx("span", {
|
|
4224
4636
|
className: "text-muted-foreground",
|
|
4225
4637
|
children: "—"
|
|
4226
4638
|
});
|
|
4227
|
-
const { text, isStructured } = toDisplayText(value)
|
|
4639
|
+
const { text, isStructured } = formatted === void 0 ? toDisplayText(value) : {
|
|
4640
|
+
text: formatted,
|
|
4641
|
+
isStructured: false
|
|
4642
|
+
};
|
|
4228
4643
|
return jsx("pre", {
|
|
4229
4644
|
className: isStructured ? "whitespace-pre-wrap break-all font-mono text-xs" : "whitespace-pre-wrap font-sans text-sm",
|
|
4230
4645
|
children: text
|
|
4231
4646
|
});
|
|
4232
4647
|
}
|
|
4233
|
-
function CodeDisplay({ value, presentation, testid }) {
|
|
4648
|
+
function CodeDisplay({ value, text: formatted, presentation, testid }) {
|
|
4234
4649
|
if (value == null || value === "") return jsx("span", {
|
|
4235
4650
|
className: "text-muted-foreground",
|
|
4236
4651
|
children: "—"
|
|
4237
4652
|
});
|
|
4238
|
-
const
|
|
4653
|
+
const text = formatted ?? toDisplayText(value).text;
|
|
4239
4654
|
return jsx("pre", {
|
|
4240
4655
|
"data-testid": testid,
|
|
4241
4656
|
className: presentation === "plain" ? "overflow-x-auto whitespace-pre font-mono text-xs leading-relaxed" : "overflow-x-auto whitespace-pre rounded-md border bg-muted/40 p-3 font-mono text-xs leading-relaxed",
|
|
@@ -4279,30 +4694,39 @@ function TextareaInput({ name, id, value, onChange, testid, placeholder, disable
|
|
|
4279
4694
|
//#endregion
|
|
4280
4695
|
//#region src/fields/default-renderers.ts
|
|
4281
4696
|
function legacyField(props) {
|
|
4282
|
-
const name =
|
|
4697
|
+
const name = optionFieldName(props.path);
|
|
4698
|
+
const texts = props.field.texts;
|
|
4283
4699
|
return Object.freeze({
|
|
4284
4700
|
name,
|
|
4285
4701
|
meta: props.meta,
|
|
4286
4702
|
ui: props.ui,
|
|
4287
|
-
|
|
4703
|
+
...texts === void 0 ? {} : { texts }
|
|
4288
4704
|
});
|
|
4289
4705
|
}
|
|
4290
|
-
function legacyOptions(options) {
|
|
4706
|
+
function legacyOptions(options, field) {
|
|
4291
4707
|
if (options.length === 0) return void 0;
|
|
4292
|
-
return options.map((option) =>
|
|
4293
|
-
value
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4708
|
+
return options.map((option) => {
|
|
4709
|
+
const value = String(option.value ?? "");
|
|
4710
|
+
return Object.freeze({
|
|
4711
|
+
value,
|
|
4712
|
+
label: fieldOptionText(field, value) ?? value,
|
|
4713
|
+
...typeof option.meta?.icon === "string" ? { icon: option.meta.icon } : {}
|
|
4714
|
+
});
|
|
4715
|
+
});
|
|
4716
|
+
}
|
|
4717
|
+
function registryKey(ref) {
|
|
4718
|
+
return ref.namespace === "default" ? ref.id : formatEntityRef(ref);
|
|
4297
4719
|
}
|
|
4298
4720
|
function display(renderer) {
|
|
4299
4721
|
return function ShadcnDisplay(props) {
|
|
4300
4722
|
return createElement(renderer, {
|
|
4301
4723
|
value: props.value,
|
|
4724
|
+
...props.text === void 0 ? {} : { text: props.text },
|
|
4302
4725
|
multiple: props.multiple,
|
|
4303
4726
|
field: legacyField(props),
|
|
4304
|
-
options: legacyOptions(props.options),
|
|
4727
|
+
options: legacyOptions(props.options, props.field),
|
|
4305
4728
|
resource: props.resource.id,
|
|
4729
|
+
owner: registryKey(props.resource),
|
|
4306
4730
|
record: props.record,
|
|
4307
4731
|
presentation: props.presentation,
|
|
4308
4732
|
testid: props.testIds.display
|
|
@@ -4327,7 +4751,7 @@ function input(renderer) {
|
|
|
4327
4751
|
multiple: props.multiple,
|
|
4328
4752
|
onChange: props.onChange ?? (() => void 0),
|
|
4329
4753
|
testid: props.testIds.input,
|
|
4330
|
-
options: legacyOptions(props.options),
|
|
4754
|
+
options: legacyOptions(props.options, props.field),
|
|
4331
4755
|
placeholder: typeof props.ui.placeholder === "string" ? props.ui.placeholder : void 0,
|
|
4332
4756
|
disabled: props.disabled,
|
|
4333
4757
|
required: props.field.required === true,
|
|
@@ -4335,12 +4759,14 @@ function input(renderer) {
|
|
|
4335
4759
|
ariaInvalid: props.issues.some(isErrorIssue),
|
|
4336
4760
|
ariaDescribedBy: props.accessibility.description,
|
|
4337
4761
|
ariaErrorMessage: props.accessibility.error,
|
|
4762
|
+
ariaLabelledBy: props.accessibility.label,
|
|
4338
4763
|
field: legacyField(props),
|
|
4339
4764
|
resource: props.resource.id,
|
|
4340
4765
|
record: props.record,
|
|
4341
4766
|
relationSeeds: props.relationSeeds,
|
|
4342
4767
|
fixedFilters: props.fixedFilters,
|
|
4343
|
-
metaSources: props.metaSources
|
|
4768
|
+
metaSources: props.metaSources,
|
|
4769
|
+
link: props.link
|
|
4344
4770
|
});
|
|
4345
4771
|
};
|
|
4346
4772
|
}
|
|
@@ -4388,9 +4814,27 @@ function scalarOrCollection(renderer, layout) {
|
|
|
4388
4814
|
});
|
|
4389
4815
|
}
|
|
4390
4816
|
function enumName(ui) {
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4817
|
+
return enumBindingKey(ui.enum);
|
|
4818
|
+
}
|
|
4819
|
+
function RegistryEnumInput(props) {
|
|
4820
|
+
const app = useOptionalApp();
|
|
4821
|
+
const control = resolveEnumControl(props.ui.control, app?.registry.enums.get(props.enumName), `field ${typeof props.path.at(-1) === "string" ? String(props.path.at(-1)) : props.enumName}`);
|
|
4822
|
+
return createElement(EnumPicker, {
|
|
4823
|
+
enumName: props.enumName,
|
|
4824
|
+
control,
|
|
4825
|
+
value: props.value == null ? void 0 : String(props.value),
|
|
4826
|
+
onChange: props.onChange ?? (() => void 0),
|
|
4827
|
+
name: props.accessibility.input,
|
|
4828
|
+
id: props.accessibility.input,
|
|
4829
|
+
testid: props.testIds.input,
|
|
4830
|
+
placeholder: typeof props.ui.placeholder === "string" ? props.ui.placeholder : void 0,
|
|
4831
|
+
disabled: props.disabled,
|
|
4832
|
+
required: props.field.required === true,
|
|
4833
|
+
ariaInvalid: props.issues.some(isErrorIssue),
|
|
4834
|
+
ariaDescribedBy: props.accessibility.description,
|
|
4835
|
+
ariaErrorMessage: props.accessibility.error,
|
|
4836
|
+
ariaLabelledBy: props.accessibility.label
|
|
4837
|
+
});
|
|
4394
4838
|
}
|
|
4395
4839
|
function enumAware(renderer, layout) {
|
|
4396
4840
|
const FallbackInput = input(renderer.Input);
|
|
@@ -4400,19 +4844,9 @@ function enumAware(renderer, layout) {
|
|
|
4400
4844
|
return Object.freeze({
|
|
4401
4845
|
Input: (props) => {
|
|
4402
4846
|
const name = enumName(props.ui);
|
|
4403
|
-
if (name !== void 0) return createElement(
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
onChange: props.onChange ?? (() => void 0),
|
|
4407
|
-
name: props.accessibility.input,
|
|
4408
|
-
id: props.accessibility.input,
|
|
4409
|
-
testid: props.testIds.input,
|
|
4410
|
-
placeholder: typeof props.ui.placeholder === "string" ? props.ui.placeholder : void 0,
|
|
4411
|
-
disabled: props.disabled,
|
|
4412
|
-
required: props.field.required === true,
|
|
4413
|
-
ariaInvalid: props.issues.some(isErrorIssue),
|
|
4414
|
-
ariaDescribedBy: props.accessibility.description,
|
|
4415
|
-
ariaErrorMessage: props.accessibility.error
|
|
4847
|
+
if (name !== void 0) return createElement(RegistryEnumInput, {
|
|
4848
|
+
...props,
|
|
4849
|
+
enumName: name
|
|
4416
4850
|
});
|
|
4417
4851
|
if (props.options.length > 0) return createElement(OptionedInput, props);
|
|
4418
4852
|
return createElement(FallbackInput, props);
|
|
@@ -4447,6 +4881,10 @@ const date = {
|
|
|
4447
4881
|
Display: DateDisplay,
|
|
4448
4882
|
Input: DateInput
|
|
4449
4883
|
};
|
|
4884
|
+
const dateTime = {
|
|
4885
|
+
Display: DateTimeDisplay,
|
|
4886
|
+
Input: DateTimeInput
|
|
4887
|
+
};
|
|
4450
4888
|
const en = {
|
|
4451
4889
|
Display: EnumDisplay,
|
|
4452
4890
|
Input: EnumInput
|
|
@@ -4482,9 +4920,9 @@ const shadcnFieldImplementations = Object.freeze({
|
|
|
4482
4920
|
number: scalar(num),
|
|
4483
4921
|
boolean: scalar(bool),
|
|
4484
4922
|
date: scalar(date),
|
|
4485
|
-
dateTime: scalar(
|
|
4486
|
-
"date-time": scalar(
|
|
4487
|
-
"default:date-time": scalar(
|
|
4923
|
+
dateTime: scalar(dateTime),
|
|
4924
|
+
"date-time": scalar(dateTime),
|
|
4925
|
+
"default:date-time": scalar(dateTime),
|
|
4488
4926
|
enum: enumAware(en),
|
|
4489
4927
|
json: scalar({
|
|
4490
4928
|
Display: JsonDisplay,
|
|
@@ -4526,7 +4964,8 @@ function DisplayBody(props) {
|
|
|
4526
4964
|
}
|
|
4527
4965
|
//#endregion
|
|
4528
4966
|
//#region src/enum/enum-display.tsx
|
|
4529
|
-
function EnumDisplay$1({ enumName, value, variant = "badge", testid, className }) {
|
|
4967
|
+
function EnumDisplay$1({ enumName: enumInput, value, variant = "badge", testid, className }) {
|
|
4968
|
+
const enumName = enumBindingKey(enumInput) ?? "";
|
|
4530
4969
|
const app = useApp();
|
|
4531
4970
|
const caps = useI18nCaps();
|
|
4532
4971
|
const def = app.registry.enums.get(enumName);
|
|
@@ -4556,7 +4995,7 @@ function EnumDisplay$1({ enumName, value, variant = "badge", testid, className }
|
|
|
4556
4995
|
children: value
|
|
4557
4996
|
});
|
|
4558
4997
|
const entry = values?.find((v) => v.value === value);
|
|
4559
|
-
const label = entry === void 0 && def?.fallback ? resolveContentSlot(caps, [enumFallbackKey(ns)], { default: def
|
|
4998
|
+
const label = entry === void 0 && (def?.fallback !== void 0 || enumFallbackText(def) !== void 0) ? resolveContentSlot(caps, [enumFallbackKey(ns)], { default: enumFallbackText(def) }) ?? value : resolveEnumLabel(caps, ns, value, enumValueText(def, value) ?? entry?.label);
|
|
4560
4999
|
const icon = entry?.icon;
|
|
4561
5000
|
if (variant === "icon-label") return jsxs("span", {
|
|
4562
5001
|
"data-testid": id,
|
|
@@ -4574,159 +5013,6 @@ function EnumDisplay$1({ enumName, value, variant = "badge", testid, className }
|
|
|
4574
5013
|
});
|
|
4575
5014
|
}
|
|
4576
5015
|
//#endregion
|
|
4577
|
-
//#region src/data-table/data-table-faceted-filter.tsx
|
|
4578
|
-
function DataTableFacetedFilter({ column, title, options = [], loadOptions, selectedLabelFor, searchPlaceholder, emptyText, getTestId, className }) {
|
|
4579
|
-
const t = useOptionalT();
|
|
4580
|
-
const filterValue = column.getFilterValue();
|
|
4581
|
-
const selected = useMemo(() => {
|
|
4582
|
-
if (Array.isArray(filterValue)) return new Set(filterValue.map(String));
|
|
4583
|
-
return new Set();
|
|
4584
|
-
}, [filterValue]);
|
|
4585
|
-
const [search, setSearch] = useState("");
|
|
4586
|
-
const [asyncOptions, setAsyncOptions] = useState([]);
|
|
4587
|
-
const [loading, setLoading] = useState(false);
|
|
4588
|
-
const debounceRef = useRef(null);
|
|
4589
|
-
const loadOptionsRef = useRef(loadOptions);
|
|
4590
|
-
useEffect(() => {
|
|
4591
|
-
loadOptionsRef.current = loadOptions;
|
|
4592
|
-
});
|
|
4593
|
-
useEffect(() => {
|
|
4594
|
-
if (!loadOptionsRef.current) return;
|
|
4595
|
-
setLoading(true);
|
|
4596
|
-
if (debounceRef.current !== null) clearTimeout(debounceRef.current);
|
|
4597
|
-
let cancelled = false;
|
|
4598
|
-
debounceRef.current = setTimeout(() => {
|
|
4599
|
-
const loader = loadOptionsRef.current;
|
|
4600
|
-
if (!loader) return;
|
|
4601
|
-
loader(search).then((results) => {
|
|
4602
|
-
if (!cancelled) {
|
|
4603
|
-
setAsyncOptions(results);
|
|
4604
|
-
setLoading(false);
|
|
4605
|
-
}
|
|
4606
|
-
}).catch(() => {
|
|
4607
|
-
if (!cancelled) setLoading(false);
|
|
4608
|
-
});
|
|
4609
|
-
}, 250);
|
|
4610
|
-
return () => {
|
|
4611
|
-
cancelled = true;
|
|
4612
|
-
if (debounceRef.current !== null) clearTimeout(debounceRef.current);
|
|
4613
|
-
};
|
|
4614
|
-
}, [search]);
|
|
4615
|
-
const effectiveOptions = loadOptions ? asyncOptions : options;
|
|
4616
|
-
const labelFor = (value) => {
|
|
4617
|
-
const opt = effectiveOptions.find((o) => o.value === value);
|
|
4618
|
-
if (opt) return opt.label;
|
|
4619
|
-
return selectedLabelFor?.(value) ?? value;
|
|
4620
|
-
};
|
|
4621
|
-
const toggle = (value) => {
|
|
4622
|
-
const next = new Set(selected);
|
|
4623
|
-
if (next.has(value)) next.delete(value);
|
|
4624
|
-
else next.add(value);
|
|
4625
|
-
column.setFilterValue(next.size === 0 ? void 0 : Array.from(next));
|
|
4626
|
-
};
|
|
4627
|
-
const selectedValues = Array.from(selected);
|
|
4628
|
-
return jsxs(Popover, { children: [jsx(PopoverTrigger, {
|
|
4629
|
-
asChild: true,
|
|
4630
|
-
children: jsxs(Button, {
|
|
4631
|
-
type: "button",
|
|
4632
|
-
variant: "outline",
|
|
4633
|
-
size: "sm",
|
|
4634
|
-
"data-testid": getTestId?.("trigger"),
|
|
4635
|
-
className: cn("h-8 border-dashed", className),
|
|
4636
|
-
children: [
|
|
4637
|
-
jsx(IconCirclePlus, {
|
|
4638
|
-
className: "mr-2 h-4 w-4",
|
|
4639
|
-
"aria-hidden": "true"
|
|
4640
|
-
}),
|
|
4641
|
-
title,
|
|
4642
|
-
selected.size > 0 && jsxs(Fragment$1, { children: [
|
|
4643
|
-
jsx("span", {
|
|
4644
|
-
className: "mx-2 h-4 w-px bg-border",
|
|
4645
|
-
"aria-hidden": "true"
|
|
4646
|
-
}),
|
|
4647
|
-
jsx(Badge, {
|
|
4648
|
-
variant: "secondary",
|
|
4649
|
-
className: "rounded-sm px-1 font-normal lg:hidden",
|
|
4650
|
-
children: selected.size
|
|
4651
|
-
}),
|
|
4652
|
-
jsx("div", {
|
|
4653
|
-
className: "hidden gap-1 lg:flex",
|
|
4654
|
-
children: selected.size > 2 ? jsx(Badge, {
|
|
4655
|
-
variant: "secondary",
|
|
4656
|
-
className: "rounded-sm px-1 font-normal",
|
|
4657
|
-
children: t("table.selectedCount", {
|
|
4658
|
-
count: selected.size,
|
|
4659
|
-
defaultValue: "{{count}} selected"
|
|
4660
|
-
})
|
|
4661
|
-
}) : selectedValues.map((value) => jsx(Badge, {
|
|
4662
|
-
variant: "secondary",
|
|
4663
|
-
className: "rounded-sm px-1 font-normal",
|
|
4664
|
-
children: labelFor(value)
|
|
4665
|
-
}, value))
|
|
4666
|
-
})
|
|
4667
|
-
] })
|
|
4668
|
-
]
|
|
4669
|
-
})
|
|
4670
|
-
}), jsx(PopoverContent, {
|
|
4671
|
-
className: "w-[220px] p-0",
|
|
4672
|
-
align: "start",
|
|
4673
|
-
children: jsxs(Command, {
|
|
4674
|
-
shouldFilter: !loadOptions,
|
|
4675
|
-
children: [
|
|
4676
|
-
jsx(CommandInput, {
|
|
4677
|
-
placeholder: searchPlaceholder ?? title,
|
|
4678
|
-
"data-testid": getTestId?.("search"),
|
|
4679
|
-
...loadOptions ? {
|
|
4680
|
-
value: search,
|
|
4681
|
-
onValueChange: setSearch
|
|
4682
|
-
} : {}
|
|
4683
|
-
}),
|
|
4684
|
-
jsxs(CommandList, { children: [
|
|
4685
|
-
loading && jsx("div", {
|
|
4686
|
-
className: "py-6 text-center text-sm text-muted-foreground",
|
|
4687
|
-
children: t("list.loadingShort", { defaultValue: "Loading…" })
|
|
4688
|
-
}),
|
|
4689
|
-
jsx(CommandEmpty, { children: emptyText ?? t("relation.noResults", { defaultValue: "No results." }) }),
|
|
4690
|
-
jsx(CommandGroup, { children: effectiveOptions.map((opt) => {
|
|
4691
|
-
const isSelected = selected.has(opt.value);
|
|
4692
|
-
const Icon = opt.icon;
|
|
4693
|
-
return jsxs(CommandItem, {
|
|
4694
|
-
value: opt.label,
|
|
4695
|
-
"data-testid": getTestId?.("option", opt.value),
|
|
4696
|
-
role: "option",
|
|
4697
|
-
"aria-selected": isSelected,
|
|
4698
|
-
"aria-checked": isSelected,
|
|
4699
|
-
onSelect: () => toggle(opt.value),
|
|
4700
|
-
children: [
|
|
4701
|
-
jsx("span", {
|
|
4702
|
-
className: cn("mr-2 flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border", isSelected ? "border-primary bg-primary text-primary-foreground" : "border-input opacity-50"),
|
|
4703
|
-
"aria-hidden": "true",
|
|
4704
|
-
children: isSelected && jsx(IconCheck, { className: "h-3.5 w-3.5" })
|
|
4705
|
-
}),
|
|
4706
|
-
Icon && jsx(Icon, {
|
|
4707
|
-
className: "mr-2 h-4 w-4 text-muted-foreground",
|
|
4708
|
-
"aria-hidden": "true"
|
|
4709
|
-
}),
|
|
4710
|
-
jsx("span", {
|
|
4711
|
-
className: "flex-1 text-left",
|
|
4712
|
-
children: opt.label
|
|
4713
|
-
})
|
|
4714
|
-
]
|
|
4715
|
-
}, opt.value);
|
|
4716
|
-
}) })
|
|
4717
|
-
] }),
|
|
4718
|
-
selected.size > 0 && jsx("button", {
|
|
4719
|
-
type: "button",
|
|
4720
|
-
"data-testid": getTestId?.("clear"),
|
|
4721
|
-
onClick: () => column.setFilterValue(void 0),
|
|
4722
|
-
className: "flex w-full items-center justify-center border-t px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground",
|
|
4723
|
-
children: t("filters.clearAll", { defaultValue: "Clear filters" })
|
|
4724
|
-
})
|
|
4725
|
-
]
|
|
4726
|
-
})
|
|
4727
|
-
})] });
|
|
4728
|
-
}
|
|
4729
|
-
//#endregion
|
|
4730
5016
|
//#region src/data-table/data-table-text-filter.tsx
|
|
4731
5017
|
function DataTableTextFilter({ column, placeholder, testid, className }) {
|
|
4732
5018
|
const external = column.getFilterValue() ?? "";
|
|
@@ -4876,14 +5162,18 @@ const OPERATOR_LABELS = {
|
|
|
4876
5162
|
null: "is null",
|
|
4877
5163
|
nnull: "is not null",
|
|
4878
5164
|
startswith: "starts with",
|
|
4879
|
-
endswith: "ends with"
|
|
5165
|
+
endswith: "ends with",
|
|
5166
|
+
has: "has",
|
|
5167
|
+
hasAny: "has any of",
|
|
5168
|
+
hasAll: "has all of",
|
|
5169
|
+
hasNone: "has none of"
|
|
4880
5170
|
};
|
|
4881
|
-
function formatOperatorLabel(op,
|
|
4882
|
-
return
|
|
5171
|
+
function formatOperatorLabel(op, chromeT) {
|
|
5172
|
+
return chromeT ? chromeT(`filters.operators.${op}`, { defaultValue: OPERATOR_LABELS[op] }) : OPERATOR_LABELS[op];
|
|
4883
5173
|
}
|
|
4884
5174
|
function useOperatorLabel() {
|
|
4885
|
-
const
|
|
4886
|
-
return (op) => formatOperatorLabel(op,
|
|
5175
|
+
const chromeT = useChromeT();
|
|
5176
|
+
return (op) => formatOperatorLabel(op, chromeT);
|
|
4887
5177
|
}
|
|
4888
5178
|
function isEmpty(v) {
|
|
4889
5179
|
return v === void 0 || v === null || v === "";
|
|
@@ -4977,7 +5267,7 @@ function DataTableOperatorFilter({ column, operators, defaultOperator, valueKind
|
|
|
4977
5267
|
//#region src/data-table/data-table-row-actions.tsx
|
|
4978
5268
|
function DataTableRowActions({ row, actions, getTestId, className }) {
|
|
4979
5269
|
const [open, setOpen] = useState(false);
|
|
4980
|
-
const
|
|
5270
|
+
const chromeT = useChromeT();
|
|
4981
5271
|
if (actions.length === 0) return null;
|
|
4982
5272
|
return jsxs(Popover, {
|
|
4983
5273
|
open,
|
|
@@ -4995,7 +5285,7 @@ function DataTableRowActions({ row, actions, getTestId, className }) {
|
|
|
4995
5285
|
"aria-hidden": "true"
|
|
4996
5286
|
}), jsx("span", {
|
|
4997
5287
|
className: "sr-only",
|
|
4998
|
-
children:
|
|
5288
|
+
children: chromeT("actions.openMenu", { defaultValue: "Open row actions menu" })
|
|
4999
5289
|
})]
|
|
5000
5290
|
})
|
|
5001
5291
|
}), jsx(PopoverContent, {
|
|
@@ -5116,7 +5406,8 @@ function BlockScreen({ block, props, resource, record, label }) {
|
|
|
5116
5406
|
children: jsx(PlannedBody, {
|
|
5117
5407
|
screen: compiled,
|
|
5118
5408
|
name: "modal",
|
|
5119
|
-
label: label ?? ""
|
|
5409
|
+
label: label ?? "",
|
|
5410
|
+
...needsRow && row !== null ? { record: row } : {}
|
|
5120
5411
|
})
|
|
5121
5412
|
})
|
|
5122
5413
|
});
|
|
@@ -5125,13 +5416,20 @@ function relation(field) {
|
|
|
5125
5416
|
if (field === null || typeof field !== "object") return false;
|
|
5126
5417
|
return isRelationField(field);
|
|
5127
5418
|
}
|
|
5419
|
+
const resolveOf = (bag) => bag !== null && typeof bag === "object" ? bag.resolve : void 0;
|
|
5420
|
+
function lazyToOne(field) {
|
|
5421
|
+
const entry = field;
|
|
5422
|
+
if (entry.kind === "relationMany" || entry.type === "array") return false;
|
|
5423
|
+
return (resolveOf(entry.meta) ?? resolveOf(entry.opts)) === "lazy";
|
|
5424
|
+
}
|
|
5128
5425
|
function peekFields(def, columns, capabilityFor, fieldVisible = () => true) {
|
|
5129
5426
|
const record = new Set(dtoFields(def, "record"));
|
|
5130
5427
|
const out = [];
|
|
5131
5428
|
for (const name of columns) {
|
|
5132
5429
|
if (out.length === 5) break;
|
|
5133
5430
|
if (name === def.displayField || out.includes(name) || !record.has(name)) continue;
|
|
5134
|
-
|
|
5431
|
+
const field = peekFieldDefinition(def, name);
|
|
5432
|
+
if (!peekLeafAllowed(def, name, capabilityFor, fieldVisible) || relation(field) && !lazyToOne(field)) continue;
|
|
5135
5433
|
out.push(name);
|
|
5136
5434
|
}
|
|
5137
5435
|
return Object.freeze(out);
|
|
@@ -5198,6 +5496,7 @@ function PeekByKey({ target, by }) {
|
|
|
5198
5496
|
page: 1,
|
|
5199
5497
|
pageSize: 2
|
|
5200
5498
|
},
|
|
5499
|
+
scope: "none",
|
|
5201
5500
|
enabled: by.key !== "",
|
|
5202
5501
|
retry: false
|
|
5203
5502
|
});
|
|
@@ -5213,7 +5512,7 @@ function PeekByKey({ target, by }) {
|
|
|
5213
5512
|
} else if (query.error != null) read = failure(query.error, () => void query.refetch());
|
|
5214
5513
|
else read = { state: "pending" };
|
|
5215
5514
|
useEffect(() => {
|
|
5216
|
-
if (read.state === "ambiguous" && process.env.NODE_ENV !== "production") console.error(`[burojs] ${relationAmbiguousError(target, by.field, by.key)
|
|
5515
|
+
if (read.state === "ambiguous" && process.env.NODE_ENV !== "production") console.error(`[burojs] ${technicalText(relationAmbiguousError(target, by.field, by.key))}`);
|
|
5217
5516
|
}, [
|
|
5218
5517
|
read.state,
|
|
5219
5518
|
target,
|
|
@@ -5229,6 +5528,7 @@ function PeekByKey({ target, by }) {
|
|
|
5229
5528
|
function PeekBody({ target, peekKey, read }) {
|
|
5230
5529
|
const tid = useTestIds();
|
|
5231
5530
|
const t = useOptionalT();
|
|
5531
|
+
const chromeT = useChromeT();
|
|
5232
5532
|
const testid = tid.peek(target, peekKey);
|
|
5233
5533
|
if (read.state === "pending") return jsx("div", {
|
|
5234
5534
|
"data-testid": testid,
|
|
@@ -5256,7 +5556,7 @@ function PeekBody({ target, peekKey, read }) {
|
|
|
5256
5556
|
variant: "outline",
|
|
5257
5557
|
"data-testid": `${testid}:retry`,
|
|
5258
5558
|
onClick: read.retry,
|
|
5259
|
-
children:
|
|
5559
|
+
children: chromeT("actions.retry", { defaultValue: "Retry" })
|
|
5260
5560
|
})]
|
|
5261
5561
|
});
|
|
5262
5562
|
if (read.state === "unavailable") return jsx("p", {
|
|
@@ -5484,7 +5784,7 @@ function DefaultPeekBody({ target, testid, row, open }) {
|
|
|
5484
5784
|
const columns = useMemo(() => {
|
|
5485
5785
|
if (def === void 0) return [];
|
|
5486
5786
|
const listed = def.views?.list?.columns;
|
|
5487
|
-
return peekFields(def, listed ?? Object.keys(def.fields), capabilityFor, (name) => access[name]?.view === "visible");
|
|
5787
|
+
return peekFields(def, listed?.map(columnName) ?? Object.keys(def.fields), capabilityFor, (name) => access[name]?.view === "visible");
|
|
5488
5788
|
}, [
|
|
5489
5789
|
def,
|
|
5490
5790
|
capabilityFor,
|
|
@@ -5521,16 +5821,24 @@ function DefaultPeekBody({ target, testid, row, open }) {
|
|
|
5521
5821
|
className: "flex min-w-0 items-baseline gap-2 text-sm",
|
|
5522
5822
|
children: [jsx("dt", {
|
|
5523
5823
|
className: "w-24 shrink-0 truncate text-xs text-muted-foreground",
|
|
5524
|
-
children: resolveFieldLabel(caps, name, field
|
|
5824
|
+
children: resolveFieldLabel(caps, name, declaredText("field", field, "label"))
|
|
5525
5825
|
}), jsx("dd", {
|
|
5526
5826
|
className: "min-w-0 break-words",
|
|
5527
|
-
children: jsx(
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
|
|
5827
|
+
children: jsx(FieldValueFrame, {
|
|
5828
|
+
field: {
|
|
5829
|
+
...field,
|
|
5830
|
+
name
|
|
5831
|
+
},
|
|
5531
5832
|
value,
|
|
5532
|
-
|
|
5533
|
-
|
|
5833
|
+
surface: "display",
|
|
5834
|
+
children: jsx(ResolvedFieldDisplay, {
|
|
5835
|
+
resource: ref,
|
|
5836
|
+
name,
|
|
5837
|
+
field,
|
|
5838
|
+
value,
|
|
5839
|
+
record,
|
|
5840
|
+
fallback: toDisplayText(value).text
|
|
5841
|
+
})
|
|
5534
5842
|
})
|
|
5535
5843
|
})]
|
|
5536
5844
|
}, name);
|
|
@@ -5542,21 +5850,36 @@ function DefaultPeekBody({ target, testid, row, open }) {
|
|
|
5542
5850
|
//#region src/quick/quick-body.tsx
|
|
5543
5851
|
const EMPTY_ROUTE = Object.freeze({});
|
|
5544
5852
|
function QuickBody({ entry }) {
|
|
5853
|
+
return jsx(RecordScopeChain, {
|
|
5854
|
+
frames: entry.scopeFrames ?? NO_RECORD_SCOPE_FRAMES,
|
|
5855
|
+
children: jsx(QuickBodyOf, { entry })
|
|
5856
|
+
});
|
|
5857
|
+
}
|
|
5858
|
+
function QuickBodyOf({ entry }) {
|
|
5545
5859
|
if (entry.mode === "create") return jsx(QuickScreenOf, {
|
|
5546
5860
|
entry,
|
|
5547
5861
|
route: EMPTY_ROUTE
|
|
5548
5862
|
});
|
|
5549
5863
|
if (entry.recordId === void 0 || entry.recordId === "") return jsx(RecordState, { state: "not-found" });
|
|
5550
|
-
return jsx(
|
|
5864
|
+
return jsx(QuickReadRoute, {
|
|
5551
5865
|
entry,
|
|
5552
5866
|
recordId: entry.recordId
|
|
5553
5867
|
});
|
|
5554
5868
|
}
|
|
5555
|
-
function
|
|
5869
|
+
function QuickReadRoute({ entry, recordId }) {
|
|
5870
|
+
const typed = useRouteRecordId(entry.resource, recordId);
|
|
5871
|
+
if (typed === void 0) return jsx(InvalidRouteId, { resource: entry.resource });
|
|
5872
|
+
return jsx(QuickRead, {
|
|
5873
|
+
entry,
|
|
5874
|
+
recordId,
|
|
5875
|
+
typedId: typed
|
|
5876
|
+
});
|
|
5877
|
+
}
|
|
5878
|
+
function QuickRead({ entry, recordId, typedId }) {
|
|
5556
5879
|
const def = useApp().registry.get(entry.resource);
|
|
5557
5880
|
const projection = useMemo(() => def === void 0 ? void 0 : dtoFields(def, "record"), [def]);
|
|
5558
5881
|
const query = useOne(entry.resource, {
|
|
5559
|
-
id:
|
|
5882
|
+
id: typedId,
|
|
5560
5883
|
retry: retryRecordRead,
|
|
5561
5884
|
...projection === void 0 ? {} : { projection }
|
|
5562
5885
|
});
|
|
@@ -5567,20 +5890,20 @@ function QuickRead({ entry, recordId }) {
|
|
|
5567
5890
|
return jsx(QuickLoaded, {
|
|
5568
5891
|
entry,
|
|
5569
5892
|
recordId,
|
|
5893
|
+
typedId,
|
|
5570
5894
|
row,
|
|
5571
5895
|
isCurrentData: !query.isPlaceholderData
|
|
5572
5896
|
});
|
|
5573
5897
|
}
|
|
5574
|
-
if (query.error != null) {
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
|
|
5580
|
-
}
|
|
5898
|
+
if (query.error != null) return jsx(LoadError, {
|
|
5899
|
+
surface: "record",
|
|
5900
|
+
resource: entry.resource,
|
|
5901
|
+
error: query.error,
|
|
5902
|
+
retry: () => void query.refetch()
|
|
5903
|
+
});
|
|
5581
5904
|
return jsx(RecordState, { state: "loading" });
|
|
5582
5905
|
}
|
|
5583
|
-
function QuickLoaded({ entry, recordId, row, isCurrentData }) {
|
|
5906
|
+
function QuickLoaded({ entry, recordId, typedId, row, isCurrentData }) {
|
|
5584
5907
|
const gate = useEntryGate();
|
|
5585
5908
|
const quick = useQuickEntry();
|
|
5586
5909
|
const answer = gate(entry.resource, entry.mode === "edit" ? "edit" : "show", row);
|
|
@@ -5600,16 +5923,16 @@ function QuickLoaded({ entry, recordId, row, isCurrentData }) {
|
|
|
5600
5923
|
if (!open) return jsx(RecordState, { state: "not-found" });
|
|
5601
5924
|
return jsx(QuickScreenOf, {
|
|
5602
5925
|
entry,
|
|
5603
|
-
route
|
|
5926
|
+
route,
|
|
5927
|
+
recordId: typedId
|
|
5604
5928
|
});
|
|
5605
5929
|
}
|
|
5606
5930
|
function canonicalOrNull(name) {
|
|
5607
|
-
if (typeof name !== "string") return null;
|
|
5608
5931
|
try {
|
|
5609
|
-
return canonicalResourceName(name);
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5932
|
+
if (typeof name === "string") return canonicalResourceName(name);
|
|
5933
|
+
if (name !== null && typeof name === "object") return routeResourceKey(name);
|
|
5934
|
+
} catch {}
|
|
5935
|
+
return null;
|
|
5613
5936
|
}
|
|
5614
5937
|
function absorbedRedirect(to, entry) {
|
|
5615
5938
|
if (typeof to !== "object" || to === null) return null;
|
|
@@ -5623,7 +5946,7 @@ function closeEntry(quick, dismiss) {
|
|
|
5623
5946
|
if (quick.stack.entries.length > 1) quick.stack.pop();
|
|
5624
5947
|
else dismiss(quick.presentationId);
|
|
5625
5948
|
}
|
|
5626
|
-
function QuickScreenOf({ entry, route }) {
|
|
5949
|
+
function QuickScreenOf({ entry, route, recordId }) {
|
|
5627
5950
|
const quick = useQuickEntry();
|
|
5628
5951
|
const instance = useUIInstance();
|
|
5629
5952
|
const runtime = useUIPresentationRuntime();
|
|
@@ -5675,7 +5998,7 @@ function QuickScreenOf({ entry, route }) {
|
|
|
5675
5998
|
children: jsx(RecordScreen, {
|
|
5676
5999
|
resource: entry.resource,
|
|
5677
6000
|
mode: entry.mode,
|
|
5678
|
-
...
|
|
6001
|
+
...recordId === void 0 ? {} : { recordId },
|
|
5679
6002
|
...entry.defaults === void 0 ? {} : { defaults: entry.defaults },
|
|
5680
6003
|
...entry.input === void 0 ? {} : { input: entry.input },
|
|
5681
6004
|
...callbacks
|
|
@@ -5697,7 +6020,7 @@ function useEntryTitle(entry) {
|
|
|
5697
6020
|
const caps = useI18nCaps(entry.resource);
|
|
5698
6021
|
const t = useOptionalT();
|
|
5699
6022
|
if (entry.mode !== "create") return entry.title ?? "";
|
|
5700
|
-
return t
|
|
6023
|
+
return resolveResourceTitle(caps, t, entry.resource, "createTitle", { label: resolveResourceLabel(caps, entry.resource, "single", app.registry.get(entry.resource)) });
|
|
5701
6024
|
}
|
|
5702
6025
|
const HEADING_CLASS = "min-w-0 flex-1 break-words text-lg font-semibold tracking-tight focus-visible:outline-hidden";
|
|
5703
6026
|
function QuickHeader({ entries }) {
|
|
@@ -5954,11 +6277,25 @@ SheetPresentationHost.optionsSchema = Object.freeze({
|
|
|
5954
6277
|
//#region src/ui-presentations/index.tsx
|
|
5955
6278
|
function FlowScreen(props) {
|
|
5956
6279
|
const loaded = useLoaded(loadFlowScreen);
|
|
5957
|
-
if (loaded.error !== void 0) return jsx(FlowLoadFailed, {
|
|
5958
|
-
|
|
6280
|
+
if (loaded.error !== void 0) return jsx(FlowLoadFailed, {
|
|
6281
|
+
label: props.label,
|
|
6282
|
+
onRetry: loaded.retry
|
|
6283
|
+
});
|
|
6284
|
+
if (loaded.module === void 0) return jsxs("div", {
|
|
6285
|
+
"data-buro-flow-step": "loading",
|
|
6286
|
+
"aria-busy": "true",
|
|
6287
|
+
className: "flex flex-col gap-4",
|
|
6288
|
+
children: [jsx(OwnTitleHeading, { label: props.label }), jsx(IconLoader2, {
|
|
6289
|
+
className: "h-5 w-5 animate-spin self-center",
|
|
6290
|
+
"aria-hidden": "true"
|
|
6291
|
+
})]
|
|
6292
|
+
});
|
|
5959
6293
|
const Screen = loaded.module.FlowScreen;
|
|
5960
6294
|
return jsx(FlowBoundary, {
|
|
5961
|
-
fallback: (_error, reset) => jsx(FlowLoadFailed, {
|
|
6295
|
+
fallback: (_error, reset) => jsx(FlowLoadFailed, {
|
|
6296
|
+
label: props.label,
|
|
6297
|
+
onRetry: reset
|
|
6298
|
+
}),
|
|
5962
6299
|
children: jsx(Screen, { ...props })
|
|
5963
6300
|
});
|
|
5964
6301
|
}
|
|
@@ -6233,9 +6570,13 @@ function DefaultCommandPalette({ open, onOpenChange, actions, children }) {
|
|
|
6233
6570
|
}
|
|
6234
6571
|
//#endregion
|
|
6235
6572
|
//#region src/shell/app-shell.tsx
|
|
6236
|
-
function AppShell({ brand, user, loginPath, sidebar, header, palette, docPanel, children }) {
|
|
6573
|
+
function AppShell({ brand, user, loginPath, sidebar, header, palette, docPanel, navChrome, children }) {
|
|
6237
6574
|
const enabled = palette !== false;
|
|
6238
|
-
const { open, setOpen } = useCommandPalette(
|
|
6575
|
+
const { open, setOpen, toggle } = useCommandPalette();
|
|
6576
|
+
useGlobalShortcut({
|
|
6577
|
+
key: "k",
|
|
6578
|
+
mod: true
|
|
6579
|
+
}, toggle, { enabled });
|
|
6239
6580
|
const paletteState = useMemo(() => ({
|
|
6240
6581
|
open,
|
|
6241
6582
|
setOpen
|
|
@@ -6253,7 +6594,7 @@ function AppShell({ brand, user, loginPath, sidebar, header, palette, docPanel,
|
|
|
6253
6594
|
sidebar: fill(sidebar, () => jsx(AppSidebar, {})),
|
|
6254
6595
|
header: fill(header, () => jsx(AppHeader, {})),
|
|
6255
6596
|
...docPanel !== void 0 ? { docPanel } : {},
|
|
6256
|
-
children
|
|
6597
|
+
children: navChrome === false ? children : jsx(NavChrome, { children })
|
|
6257
6598
|
}), paletteNode]
|
|
6258
6599
|
});
|
|
6259
6600
|
}
|
|
@@ -6361,6 +6702,6 @@ function ScopeSwitcher({ options, value, onChange, label, extra, placeholder })
|
|
|
6361
6702
|
const PACKAGE_NAME = "@burojs/ui-shadcn";
|
|
6362
6703
|
const PACKAGE_VERSION = "0.0.0";
|
|
6363
6704
|
//#endregion
|
|
6364
|
-
export { ActionButton, ActionOverflow, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AppActions, AppFlowButton, AppHeader, AppLayout, AppShell, AppSidebar, AuthPage, Avatar, AvatarFallback, AvatarImage, Badge, BooleanDisplay, BooleanInput, BrandMark, Breadcrumbs, BulkActionToolbar, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CheckConfirmDialog, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, ColumnsToggle, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandPalette, CommandPaletteActionsGroup, CommandPaletteCreateGroup, CommandPaletteDocsGroup, CommandPaletteNavigationGroups, CommandPaletteRecentGroup, CommandPaletteRecordsGroup, CommandPaletteTrigger, CommandSeparator, ContextPicker, CopyId, CreateButton, CursorLoadMore,
|
|
6705
|
+
export { ActionButton, ActionOverflow, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AppActions, AppFlowButton, AppHeader, AppLayout, AppShell, AppSidebar, AuthPage, Avatar, AvatarFallback, AvatarImage, Badge, BooleanDisplay, BooleanInput, BrandMark, Breadcrumbs, BulkActionToolbar, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CheckConfirmDialog, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, ColumnsToggle, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandPalette, CommandPaletteActionsGroup, CommandPaletteCreateGroup, CommandPaletteDocsGroup, CommandPaletteNavigationGroups, CommandPaletteRecentGroup, CommandPaletteRecordsGroup, CommandPaletteTrigger, CommandSeparator, ContextPicker, CopyId, CreateButton, CursorLoadMore, DEFAULT_LANGUAGE_STORAGE_KEY, DataTable, DataTableDateRangeFilter, DataTableEnumFilter, DataTableFacetedFilter, DataTableNumRangeFilter, DataTableOperatorFilter, DataTableRowActions, DataTableTextFilter, DataTableToolbar, DataTableViewOptions, DateDisplay, DateInput, DeclarativeDisplay, DeclarativeForm, DefaultCommandPalette, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogPresentationHost, DialogPresentationShell, DialogTitle, DialogTrigger, DisabledAction, DocBrowser, DocInfo, DocPanel, DocTrailHelp, DocumentTitleProvider, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, ENUM_PICKER_CLEAR_SENTINEL, EditPageHeader, EnumBadge, EnumDisplay, EnumInput, EnumPicker, EnumDisplay$1 as EnumValueDisplay, ExportButton, ExportDialog, FacetedFilterPicker, Field, FieldDisplay, FileDisplay, FileField, FileInput, FilterBadges, FilterBuilder, FilterPanel, FilterRegion, FilterValueControl, FlowActionButton, Form, FormActions, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, HeaderBreadcrumbs, HelpButton, Icon, Input, Label, LanguageSubmenu, LanguageSwitch, LinkComponentProvider, LinkKeysDisplay, ListBody, ListBulkBar, ListColumns, ListControls, ListCreate, ListErrorState, ListExport, ListFilters, ListFlows, ListLive, ListSavedViews, ListSearchInput, LoginForm, NavAreaPage, NavChrome, NavMain, NavigationGuardDialog, NumberDisplay, NumberInput, PACKAGE_NAME, PACKAGE_VERSION, PageHeader, PinnedFilterControls, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverPresentationHost, PopoverTrigger, PresetFilterControls, Progress, RecordActions, RecordBreadcrumbs, RecordPage, RecordScreen, RecordTitle, RefreshButton, RelationDisplay, RelationField, RelationManyDisplay, RelationPicker, LazyRelationPickerDialog as RelationPickerDialog, RelationPickerInput, ResourceList, ResourceListPage, ResourcePageRouter, SavedViewsDropdown, ScopeDimensionPicker, ScopeSwitcher, SecondarySidebarLayout, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetPresentationHost, SheetPresentationShell, SheetTitle, SheetTrigger, ShellProvider, ShowPageHeader, Sidebar, SidebarBrand, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, THEME_CHOICES, THEME_STORAGE_KEY, Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsLayout, TabsList, TabsTrigger, TaskRunPanel, TextDisplay, TextInput, Textarea, TextareaDisplay, TextareaInput, ThemeSubmenu, ThemeToggle, Toaster, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserMenu, badgeVariants, buildNavItems, buroSortingToTanStack, buttonVariants, cn, defaultNavLayouts, defaultUserMapper, downloadArtifact, formatOperatorLabel, hasIcon, i18nPrefixToRef, isImage, layoutSlot, listSlot, loadLocale, localeLabel, modeForSurface, recordDisplayName, registerIcons, relationLinkClassName, resolveNavIcon, resolveUpdater, saveLocale, shadcnBlockImplementations, shadcnFieldImplementations, shadcnPresentationHosts, spacing, tanStackSortingToBuro, toast, typography, useBuroDataTable, useCurrentUser, useDialogFilterState, useDocumentTitle, useExportRunWatcher, useFormControl, useFormField, useHref, useIsMobile, useLanguagePaletteActions, useLanguageSwitch, useLayout, useLayoutResolver, useLinkComponent, useListSlot, useMatch, useNavIcon, useNavTree, useNavVisible, useOptionalSidebar, usePaletteState, usePresentationCopy, useRelationPicker, useShell, useSidebar, useTheme, useThemePaletteActions, webPlatform, wrapperEnabled };
|
|
6365
6706
|
|
|
6366
6707
|
//# sourceMappingURL=index.js.map
|