@burojs/ui-shadcn 0.7.0 → 0.8.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/dist/{bulk-summary-CrEij5vq.cjs → bulk-summary-2HLgz7Il.cjs} +31 -5
- package/dist/bulk-summary-2HLgz7Il.cjs.map +1 -0
- package/dist/{bulk-summary-BWSAS7k2.js → bulk-summary-D6A0ua21.js} +32 -6
- package/dist/bulk-summary-D6A0ua21.js.map +1 -0
- package/dist/{candidates-relation-picker-y5M6_oe4.cjs → candidates-relation-picker-C47mF260.cjs} +3 -3
- package/dist/{candidates-relation-picker-y5M6_oe4.cjs.map → candidates-relation-picker-C47mF260.cjs.map} +1 -1
- package/dist/{candidates-relation-picker-CS_JZ4Fd.js → candidates-relation-picker-CGXItMN0.js} +3 -3
- package/dist/{candidates-relation-picker-CS_JZ4Fd.js.map → candidates-relation-picker-CGXItMN0.js.map} +1 -1
- package/dist/{check-confirm-dialog-C-NHgMST.cjs → check-confirm-dialog-BT04Mieo.cjs} +13 -6
- package/dist/check-confirm-dialog-BT04Mieo.cjs.map +1 -0
- package/dist/{check-confirm-dialog-2j0gOd7x.js → check-confirm-dialog-CtiRzOAt.js} +14 -7
- package/dist/{check-confirm-dialog-2j0gOd7x.js.map → check-confirm-dialog-CtiRzOAt.js.map} +1 -1
- package/dist/{filter-builder-DFu0JP-1.cjs → filter-builder-ByGhxLf_.cjs} +127 -63
- package/dist/filter-builder-ByGhxLf_.cjs.map +1 -0
- package/dist/{filter-builder-DaWHUZuV.js → filter-builder-z3Axzf9Y.js} +114 -56
- package/dist/filter-builder-z3Axzf9Y.js.map +1 -0
- package/dist/{flow-runtime-BpmrIUb6.cjs → flow-runtime-BVFjMU5-.cjs} +6 -3
- package/dist/{flow-runtime-BpmrIUb6.cjs.map → flow-runtime-BVFjMU5-.cjs.map} +1 -1
- package/dist/{flow-runtime-DyqTmK3H.js → flow-runtime-DrUWyTS0.js} +6 -3
- package/dist/{flow-runtime-DyqTmK3H.js.map → flow-runtime-DrUWyTS0.js.map} +1 -1
- package/dist/{flow-screen-DCdli6Ha.js → flow-screen-3fk6J33y.js} +6 -4
- package/dist/flow-screen-3fk6J33y.js.map +1 -0
- package/dist/{flow-screen-Bcz9NF2V.cjs → flow-screen-6y5E_HT6.cjs} +5 -3
- package/dist/flow-screen-6y5E_HT6.cjs.map +1 -0
- package/dist/index.cjs +518 -107
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +187 -86
- package/dist/index.d.ts +187 -86
- package/dist/index.js +519 -108
- package/dist/index.js.map +1 -1
- package/dist/{inline-flow-host-3vw7LzzD.cjs → inline-flow-host-C4KmZIYE.cjs} +3 -3
- package/dist/{inline-flow-host-3vw7LzzD.cjs.map → inline-flow-host-C4KmZIYE.cjs.map} +1 -1
- package/dist/{inline-flow-host-C0rI9B7f.js → inline-flow-host-YnnvWjdU.js} +3 -3
- package/dist/{inline-flow-host-C0rI9B7f.js.map → inline-flow-host-YnnvWjdU.js.map} +1 -1
- package/dist/{lazy-relation-picker-dialog-Bt8lrEIu.cjs → lazy-relation-picker-dialog-BAKBRn3V.cjs} +2 -2
- package/dist/{lazy-relation-picker-dialog-Bt8lrEIu.cjs.map → lazy-relation-picker-dialog-BAKBRn3V.cjs.map} +1 -1
- package/dist/{lazy-relation-picker-dialog-CAScLPb2.js → lazy-relation-picker-dialog-DN4bvQfg.js} +2 -2
- package/dist/{lazy-relation-picker-dialog-CAScLPb2.js.map → lazy-relation-picker-dialog-DN4bvQfg.js.map} +1 -1
- package/dist/{page-flow-route-BHUEpn0I.js → page-flow-route-CtEfqAvU.js} +5 -6
- package/dist/page-flow-route-CtEfqAvU.js.map +1 -0
- package/dist/{page-flow-route-DS8IVTVH.cjs → page-flow-route-DEjAxHe3.cjs} +6 -7
- package/dist/page-flow-route-DEjAxHe3.cjs.map +1 -0
- package/dist/{place-node-CfzQvh4Y.js → place-node-BdxT-30h.js} +149 -108
- package/dist/place-node-BdxT-30h.js.map +1 -0
- package/dist/{place-node-CNb3w-c7.cjs → place-node-Bhl8B3fF.cjs} +163 -134
- package/dist/place-node-Bhl8B3fF.cjs.map +1 -0
- package/dist/{related-list-cards-CelMxl4q.cjs → related-list-cards-Bc_vfCE_.cjs} +3 -3
- package/dist/{related-list-cards-CelMxl4q.cjs.map → related-list-cards-Bc_vfCE_.cjs.map} +1 -1
- package/dist/{related-list-cards-BIqqY69Y.js → related-list-cards-BvkD5OcC.js} +3 -3
- package/dist/{related-list-cards-BIqqY69Y.js.map → related-list-cards-BvkD5OcC.js.map} +1 -1
- package/dist/related-list-timeline-DCrwN9oO.js +167 -0
- package/dist/related-list-timeline-DCrwN9oO.js.map +1 -0
- package/dist/related-list-timeline-k0DtnxTs.cjs +167 -0
- package/dist/related-list-timeline-k0DtnxTs.cjs.map +1 -0
- package/dist/{related-rows-MPnLCmPF.cjs → related-rows-BW9Jr07T.cjs} +3 -3
- package/dist/{related-rows-MPnLCmPF.cjs.map → related-rows-BW9Jr07T.cjs.map} +1 -1
- package/dist/{related-rows--uP2iKQC.js → related-rows-CPE-9FFr.js} +3 -3
- package/dist/{related-rows--uP2iKQC.js.map → related-rows-CPE-9FFr.js.map} +1 -1
- package/dist/{relation-many-picker-BJhaEqxz.js → relation-many-picker-BlrGRwMV.js} +10 -5
- package/dist/relation-many-picker-BlrGRwMV.js.map +1 -0
- package/dist/{relation-many-picker-DzuGJpEl.cjs → relation-many-picker-Br-zBHxT.cjs} +10 -5
- package/dist/relation-many-picker-Br-zBHxT.cjs.map +1 -0
- package/dist/{relation-picker-DaIMzf2H.cjs → relation-picker-ADjxI_TI.cjs} +11 -6
- package/dist/relation-picker-ADjxI_TI.cjs.map +1 -0
- package/dist/{relation-picker-dialog-DoEY8EkH.js → relation-picker-dialog-CyKliBkN.js} +2 -2
- package/dist/{relation-picker-dialog-DoEY8EkH.js.map → relation-picker-dialog-CyKliBkN.js.map} +1 -1
- package/dist/{relation-picker-dialog-9Vg5vvR1.cjs → relation-picker-dialog-DimVQF9Y.cjs} +2 -2
- package/dist/{relation-picker-dialog-9Vg5vvR1.cjs.map → relation-picker-dialog-DimVQF9Y.cjs.map} +1 -1
- package/dist/{relation-picker-D-tBBZW_.js → relation-picker-x7P5HKie.js} +11 -6
- package/dist/relation-picker-x7P5HKie.js.map +1 -0
- package/dist/{resource-page-router-Diw6S6TK.js → resource-page-router-BRpUnhay.js} +144 -17
- package/dist/resource-page-router-BRpUnhay.js.map +1 -0
- package/dist/{resource-page-router-C_kGW2o_.cjs → resource-page-router-qEd2xb55.cjs} +158 -19
- package/dist/resource-page-router-qEd2xb55.cjs.map +1 -0
- package/dist/use-record-subtitle-bfwIoUme.cjs +70 -0
- package/dist/use-record-subtitle-bfwIoUme.cjs.map +1 -0
- package/dist/use-record-subtitle-gIaCGgbI.js +53 -0
- package/dist/use-record-subtitle-gIaCGgbI.js.map +1 -0
- package/package.json +9 -9
- package/dist/bulk-summary-BWSAS7k2.js.map +0 -1
- package/dist/bulk-summary-CrEij5vq.cjs.map +0 -1
- package/dist/check-confirm-dialog-C-NHgMST.cjs.map +0 -1
- package/dist/filter-builder-DFu0JP-1.cjs.map +0 -1
- package/dist/filter-builder-DaWHUZuV.js.map +0 -1
- package/dist/flow-screen-Bcz9NF2V.cjs.map +0 -1
- package/dist/flow-screen-DCdli6Ha.js.map +0 -1
- package/dist/page-flow-route-BHUEpn0I.js.map +0 -1
- package/dist/page-flow-route-DS8IVTVH.cjs.map +0 -1
- package/dist/place-node-CNb3w-c7.cjs.map +0 -1
- package/dist/place-node-CfzQvh4Y.js.map +0 -1
- package/dist/related-list-timeline-CRh7xwLD.js +0 -141
- package/dist/related-list-timeline-CRh7xwLD.js.map +0 -1
- package/dist/related-list-timeline-DsLdi8sv.cjs +0 -141
- package/dist/related-list-timeline-DsLdi8sv.cjs.map +0 -1
- package/dist/relation-many-picker-BJhaEqxz.js.map +0 -1
- package/dist/relation-many-picker-DzuGJpEl.cjs.map +0 -1
- package/dist/relation-picker-D-tBBZW_.js.map +0 -1
- package/dist/relation-picker-DaIMzf2H.cjs.map +0 -1
- package/dist/resource-page-router-C_kGW2o_.cjs.map +0 -1
- package/dist/resource-page-router-Diw6S6TK.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
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
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-
|
|
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-CtiRzOAt.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
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
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";
|
|
8
8
|
import { t as Skeleton } from "./skeleton-U2noefj5.js";
|
|
9
|
-
import { $ as CursorLoadMore, A as ListSearchInput, At as
|
|
9
|
+
import { $ as CursorLoadMore, A as ListSearchInput, At as AppFlowButton, B as ExportDialog, C as ListControls, D as ListFlows, Dt as EnumSettlingRow, E as ListLive, Et as EnumBadge, F as ListColumns, Ft as toDisplayText, H as ScreenTree, I as ColumnsToggle, It as ShellProvider, L as DataTableViewOptions, Lt as defaultUserMapper, M as ExportButton, Mt as FieldDisplay, N as ListCreate, Nt as i18nPrefixToRef, O as ListFilters, Ot as unknownEnumValueLabel, P as CreateButton, Pt as FieldValueFrame, Q as ResourceList, R as ListBulkBar, Rt as usePaletteState, St as ActionOverflow, T as SavedViewsDropdown, Tt as downloadArtifact, V as DeclarativeForm, W as QuickScreenClaimContext, Y as useFormControl, Z as ListBody, _ as CopyId, _t as ShowPageHeader, a as peekFieldDefinition, at as DataTable, b as RecordTitle, bt as useDocumentTitle, c as peekRow, ct as TabsContent, d as resolveFrameView, et as ListErrorState, f as shadcnFrameViews, gt as PageHeader, ht as EditPageHeader, it as useBuroDataTable, j as ListExport, jt as Field, k as FilterRegion, l as useRelationPicker, lt as TabsList, 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 resolveResourceTitle, w as ListSavedViews, wt as useExportRunWatcher, xt as typography, y as RecordActions, yt as DocumentTitleProvider, z as BulkActionToolbar, zt as useShell } from "./place-node-BdxT-30h.js";
|
|
10
10
|
import { THEME_STORAGE_KEY } from "./layout/theme-storage-key.js";
|
|
11
|
-
import { A as
|
|
12
|
-
import { A as
|
|
11
|
+
import { A as TableHeader, B as DEFAULT_LANGUAGE_STORAGE_KEY, C as SelectTrigger, D as TableCaption, E as TableBody, F as ResolvedFieldDisplay, H as saveLocale, M as Badge, N as badgeVariants, O as TableCell, S as SelectSeparator, T as Table, V as loadLocale, _ as SelectGroup, a as PinnedFilterControls, b as SelectScrollDownButton, c as fromLocalDateTimeText, d as useFieldTimeZone, f as FilterBadges, g as SelectContent, h as Select, i as FacetedFilterPicker, j as TableRow, k as TableHead, l as toLocalDateTimeText, m as localeTag, n as PresetFilterControls, o as FilterPanel, p as formatNumber, r as DataTableFacetedFilter, s as FilterValueControl, t as FilterBuilder, u as dateDisplayParams, v as SelectItem, w as SelectValue, x as SelectScrollUpButton, y as SelectLabel, z as lowerLegacyField } from "./filter-builder-z3Axzf9Y.js";
|
|
12
|
+
import { A as useLayoutResolver, C as useMatch, D as BUILTIN_LAYOUTS, E as useResourceVisible, F as canonicalResourceKey$1, M as TabsLayout, N as SecondarySidebarLayout, O as layoutSlot, P as canonicalNavKey, S as useHref, T as usePageAllowed, _ as RecordScreen, a as useRecordVisit, b as ResourceListPage, c as headerTrail, d as recordTrailRoute, f as useTrailContext, g as usePublishedRecordTrail, i as RecordPage, j as useReportUnresolvedLayouts, k as useLayout, l as originTrail, m as recordTrailKey, n as NavAreaPage, o as RECENT_LABEL_KEYS, p as isShowAvailable, r as ResourcePageRouter, s as readRecentRecords, u as recordTrail, v as useResourceDimensionOptions, w as useNavVisible, x as NavChromeMountedProvider, y as PlannedBody } from "./resource-page-router-BRpUnhay.js";
|
|
13
13
|
import { t as Label } from "./label-66W1qbke.js";
|
|
14
|
-
import { t as LazyRelationPickerDialog } from "./lazy-relation-picker-dialog-
|
|
15
|
-
import { n as
|
|
14
|
+
import { t as LazyRelationPickerDialog } from "./lazy-relation-picker-dialog-DN4bvQfg.js";
|
|
15
|
+
import { n as useRecordSubtitle, r as useRowSubtitle } from "./use-record-subtitle-gIaCGgbI.js";
|
|
16
|
+
import { n as RelationPicker, r as RelationPickerInput } from "./relation-picker-x7P5HKie.js";
|
|
16
17
|
import { t as useDialogFilterState } from "./use-dialog-filter-state-B_MqzHaT.js";
|
|
17
18
|
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";
|
|
19
|
+
import { ENUM_CONTROLS, builtinFrames, canonicalInstant, columnName, compilePageScreen, compiledScreenFor, declaredField, declaredText, dtoFields, effectiveFlow, enumFallbackKey, enumFallbackText, enumNamespaceOf, enumValueText, epochMsToInstant, evaluateVisible, fieldOptionText, formatEntityRef, formatTimeValue, hasListPage, hasRecordPage, hrefFor, humanizeKey, isCalendarDate, 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, zoneShortName } from "@burojs/core";
|
|
20
|
+
import { ComponentsContext, DispatcherProvider, I18nContext, NO_RECORD_SCOPE_FRAMES, QUICK_ANCHOR_ATTRIBUTE, QuickEntryContext, RecordScopeChain, RouteSourceContext, ScreenStateProvider, formatBytes, optionFieldName, recordRouteAvailable, resolveErrorText, resolveOptionLabel, retryRecordRead, useApp, useAppActions, useApplicationSnapshot, useAvailabilityGate, useAvailableEnumValues, useBoundEnum, useCapabilityResolver, useChangeLocale, useChromeT, useCommandPalette, useCurrentUserId, useDebouncedValue, useDispatcherEffects, useDocPanel, useDocScopes, useDocTopics, useDocTrailScopes, useDocsConfig, useDocumentedScopes, useEntryGate, useEnumValues, useFieldAccess, useFieldMetaSources, useFileField, useFileUrls, useFormController, useFrameImplementations, useFrameT, useI18nCaps, useIdentity, useLanguageStorageKey, useLinkKeys, useList, useListAccess, useLocale, useLogout, useNavigationGuardText, useNavigationOrigin, useOne, useOptionCaps, useOptionalApp, useOptionalAuthController, useOptionalDataRuntime, useOptionalFileStorage, useOptionalLocale, useOptionalRouterAdapter, useOptionalT, useOriginIntent, usePlatformStorage, usePresentBlock, useProjectedRecord, useProjectedTitle, usePublishOriginTitle, useQuick, useQuickEntry, useQuickEntryValue, useQuickOpener, useRecordTitle, useRefresh, useRegisterNavigationGuardDialog, useRelatedRecord, useRouteNavigate, useRouteRecordId, useRouterAdapter, useScope, useT, useTestIds, useTimeZone, useUIInstance, useUIPresentationRuntime, useVisibilityCtx } from "@burojs/react";
|
|
21
|
+
import { IconAlertCircle, IconArrowDown, IconArrowLeft, IconArrowUp, IconArrowUpRight, IconBook2, IconCheck, IconChevronDown, IconChevronRight, IconDeviceDesktop, IconDots, IconExternalLink, IconHelp, IconHelpHexagon, IconLayoutSidebar, IconLoader2, IconLogin, IconLogout, IconMaximize, IconMinimize, IconMoon, IconPlus, IconRefresh, IconRotate, IconSearch, IconSelector, IconSun, IconTrash, IconUpload, IconUser, IconX } from "@tabler/icons-react";
|
|
21
22
|
import * as React from "react";
|
|
22
23
|
import { Children, Fragment, Suspense, cloneElement, createContext, createElement, isValidElement, lazy, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
23
24
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -29,7 +30,7 @@ import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
|
|
29
30
|
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
|
|
30
31
|
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
31
32
|
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
|
32
|
-
import { enumBindingKey } from "@burojs/core/internal";
|
|
33
|
+
import { enumBindingKey, enumParamsOf, narrowEntriesOf } from "@burojs/core/internal";
|
|
33
34
|
import { Controller, FormProvider, useForm, useFormContext } from "react-hook-form";
|
|
34
35
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
35
36
|
import { z } from "zod";
|
|
@@ -1974,6 +1975,10 @@ function NavMain({ topLabel, iconForResource, iconForCustomPage, iconForSection,
|
|
|
1974
1975
|
const t = useT();
|
|
1975
1976
|
const RouterLink = useLinkComponent();
|
|
1976
1977
|
const navIcon = useNavIcon();
|
|
1978
|
+
const intent = useOriginIntent();
|
|
1979
|
+
const jump = (entry) => () => {
|
|
1980
|
+
if (entry.href !== void 0) intent(entry.href, "jump");
|
|
1981
|
+
};
|
|
1977
1982
|
const ownOr = (own, name) => own !== void 0 ? own : navIcon(name);
|
|
1978
1983
|
const groupAsSection = (key) => app.registry.sections.get(key) ?? app.registry.groups.get(key);
|
|
1979
1984
|
const sectionIcon = (key, name) => {
|
|
@@ -2000,6 +2005,7 @@ function NavMain({ topLabel, iconForResource, iconForCustomPage, iconForSection,
|
|
|
2000
2005
|
href: entry.href ?? "",
|
|
2001
2006
|
"aria-current": entry.active ? "page" : void 0,
|
|
2002
2007
|
"data-testid": entryTestId(entry),
|
|
2008
|
+
onClick: jump(entry),
|
|
2003
2009
|
children: [icon != null && jsx("span", {
|
|
2004
2010
|
className: "inline-flex h-4 w-4 items-center justify-center",
|
|
2005
2011
|
"aria-hidden": "true",
|
|
@@ -2015,6 +2021,7 @@ function NavMain({ topLabel, iconForResource, iconForCustomPage, iconForSection,
|
|
|
2015
2021
|
href: entry.href ?? "",
|
|
2016
2022
|
"aria-current": entry.active ? "page" : void 0,
|
|
2017
2023
|
"data-testid": entryTestId(entry),
|
|
2024
|
+
onClick: jump(entry),
|
|
2018
2025
|
children: jsx("span", { children: entry.label })
|
|
2019
2026
|
})
|
|
2020
2027
|
}) }, entry.key);
|
|
@@ -2128,11 +2135,17 @@ function Breadcrumbs(input) {
|
|
|
2128
2135
|
const t = useOptionalT();
|
|
2129
2136
|
const RouterLink = useLinkComponent();
|
|
2130
2137
|
const caps = useI18nCaps(def?.name);
|
|
2138
|
+
const intent = useOriginIntent();
|
|
2139
|
+
const onJump = (seg) => {
|
|
2140
|
+
const href = seg.href;
|
|
2141
|
+
return seg.jump === true && href !== void 0 ? () => intent(href, "jump") : void 0;
|
|
2142
|
+
};
|
|
2131
2143
|
const trailScopes = useDocTrailScopes(def?.name);
|
|
2132
2144
|
const leading = (name) => leadingSegments?.map((seg, i) => jsxs("span", {
|
|
2133
2145
|
className: "flex min-w-0 items-center gap-1",
|
|
2134
2146
|
children: [seg.href ? jsx(RouterLink, {
|
|
2135
2147
|
href: seg.href,
|
|
2148
|
+
onClick: onJump(seg),
|
|
2136
2149
|
"data-testid": `${tid.navBreadcrumb(name)}:lead:${i}`,
|
|
2137
2150
|
className: cn(LINK_CLASS, "truncate"),
|
|
2138
2151
|
title: seg.label,
|
|
@@ -2167,9 +2180,34 @@ function Breadcrumbs(input) {
|
|
|
2167
2180
|
]
|
|
2168
2181
|
});
|
|
2169
2182
|
if (!def) return null;
|
|
2170
|
-
const { recordId, pageLabel, middleSegments } = props;
|
|
2183
|
+
const { recordId, pageLabel, middleSegments, rootSegments } = props;
|
|
2171
2184
|
const resourceKey = canonicalResourceKey$1(def);
|
|
2172
|
-
|
|
2185
|
+
if (rootSegments !== void 0 && rootSegments.length > 0) return jsxs("nav", {
|
|
2186
|
+
className: navClass,
|
|
2187
|
+
"aria-label": ariaLabel,
|
|
2188
|
+
"data-testid": testId,
|
|
2189
|
+
children: [
|
|
2190
|
+
rootSegments.map((seg, i) => jsxs("span", {
|
|
2191
|
+
className: "flex min-w-0 items-center gap-1",
|
|
2192
|
+
children: [i > 0 && jsx(Chevron, {}), seg.href ? jsx(RouterLink, {
|
|
2193
|
+
href: seg.href,
|
|
2194
|
+
onClick: onJump(seg),
|
|
2195
|
+
"data-testid": `${tid.navBreadcrumb(resourceKey)}:root:${i}`,
|
|
2196
|
+
className: cn(LINK_CLASS, "truncate"),
|
|
2197
|
+
title: seg.label,
|
|
2198
|
+
children: seg.label
|
|
2199
|
+
}) : jsx("span", {
|
|
2200
|
+
"data-testid": `${tid.navBreadcrumb(resourceKey)}:root:${i}`,
|
|
2201
|
+
className: "truncate",
|
|
2202
|
+
title: seg.label,
|
|
2203
|
+
children: seg.label
|
|
2204
|
+
})]
|
|
2205
|
+
}, `root:${i}:${seg.label}`)),
|
|
2206
|
+
pageLabel && jsxs(Fragment$1, { children: [jsx(Chevron, {}), current(tid.navBreadcrumb(resourceKey, recordId), pageLabel)] }),
|
|
2207
|
+
help
|
|
2208
|
+
]
|
|
2209
|
+
});
|
|
2210
|
+
const listHref = props.resourceHref ?? hrefFor(app.registry, resourceKey);
|
|
2173
2211
|
const resourceLabel = resolveResourceLabel(caps, resourceKey, "plural", def);
|
|
2174
2212
|
const resourceIsCurrent = !pageLabel && !(middleSegments && middleSegments.length > 0);
|
|
2175
2213
|
return jsxs("nav", {
|
|
@@ -2194,6 +2232,7 @@ function Breadcrumbs(input) {
|
|
|
2194
2232
|
className: "flex min-w-0 items-center gap-1",
|
|
2195
2233
|
children: [jsx(Chevron, {}), seg.href ? jsx(RouterLink, {
|
|
2196
2234
|
href: seg.href,
|
|
2235
|
+
onClick: onJump(seg),
|
|
2197
2236
|
"data-testid": `${tid.navBreadcrumb(resourceKey)}:mid:${i}`,
|
|
2198
2237
|
className: cn(LINK_CLASS, "truncate"),
|
|
2199
2238
|
title: seg.label,
|
|
@@ -2211,6 +2250,12 @@ function Breadcrumbs(input) {
|
|
|
2211
2250
|
}
|
|
2212
2251
|
//#endregion
|
|
2213
2252
|
//#region src/layout/record-breadcrumbs.tsx
|
|
2253
|
+
function viewOrigin(ctx, trail, resource) {
|
|
2254
|
+
if (trail === void 0 || trail.resource === void 0 || trail.segments.length > 0) return void 0;
|
|
2255
|
+
const target = ctx.registry.get(trail.resource)?.routesTo?.show;
|
|
2256
|
+
if (target === void 0 || ctx.registry.get(target) !== ctx.registry.get(resource)) return void 0;
|
|
2257
|
+
return trail.resource;
|
|
2258
|
+
}
|
|
2214
2259
|
function RecordBreadcrumbs() {
|
|
2215
2260
|
const ctx = useTrailContext();
|
|
2216
2261
|
const match = useMatch();
|
|
@@ -2218,9 +2263,17 @@ function RecordBreadcrumbs() {
|
|
|
2218
2263
|
const route = recordTrailRoute(ctx.registry, match);
|
|
2219
2264
|
const published = usePublishedRecordTrail(route === null ? "" : recordTrailKey(route.resource, route.id, route.flow === void 0 ? route.action : `flow:${route.flow}`));
|
|
2220
2265
|
const idTitle = useRecordTitle(route?.resource, route?.id);
|
|
2266
|
+
usePublishOriginTitle(published?.title || void 0);
|
|
2267
|
+
const origin = useNavigationOrigin();
|
|
2268
|
+
const rooted = origin === null ? void 0 : originTrail(ctx, origin);
|
|
2269
|
+
const view = route === null ? void 0 : viewOrigin(ctx, rooted, route.resource);
|
|
2270
|
+
const viewScopes = useDocTrailScopes(view);
|
|
2271
|
+
const ownScopes = useDocTrailScopes(view === void 0 ? void 0 : route?.resource);
|
|
2272
|
+
const docScopes = view === void 0 ? {} : { docScopes: [...new Set([...viewScopes, ...ownScopes])] };
|
|
2221
2273
|
if (route === null || match === null) return null;
|
|
2222
2274
|
const { resource, id, groupChain } = route;
|
|
2223
2275
|
const title = published?.title ?? idTitle;
|
|
2276
|
+
const withOrigin = rooted === void 0 ? {} : { origin: rooted };
|
|
2224
2277
|
if (route.flow !== void 0) {
|
|
2225
2278
|
if (effectiveFlow(snapshot, match.ref, route.flow) === void 0) return null;
|
|
2226
2279
|
const flowLabel = published?.flowLabel;
|
|
@@ -2230,8 +2283,10 @@ function RecordBreadcrumbs() {
|
|
|
2230
2283
|
action: "show",
|
|
2231
2284
|
id,
|
|
2232
2285
|
title: idTitle,
|
|
2233
|
-
groupChain
|
|
2286
|
+
groupChain,
|
|
2287
|
+
...withOrigin
|
|
2234
2288
|
}),
|
|
2289
|
+
...docScopes,
|
|
2235
2290
|
"data-testid": "record-breadcrumbs"
|
|
2236
2291
|
});
|
|
2237
2292
|
return jsx(Breadcrumbs, {
|
|
@@ -2240,8 +2295,10 @@ function RecordBreadcrumbs() {
|
|
|
2240
2295
|
action: "edit",
|
|
2241
2296
|
id,
|
|
2242
2297
|
title,
|
|
2243
|
-
groupChain
|
|
2298
|
+
groupChain,
|
|
2299
|
+
...withOrigin
|
|
2244
2300
|
}),
|
|
2301
|
+
...docScopes,
|
|
2245
2302
|
pageLabel: flowLabel,
|
|
2246
2303
|
"data-testid": "record-breadcrumbs"
|
|
2247
2304
|
});
|
|
@@ -2252,8 +2309,10 @@ function RecordBreadcrumbs() {
|
|
|
2252
2309
|
action: route.action,
|
|
2253
2310
|
id,
|
|
2254
2311
|
title,
|
|
2255
|
-
groupChain
|
|
2312
|
+
groupChain,
|
|
2313
|
+
...withOrigin
|
|
2256
2314
|
}),
|
|
2315
|
+
...docScopes,
|
|
2257
2316
|
"data-testid": "record-breadcrumbs"
|
|
2258
2317
|
});
|
|
2259
2318
|
}
|
|
@@ -2598,7 +2657,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
|
|
|
2598
2657
|
}, [app, visibilityCtx]);
|
|
2599
2658
|
const goTo = (href) => {
|
|
2600
2659
|
onSelect?.();
|
|
2601
|
-
navigate(href);
|
|
2660
|
+
navigate(href, { origin: "jump" });
|
|
2602
2661
|
};
|
|
2603
2662
|
const resourceLabel = (def) => resolveResourceLabel(caps, canonicalResourceKey$1(def), "plural", def);
|
|
2604
2663
|
const pageLabel = (def) => resolveNavLabel(caps, `pages.${canonicalNavKey(def)}`, declaredText("chrome", def, "label"));
|
|
@@ -2802,7 +2861,7 @@ function CommandPaletteRecentGroup({ onSelect, getTestId, heading, refreshKey, w
|
|
|
2802
2861
|
const goTo = (href, entry) => {
|
|
2803
2862
|
onSelect?.();
|
|
2804
2863
|
if (href === null) quick.show(entry.canonicalRef, entry.id);
|
|
2805
|
-
else navigate(href);
|
|
2864
|
+
else navigate(href, { origin: "jump" });
|
|
2806
2865
|
};
|
|
2807
2866
|
return jsxs(Fragment, { children: [jsx(CommandGroup, {
|
|
2808
2867
|
heading: resolvedHeading,
|
|
@@ -2877,7 +2936,7 @@ function CommandPaletteRecordsGroup({ enabled = true, pageSize = 5, minQueryLeng
|
|
|
2877
2936
|
const goTo = (href, resource, id) => {
|
|
2878
2937
|
onSelect?.();
|
|
2879
2938
|
if (href === null) quick.show(resource, id);
|
|
2880
|
-
else navigate(href);
|
|
2939
|
+
else navigate(href, { origin: "jump" });
|
|
2881
2940
|
};
|
|
2882
2941
|
return jsx(CommandGroup, {
|
|
2883
2942
|
heading: resolvedHeading,
|
|
@@ -2915,6 +2974,7 @@ function PerResourceSearchHits({ def, displayField, query, pageSize, goTo, recor
|
|
|
2915
2974
|
enabled: shouldFetch
|
|
2916
2975
|
});
|
|
2917
2976
|
const report = useCommandPaletteResults(`records:${resource}`);
|
|
2977
|
+
const rowSubtitle = useRowSubtitle(resource);
|
|
2918
2978
|
const rows = !shouldFetch || q.isLoading || q.isError ? [] : q.data?.data ?? [];
|
|
2919
2979
|
useEffect(() => {
|
|
2920
2980
|
report(rows.length);
|
|
@@ -2929,16 +2989,25 @@ function PerResourceSearchHits({ def, displayField, query, pageSize, goTo, recor
|
|
|
2929
2989
|
if (!id) return null;
|
|
2930
2990
|
const display = titleVisible ? row[displayField] : void 0;
|
|
2931
2991
|
const labelText = typeof display === "string" && display.length > 0 ? display : id;
|
|
2992
|
+
const subtitle = rowSubtitle(row) ?? null;
|
|
2932
2993
|
const href = recordHref ? recordHref(resource, id) : isShowAvailable(registry, resource) ? resourceShowHref(registry, def, resource, id) : null;
|
|
2933
2994
|
return jsxs(CommandItem, {
|
|
2934
2995
|
value: `record:${resource}:${id}:${labelText}`,
|
|
2935
2996
|
forceMount: true,
|
|
2936
2997
|
onSelect: () => goTo(href, resource, id),
|
|
2937
2998
|
"data-testid": getTestId?.("records-record", `${resource}:${id}`),
|
|
2938
|
-
children: [
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2999
|
+
children: [
|
|
3000
|
+
jsxs("span", {
|
|
3001
|
+
className: "text-muted-foreground group-data-[selected=true]:text-accent-foreground mr-2",
|
|
3002
|
+
children: [resourceLabel, ":"]
|
|
3003
|
+
}),
|
|
3004
|
+
labelText,
|
|
3005
|
+
subtitle === null ? null : jsx("span", {
|
|
3006
|
+
"data-buro-region": "record-subtitle",
|
|
3007
|
+
className: "ml-auto truncate pl-2 text-xs text-muted-foreground group-data-[selected=true]:text-accent-foreground",
|
|
3008
|
+
children: subtitle
|
|
3009
|
+
})
|
|
3010
|
+
]
|
|
2942
3011
|
}, `record:${resource}:${id}`);
|
|
2943
3012
|
}) });
|
|
2944
3013
|
}
|
|
@@ -3086,7 +3155,7 @@ function CommandPaletteCreateGroup({ resourceFilter, onSelect, getTestId, headin
|
|
|
3086
3155
|
]);
|
|
3087
3156
|
if (visibleResources.length === 0) return null;
|
|
3088
3157
|
const goTo = (href) => {
|
|
3089
|
-
navigate(href);
|
|
3158
|
+
navigate(href, { origin: "jump" });
|
|
3090
3159
|
onSelect?.();
|
|
3091
3160
|
};
|
|
3092
3161
|
const createIn = (def, href) => {
|
|
@@ -3434,7 +3503,7 @@ const NONE = "__none__";
|
|
|
3434
3503
|
function isEmpty$1(value) {
|
|
3435
3504
|
return value === null || value === void 0 || value === "";
|
|
3436
3505
|
}
|
|
3437
|
-
function EnumChoiceGroup({ control, options, value, onChange, testid, name, id, required, disabled, ariaInvalid, ariaDescribedBy, ariaErrorMessage, ariaLabelledBy, className }) {
|
|
3506
|
+
function EnumChoiceGroup({ control, options, current, settling, value, onChange, testid, name, id, required, disabled, ariaInvalid, ariaDescribedBy, ariaErrorMessage, ariaLabelledBy, className }) {
|
|
3438
3507
|
const t = useOptionalT();
|
|
3439
3508
|
const generatedName = React.useId();
|
|
3440
3509
|
const groupName = name ?? generatedName;
|
|
@@ -3449,16 +3518,25 @@ function EnumChoiceGroup({ control, options, value, onChange, testid, name, id,
|
|
|
3449
3518
|
...ariaErrorMessage ? { "aria-errormessage": ariaErrorMessage } : {}
|
|
3450
3519
|
};
|
|
3451
3520
|
if (control === "segmented") {
|
|
3452
|
-
const
|
|
3521
|
+
const segmentLabel = (option) => jsxs(Fragment$1, { children: [option.icon ? jsx("span", {
|
|
3522
|
+
"data-testid": `${testid}:option:${option.value}:icon`,
|
|
3523
|
+
className: "contents",
|
|
3524
|
+
children: jsx(Icon, {
|
|
3525
|
+
name: option.icon,
|
|
3526
|
+
className: "size-3.5 shrink-0"
|
|
3527
|
+
})
|
|
3528
|
+
}) : null, option.label] });
|
|
3529
|
+
const segment = (key, label, active, select, currentItem = false) => jsx("button", {
|
|
3453
3530
|
type: "button",
|
|
3454
3531
|
"aria-pressed": active,
|
|
3455
3532
|
"data-state": active ? "active" : "inactive",
|
|
3456
|
-
"data-testid": `${testid}:option:${key}`,
|
|
3457
|
-
|
|
3533
|
+
"data-testid": currentItem ? `${testid}:current` : `${testid}:option:${key}`,
|
|
3534
|
+
...currentItem ? { "data-current": "" } : {},
|
|
3535
|
+
disabled: disabled || currentItem,
|
|
3458
3536
|
onClick: select,
|
|
3459
3537
|
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
3538
|
children: label
|
|
3461
|
-
}, key);
|
|
3539
|
+
}, currentItem ? `current:${key}` : key);
|
|
3462
3540
|
return jsxs("div", {
|
|
3463
3541
|
role: "group",
|
|
3464
3542
|
id,
|
|
@@ -3466,22 +3544,24 @@ function EnumChoiceGroup({ control, options, value, onChange, testid, name, id,
|
|
|
3466
3544
|
"data-testid": testid,
|
|
3467
3545
|
className: cn("inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground", className),
|
|
3468
3546
|
...ariaProps,
|
|
3469
|
-
children: [
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
})
|
|
3476
|
-
|
|
3547
|
+
children: [
|
|
3548
|
+
current === void 0 ? null : segment(current.value, segmentLabel(current), true, () => void 0, true),
|
|
3549
|
+
required || settling !== void 0 ? null : segment(NONE, noneLabel, empty, () => pick(void 0)),
|
|
3550
|
+
settling === void 0 ? null : jsx(EnumSettlingRow, {
|
|
3551
|
+
status: settling,
|
|
3552
|
+
testid
|
|
3553
|
+
}),
|
|
3554
|
+
options.map((option) => segment(option.value, segmentLabel(option), value === option.value, () => pick(option.value)))
|
|
3555
|
+
]
|
|
3477
3556
|
});
|
|
3478
3557
|
}
|
|
3479
3558
|
const cards = control === "cards";
|
|
3480
|
-
const choice = (key, option, label, checked, select) => {
|
|
3481
|
-
const inputId = `${id ?? groupName}:${key}`;
|
|
3559
|
+
const choice = (key, option, label, checked, select, currentItem = false) => {
|
|
3560
|
+
const inputId = `${id ?? groupName}:${currentItem ? "current:" : ""}${key}`;
|
|
3561
|
+
const inert = disabled || currentItem;
|
|
3482
3562
|
return jsxs("label", {
|
|
3483
3563
|
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"),
|
|
3564
|
+
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"), inert && "cursor-not-allowed opacity-60"),
|
|
3485
3565
|
children: [jsx("input", {
|
|
3486
3566
|
type: "radio",
|
|
3487
3567
|
id: inputId,
|
|
@@ -3489,9 +3569,10 @@ function EnumChoiceGroup({ control, options, value, onChange, testid, name, id,
|
|
|
3489
3569
|
value: key,
|
|
3490
3570
|
checked,
|
|
3491
3571
|
onChange: select,
|
|
3492
|
-
disabled,
|
|
3572
|
+
disabled: inert,
|
|
3493
3573
|
...ariaProps,
|
|
3494
|
-
"data-testid": `${testid}:option:${key}`,
|
|
3574
|
+
"data-testid": currentItem ? `${testid}:current` : `${testid}:option:${key}`,
|
|
3575
|
+
...currentItem ? { "data-current": "" } : {},
|
|
3495
3576
|
className: cn("h-4 w-4 shrink-0 accent-primary", cards ? "mt-0.5" : "mt-1")
|
|
3496
3577
|
}), jsxs("span", {
|
|
3497
3578
|
className: "flex min-w-0 flex-col gap-0.5",
|
|
@@ -3511,7 +3592,7 @@ function EnumChoiceGroup({ control, options, value, onChange, testid, name, id,
|
|
|
3511
3592
|
children: option.summary
|
|
3512
3593
|
})]
|
|
3513
3594
|
})]
|
|
3514
|
-
}, key);
|
|
3595
|
+
}, currentItem ? `current:${key}` : key);
|
|
3515
3596
|
};
|
|
3516
3597
|
return jsxs("div", {
|
|
3517
3598
|
role: "radiogroup",
|
|
@@ -3520,7 +3601,15 @@ function EnumChoiceGroup({ control, options, value, onChange, testid, name, id,
|
|
|
3520
3601
|
"data-testid": testid,
|
|
3521
3602
|
"aria-required": required,
|
|
3522
3603
|
className: cn("flex flex-col", cards ? "gap-2" : "gap-1.5", className),
|
|
3523
|
-
children: [
|
|
3604
|
+
children: [
|
|
3605
|
+
current === void 0 ? null : choice(current.value, current, current.label, true, () => void 0, true),
|
|
3606
|
+
required || settling !== void 0 ? null : choice(NONE, void 0, noneLabel, empty, () => pick(void 0)),
|
|
3607
|
+
settling === void 0 ? null : jsx(EnumSettlingRow, {
|
|
3608
|
+
status: settling,
|
|
3609
|
+
testid
|
|
3610
|
+
}),
|
|
3611
|
+
options.map((option) => choice(option.value, option, option.label, value === option.value, () => pick(option.value)))
|
|
3612
|
+
]
|
|
3524
3613
|
});
|
|
3525
3614
|
}
|
|
3526
3615
|
//#endregion
|
|
@@ -3529,7 +3618,7 @@ const ENUM_PICKER_CLEAR_SENTINEL = "__buro_clear__";
|
|
|
3529
3618
|
function withSummary(summary) {
|
|
3530
3619
|
return summary === void 0 ? {} : { summary };
|
|
3531
3620
|
}
|
|
3532
|
-
function EnumPicker({ enumName: enumInput, value, onChange, control = "select", name, id, testid, placeholder, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage, ariaLabelledBy, className, clearable = false, clearLabel = "All" }) {
|
|
3621
|
+
function EnumPicker({ enumName: enumInput, value, onChange, control = "select", name, id, testid, placeholder, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage, ariaLabelledBy, className, clearable = false, clearLabel = "All", use }) {
|
|
3533
3622
|
const enumName = enumBindingKey(enumInput) ?? "";
|
|
3534
3623
|
const app = useApp();
|
|
3535
3624
|
const t = useOptionalT();
|
|
@@ -3537,6 +3626,11 @@ function EnumPicker({ enumName: enumInput, value, onChange, control = "select",
|
|
|
3537
3626
|
const caps = useI18nCaps();
|
|
3538
3627
|
const ns = def?.i18nNamespace ?? enumName;
|
|
3539
3628
|
const { values, isLoading, error } = useEnumValues(enumName);
|
|
3629
|
+
const available = useAvailableEnumValues({
|
|
3630
|
+
values: isLoading || values === void 0 ? "pending" : values,
|
|
3631
|
+
...def === void 0 ? {} : { enum: def },
|
|
3632
|
+
...use === void 0 ? {} : { use }
|
|
3633
|
+
});
|
|
3540
3634
|
const tid = testid ?? `enum-picker:${enumName}`;
|
|
3541
3635
|
if (!def) return jsxs("span", {
|
|
3542
3636
|
"data-testid": `${tid}:unregistered`,
|
|
@@ -3578,9 +3672,22 @@ function EnumPicker({ enumName: enumInput, value, onChange, control = "select",
|
|
|
3578
3672
|
});
|
|
3579
3673
|
const labelOf = (entry) => resolveEnumLabel(caps, ns, entry.value, enumValueText(def, entry.value) ?? entry.label);
|
|
3580
3674
|
const summaryOf = (entry) => resolveDoc(caps, `enum/${ns}/${entry.value}`)?.summary || void 0;
|
|
3675
|
+
const settling = available.status === "ready" ? void 0 : available.status;
|
|
3676
|
+
const offered = settling === void 0 ? available.values : [];
|
|
3677
|
+
const known = value == null ? void 0 : values.find((entry) => entry.value === value);
|
|
3678
|
+
const current = value == null || value === "" || offered.some((entry) => entry.value === value) ? void 0 : known === void 0 ? {
|
|
3679
|
+
value,
|
|
3680
|
+
label: unknownEnumValueLabel(caps, def, ns, value).label
|
|
3681
|
+
} : {
|
|
3682
|
+
value,
|
|
3683
|
+
label: labelOf(known),
|
|
3684
|
+
...known.icon === void 0 ? {} : { icon: known.icon }
|
|
3685
|
+
};
|
|
3581
3686
|
if (control !== "select") return jsx(EnumChoiceGroup, {
|
|
3582
3687
|
control,
|
|
3583
|
-
|
|
3688
|
+
...current === void 0 ? {} : { current },
|
|
3689
|
+
...settling === void 0 ? {} : { settling },
|
|
3690
|
+
options: offered.map((entry) => ({
|
|
3584
3691
|
value: entry.value,
|
|
3585
3692
|
label: labelOf(entry),
|
|
3586
3693
|
...entry.icon === void 0 ? {} : { icon: entry.icon },
|
|
@@ -3617,28 +3724,43 @@ function EnumPicker({ enumName: enumInput, value, onChange, control = "select",
|
|
|
3617
3724
|
name,
|
|
3618
3725
|
id,
|
|
3619
3726
|
"aria-required": required,
|
|
3727
|
+
"aria-busy": settling === "pending" || void 0,
|
|
3620
3728
|
"aria-invalid": ariaInvalid || void 0,
|
|
3621
3729
|
"aria-describedby": ariaDescribedBy,
|
|
3622
3730
|
...ariaErrorMessage ? { "aria-errormessage": ariaErrorMessage } : {},
|
|
3623
3731
|
className,
|
|
3624
3732
|
children: jsx(SelectValue, { placeholder: placeholder ?? t("field.select", { defaultValue: "Select…" }) })
|
|
3625
|
-
}), jsxs(SelectContent, { children: [
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
"data-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3733
|
+
}), jsxs(SelectContent, { children: [
|
|
3734
|
+
clearable && jsx(SelectItem, {
|
|
3735
|
+
value: "__buro_clear__",
|
|
3736
|
+
"data-testid": `${tid}:option:__clear__`,
|
|
3737
|
+
children: clearLabel
|
|
3738
|
+
}),
|
|
3739
|
+
current === void 0 ? null : jsx(SelectItem, {
|
|
3740
|
+
value: current.value,
|
|
3741
|
+
disabled: true,
|
|
3742
|
+
"data-current": "",
|
|
3743
|
+
"data-testid": `${tid}:current`,
|
|
3744
|
+
children: current.label
|
|
3745
|
+
}),
|
|
3746
|
+
settling === void 0 ? null : jsx(EnumSettlingRow, {
|
|
3747
|
+
status: settling,
|
|
3748
|
+
testid: tid
|
|
3749
|
+
}),
|
|
3750
|
+
offered.map((entry) => {
|
|
3751
|
+
const optionLabel = labelOf(entry);
|
|
3752
|
+
const optionDoc = summaryOf(entry);
|
|
3753
|
+
return jsx(SelectItem, {
|
|
3754
|
+
value: entry.value,
|
|
3755
|
+
"data-testid": `${tid}:option:${entry.value}`,
|
|
3756
|
+
description: optionDoc === void 0 ? void 0 : jsx("span", {
|
|
3757
|
+
"data-testid": `${tid}:option:${entry.value}:doc`,
|
|
3758
|
+
children: optionDoc
|
|
3759
|
+
}),
|
|
3760
|
+
children: optionLabel
|
|
3761
|
+
}, entry.value);
|
|
3762
|
+
})
|
|
3763
|
+
] })]
|
|
3642
3764
|
});
|
|
3643
3765
|
}
|
|
3644
3766
|
//#endregion
|
|
@@ -3688,41 +3810,63 @@ function BooleanInput({ name, id, value, onChange, testid, disabled, required, a
|
|
|
3688
3810
|
}
|
|
3689
3811
|
//#endregion
|
|
3690
3812
|
//#region src/fields/date.tsx
|
|
3691
|
-
function DateDisplay(
|
|
3813
|
+
function DateDisplay(props) {
|
|
3692
3814
|
return jsx(TemporalDisplay, {
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
format: formatDate
|
|
3815
|
+
kind: "date",
|
|
3816
|
+
...props
|
|
3696
3817
|
});
|
|
3697
3818
|
}
|
|
3698
|
-
function DateTimeDisplay(
|
|
3819
|
+
function DateTimeDisplay(props) {
|
|
3699
3820
|
return jsx(TemporalDisplay, {
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3821
|
+
kind: "dateTime",
|
|
3822
|
+
...props
|
|
3823
|
+
});
|
|
3824
|
+
}
|
|
3825
|
+
function TimeDisplay(props) {
|
|
3826
|
+
return jsx(TemporalDisplay, {
|
|
3827
|
+
kind: "time",
|
|
3828
|
+
...props
|
|
3703
3829
|
});
|
|
3704
3830
|
}
|
|
3705
|
-
function
|
|
3831
|
+
function storedText(value) {
|
|
3832
|
+
return value instanceof Date && !Number.isNaN(value.getTime()) ? value.toISOString() : String(value);
|
|
3833
|
+
}
|
|
3834
|
+
function TemporalDisplay({ kind, value, text, field, record }) {
|
|
3706
3835
|
const locale = useOptionalLocale();
|
|
3836
|
+
const zone = useFieldTimeZone(field?.zone, record);
|
|
3837
|
+
const viewer = useTimeZone();
|
|
3707
3838
|
if (value == null || value === "") return jsx("span", {
|
|
3708
3839
|
className: "text-muted-foreground",
|
|
3709
3840
|
children: "—"
|
|
3710
3841
|
});
|
|
3711
|
-
if (
|
|
3712
|
-
|
|
3713
|
-
|
|
3842
|
+
if (zone.status === "pending" || viewer.status === "pending") return jsx(Skeleton, {
|
|
3843
|
+
className: "h-4 w-24",
|
|
3844
|
+
"aria-busy": "true"
|
|
3845
|
+
});
|
|
3846
|
+
const raw = storedText(value);
|
|
3847
|
+
const formatted = formatTimeValue(kind, raw, {
|
|
3848
|
+
zone: zone.zone,
|
|
3849
|
+
viewerZone: viewer.zone,
|
|
3850
|
+
locale: localeTag(locale),
|
|
3851
|
+
params: {
|
|
3852
|
+
...kind === "time" && field?.ui?.seconds === true ? { timeStyle: "medium" } : {},
|
|
3853
|
+
...dateDisplayParams(field?.ui)
|
|
3854
|
+
}
|
|
3855
|
+
});
|
|
3856
|
+
if (text !== void 0) return jsx("span", {
|
|
3857
|
+
title: formatted,
|
|
3858
|
+
children: text
|
|
3859
|
+
});
|
|
3860
|
+
if (formatted === void 0) return jsx("span", { children: raw });
|
|
3714
3861
|
return jsx("span", {
|
|
3715
3862
|
className: "whitespace-nowrap",
|
|
3716
|
-
children:
|
|
3863
|
+
children: formatted
|
|
3717
3864
|
});
|
|
3718
3865
|
}
|
|
3719
3866
|
function toIsoDate(v) {
|
|
3720
3867
|
if (v == null || v === "") return "";
|
|
3721
3868
|
const s = String(v);
|
|
3722
|
-
|
|
3723
|
-
const d = new Date(s);
|
|
3724
|
-
if (Number.isNaN(d.getTime())) return "";
|
|
3725
|
-
return d.toISOString().slice(0, 10);
|
|
3869
|
+
return isCalendarDate(s) ? s : "";
|
|
3726
3870
|
}
|
|
3727
3871
|
function DateInput(props) {
|
|
3728
3872
|
return jsx(TemporalInput, {
|
|
@@ -3733,18 +3877,44 @@ function DateInput(props) {
|
|
|
3733
3877
|
});
|
|
3734
3878
|
}
|
|
3735
3879
|
function DateTimeInput(props) {
|
|
3880
|
+
const locale = useOptionalLocale();
|
|
3881
|
+
const zone = useFieldTimeZone(props.field?.zone, props.values === void 0 ? props.record : {
|
|
3882
|
+
...props.record,
|
|
3883
|
+
...props.values
|
|
3884
|
+
});
|
|
3885
|
+
const viewer = useTimeZone();
|
|
3886
|
+
const pending = zone.status === "pending";
|
|
3887
|
+
const fieldZone = zone.status === "ready" ? zone.zone : void 0;
|
|
3888
|
+
const named = fieldZone !== void 0 && viewer.status === "ready" && fieldZone !== viewer.zone ? zoneShortName(canonicalInstant(String(props.value ?? "")) ?? epochMsToInstant(Date.now()), fieldZone, localeTag(locale)) : void 0;
|
|
3736
3889
|
return jsx(TemporalInput, {
|
|
3737
3890
|
...props,
|
|
3738
3891
|
type: "datetime-local",
|
|
3739
|
-
|
|
3740
|
-
|
|
3892
|
+
disabled: props.disabled || pending,
|
|
3893
|
+
toText: (value) => fieldZone === void 0 ? "" : toLocalDateTimeText(value, fieldZone),
|
|
3894
|
+
fromText: (text) => fieldZone === void 0 ? null : fromLocalDateTimeText(text, fieldZone) ?? null,
|
|
3895
|
+
...named === void 0 ? {} : { zoneName: named }
|
|
3741
3896
|
});
|
|
3742
3897
|
}
|
|
3743
|
-
function
|
|
3744
|
-
|
|
3898
|
+
function TimeInput(props) {
|
|
3899
|
+
const seconds = props.field?.ui?.seconds === true;
|
|
3900
|
+
return jsx(TemporalInput, {
|
|
3901
|
+
...props,
|
|
3902
|
+
type: "time",
|
|
3903
|
+
step: seconds ? 1 : 60,
|
|
3904
|
+
toText: (value) => value == null ? "" : String(value),
|
|
3905
|
+
fromText: (text) => {
|
|
3906
|
+
if (text === "") return null;
|
|
3907
|
+
if (seconds) return text.length === 5 ? `${text}:00` : text;
|
|
3908
|
+
return text.slice(0, 5);
|
|
3909
|
+
}
|
|
3910
|
+
});
|
|
3911
|
+
}
|
|
3912
|
+
function TemporalInput({ type, step, toText, fromText, name, id, value, onChange, testid, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage, zoneName }) {
|
|
3913
|
+
const input = jsx(Input, {
|
|
3745
3914
|
name,
|
|
3746
3915
|
id,
|
|
3747
3916
|
type,
|
|
3917
|
+
...step === void 0 ? {} : { step },
|
|
3748
3918
|
value: toText(value),
|
|
3749
3919
|
onChange: (e) => onChange(fromText(e.target.value)),
|
|
3750
3920
|
"data-testid": testid,
|
|
@@ -3755,6 +3925,15 @@ function TemporalInput({ type, toText, fromText, name, id, value, onChange, test
|
|
|
3755
3925
|
"aria-describedby": ariaDescribedBy,
|
|
3756
3926
|
...ariaErrorMessage ? { "aria-errormessage": ariaErrorMessage } : {}
|
|
3757
3927
|
});
|
|
3928
|
+
if (zoneName === void 0) return input;
|
|
3929
|
+
return jsxs("div", {
|
|
3930
|
+
className: "flex items-center gap-2",
|
|
3931
|
+
children: [input, jsx("span", {
|
|
3932
|
+
className: "whitespace-nowrap text-xs text-muted-foreground",
|
|
3933
|
+
"data-testid": testid === void 0 ? void 0 : `${testid}:zone`,
|
|
3934
|
+
children: zoneName
|
|
3935
|
+
})]
|
|
3936
|
+
});
|
|
3758
3937
|
}
|
|
3759
3938
|
//#endregion
|
|
3760
3939
|
//#region src/fields/enum.tsx
|
|
@@ -3775,13 +3954,30 @@ function EnumDisplay({ value, options, field, resource }) {
|
|
|
3775
3954
|
}) : null, label]
|
|
3776
3955
|
});
|
|
3777
3956
|
}
|
|
3778
|
-
function EnumInput({ name, id, value, onChange, testid, options, field, placeholder, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage, ariaLabelledBy, resource }) {
|
|
3957
|
+
function EnumInput({ name, id, value, onChange, testid, options, field, placeholder, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage, ariaLabelledBy, resource, record, values, metaSources, baseline }) {
|
|
3779
3958
|
const t = useOptionalT();
|
|
3780
3959
|
const caps = useOptionCaps(resource);
|
|
3781
3960
|
const enumDef = useBoundEnum(field);
|
|
3782
3961
|
const ns = enumNamespaceOf(field);
|
|
3783
3962
|
const control = resolveEnumControl(field?.ui?.control, enumDef, `field ${field?.name ?? name}`);
|
|
3784
|
-
const
|
|
3963
|
+
const sources = useFieldMetaSources({
|
|
3964
|
+
record,
|
|
3965
|
+
values,
|
|
3966
|
+
extra: metaSources
|
|
3967
|
+
});
|
|
3968
|
+
const available = useAvailableEnumValues({
|
|
3969
|
+
values: options ?? [],
|
|
3970
|
+
use: {
|
|
3971
|
+
narrow: narrowEntriesOf(field?.meta?.narrow),
|
|
3972
|
+
sources,
|
|
3973
|
+
mode: record === void 0 ? "create" : "edit",
|
|
3974
|
+
baseline: baseline ?? record
|
|
3975
|
+
}
|
|
3976
|
+
});
|
|
3977
|
+
const settling = available.status === "ready" ? void 0 : available.status;
|
|
3978
|
+
const offered = settling === void 0 ? available.values : [];
|
|
3979
|
+
const tid = testid ?? name;
|
|
3980
|
+
const resolved = offered.map((o) => {
|
|
3785
3981
|
const summary = ns === void 0 ? void 0 : resolveDoc(caps, `enum/${ns}/${o.value}`)?.summary;
|
|
3786
3982
|
return {
|
|
3787
3983
|
value: o.value,
|
|
@@ -3790,12 +3986,21 @@ function EnumInput({ name, id, value, onChange, testid, options, field, placehol
|
|
|
3790
3986
|
...summary === void 0 ? {} : { summary }
|
|
3791
3987
|
};
|
|
3792
3988
|
});
|
|
3989
|
+
const raw = value == null || value === "" ? void 0 : String(value);
|
|
3990
|
+
const known = raw === void 0 ? void 0 : options?.find((o) => o.value === raw);
|
|
3991
|
+
const current = raw === void 0 || resolved.some((o) => o.value === raw) ? void 0 : {
|
|
3992
|
+
value: raw,
|
|
3993
|
+
label: resolveOptionLabel(caps, field, raw, known, enumDef),
|
|
3994
|
+
...known?.icon === void 0 ? {} : { icon: known.icon }
|
|
3995
|
+
};
|
|
3793
3996
|
if (control !== "select") return jsx(EnumChoiceGroup, {
|
|
3794
3997
|
control,
|
|
3795
3998
|
options: resolved,
|
|
3999
|
+
...current === void 0 ? {} : { current },
|
|
4000
|
+
...settling === void 0 ? {} : { settling },
|
|
3796
4001
|
value,
|
|
3797
4002
|
onChange,
|
|
3798
|
-
testid:
|
|
4003
|
+
testid: tid,
|
|
3799
4004
|
name,
|
|
3800
4005
|
id,
|
|
3801
4006
|
required,
|
|
@@ -3815,25 +4020,39 @@ function EnumInput({ name, id, value, onChange, testid, options, field, placehol
|
|
|
3815
4020
|
name,
|
|
3816
4021
|
id,
|
|
3817
4022
|
"aria-required": required,
|
|
4023
|
+
"aria-busy": settling === "pending" || void 0,
|
|
3818
4024
|
"aria-invalid": ariaInvalid || void 0,
|
|
3819
4025
|
"aria-describedby": ariaDescribedBy,
|
|
3820
4026
|
...ariaErrorMessage ? { "aria-errormessage": ariaErrorMessage } : {},
|
|
3821
4027
|
children: jsx(SelectValue, { placeholder: placeholder ?? t("field.select", { defaultValue: "Select…" }) })
|
|
3822
|
-
}),
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
"data-
|
|
3827
|
-
|
|
4028
|
+
}), jsxs(SelectContent, { children: [
|
|
4029
|
+
current === void 0 ? null : jsx(SelectItem, {
|
|
4030
|
+
value: current.value,
|
|
4031
|
+
disabled: true,
|
|
4032
|
+
"data-current": "",
|
|
4033
|
+
"data-testid": `${tid}:current`,
|
|
4034
|
+
children: current.label
|
|
3828
4035
|
}),
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
4036
|
+
settling === void 0 ? null : jsx(EnumSettlingRow, {
|
|
4037
|
+
status: settling,
|
|
4038
|
+
testid: tid
|
|
4039
|
+
}),
|
|
4040
|
+
resolved.map((o) => jsx(SelectItem, {
|
|
4041
|
+
value: o.value,
|
|
4042
|
+
"data-testid": testid === void 0 ? void 0 : `${testid}:option:${o.value}`,
|
|
4043
|
+
description: o.summary === void 0 ? void 0 : jsx("span", {
|
|
4044
|
+
"data-testid": testid === void 0 ? void 0 : `${testid}:option:${o.value}:doc`,
|
|
4045
|
+
children: o.summary
|
|
4046
|
+
}),
|
|
4047
|
+
children: jsxs("span", {
|
|
4048
|
+
className: "inline-flex items-center gap-1.5",
|
|
4049
|
+
children: [o.icon ? jsx(Icon, {
|
|
4050
|
+
name: o.icon,
|
|
4051
|
+
className: "size-3.5 shrink-0 text-muted-foreground"
|
|
4052
|
+
}) : null, o.label]
|
|
4053
|
+
})
|
|
4054
|
+
}, o.value))
|
|
4055
|
+
] })]
|
|
3837
4056
|
});
|
|
3838
4057
|
}
|
|
3839
4058
|
//#endregion
|
|
@@ -4254,7 +4473,7 @@ function JsonInput({ name, id, value, onChange, testid, disabled, required, aria
|
|
|
4254
4473
|
}
|
|
4255
4474
|
//#endregion
|
|
4256
4475
|
//#region src/fields/lazy-relation-many.tsx
|
|
4257
|
-
const RelationManyPickerInput = lazy(() => import("./relation-many-picker-
|
|
4476
|
+
const RelationManyPickerInput = lazy(() => import("./relation-many-picker-BlrGRwMV.js").then((module) => ({ default: module.RelationManyPickerInput })));
|
|
4258
4477
|
function LazyRelationManyInput(props) {
|
|
4259
4478
|
return jsx(Suspense, {
|
|
4260
4479
|
fallback: jsx(Skeleton, {
|
|
@@ -4366,6 +4585,144 @@ function NumberInput({ name, id, value, onChange, testid, placeholder, disabled,
|
|
|
4366
4585
|
});
|
|
4367
4586
|
}
|
|
4368
4587
|
//#endregion
|
|
4588
|
+
//#region src/fields/object-group.tsx
|
|
4589
|
+
const GROUP = "rounded-md border border-input p-3";
|
|
4590
|
+
function ObjectGroupInput(props) {
|
|
4591
|
+
const { testIds, accessibility, children } = props;
|
|
4592
|
+
return jsx("div", {
|
|
4593
|
+
role: "group",
|
|
4594
|
+
"data-buro-object-group": "input",
|
|
4595
|
+
className: cn(GROUP, "space-y-3"),
|
|
4596
|
+
"data-testid": testIds.input,
|
|
4597
|
+
id: accessibility.input,
|
|
4598
|
+
"aria-labelledby": accessibility.label,
|
|
4599
|
+
"aria-describedby": accessibility.description,
|
|
4600
|
+
"aria-invalid": props.issues.some((issue) => issue.severity === "error" && issue.path.length === 0) || void 0,
|
|
4601
|
+
"aria-errormessage": accessibility.error,
|
|
4602
|
+
children
|
|
4603
|
+
});
|
|
4604
|
+
}
|
|
4605
|
+
function ObjectGroupDisplay(props) {
|
|
4606
|
+
const { testIds, children } = props;
|
|
4607
|
+
return jsx("div", {
|
|
4608
|
+
role: "group",
|
|
4609
|
+
"data-buro-object-group": "display",
|
|
4610
|
+
className: cn(GROUP, "space-y-2"),
|
|
4611
|
+
"data-testid": testIds.display,
|
|
4612
|
+
children
|
|
4613
|
+
});
|
|
4614
|
+
}
|
|
4615
|
+
//#endregion
|
|
4616
|
+
//#region src/fields/repeater.tsx
|
|
4617
|
+
function useRepeaterTexts() {
|
|
4618
|
+
const t = useChromeT();
|
|
4619
|
+
return {
|
|
4620
|
+
add: t("field.repeater.add", { defaultValue: "Add" }),
|
|
4621
|
+
empty: t("field.repeater.empty", { defaultValue: "No items yet" }),
|
|
4622
|
+
remove: (position) => t("field.repeater.remove", {
|
|
4623
|
+
params: { position },
|
|
4624
|
+
defaultValue: "Remove item {{position}}"
|
|
4625
|
+
}),
|
|
4626
|
+
moveUp: (position) => t("field.repeater.moveUp", {
|
|
4627
|
+
params: { position },
|
|
4628
|
+
defaultValue: "Move item {{position}} up"
|
|
4629
|
+
}),
|
|
4630
|
+
moveDown: (position) => t("field.repeater.moveDown", {
|
|
4631
|
+
params: { position },
|
|
4632
|
+
defaultValue: "Move item {{position}} down"
|
|
4633
|
+
})
|
|
4634
|
+
};
|
|
4635
|
+
}
|
|
4636
|
+
function RepeaterInput(props) {
|
|
4637
|
+
const texts = useRepeaterTexts();
|
|
4638
|
+
const { value, renderElement, elementKeys, onAdd, onRemove, onMove, testIds, accessibility } = props;
|
|
4639
|
+
const root = testIds.input;
|
|
4640
|
+
const at = (suffix) => root === void 0 ? void 0 : `${root}:${suffix}`;
|
|
4641
|
+
const editable = props.disabled !== true && props.readOnly !== true;
|
|
4642
|
+
const canAdd = editable && onAdd !== void 0 && props.canAdd !== false;
|
|
4643
|
+
const canRemove = editable && onRemove !== void 0 && props.canRemove !== false;
|
|
4644
|
+
const last = value.length - 1;
|
|
4645
|
+
return jsxs("div", {
|
|
4646
|
+
role: "group",
|
|
4647
|
+
className: "space-y-2",
|
|
4648
|
+
"data-testid": root,
|
|
4649
|
+
id: accessibility.input,
|
|
4650
|
+
"aria-labelledby": accessibility.label,
|
|
4651
|
+
"aria-describedby": accessibility.description,
|
|
4652
|
+
"aria-errormessage": accessibility.error,
|
|
4653
|
+
children: [value.length === 0 ? jsx("p", {
|
|
4654
|
+
className: "text-sm text-muted-foreground",
|
|
4655
|
+
"data-testid": at("empty"),
|
|
4656
|
+
children: texts.empty
|
|
4657
|
+
}) : jsx("ol", {
|
|
4658
|
+
className: "space-y-2",
|
|
4659
|
+
children: value.map((_, index) => jsxs("li", {
|
|
4660
|
+
className: "flex items-start gap-2 rounded-md border border-input p-3",
|
|
4661
|
+
"data-testid": at(`item:${index}`),
|
|
4662
|
+
children: [jsx("div", {
|
|
4663
|
+
className: "min-w-0 flex-1",
|
|
4664
|
+
children: renderElement?.(index)
|
|
4665
|
+
}), onMove === void 0 && onRemove === void 0 ? null : jsxs("div", {
|
|
4666
|
+
className: "flex shrink-0 gap-1",
|
|
4667
|
+
children: [onMove === void 0 ? null : jsxs(Fragment$1, { children: [jsx(Button, {
|
|
4668
|
+
type: "button",
|
|
4669
|
+
variant: "ghost",
|
|
4670
|
+
size: "icon",
|
|
4671
|
+
"aria-label": texts.moveUp(index + 1),
|
|
4672
|
+
disabled: !editable || index === 0,
|
|
4673
|
+
"data-testid": at(`up:${index}`),
|
|
4674
|
+
onClick: () => onMove(index, index - 1),
|
|
4675
|
+
children: jsx(IconArrowUp, { "aria-hidden": "true" })
|
|
4676
|
+
}), jsx(Button, {
|
|
4677
|
+
type: "button",
|
|
4678
|
+
variant: "ghost",
|
|
4679
|
+
size: "icon",
|
|
4680
|
+
"aria-label": texts.moveDown(index + 1),
|
|
4681
|
+
disabled: !editable || index === last,
|
|
4682
|
+
"data-testid": at(`down:${index}`),
|
|
4683
|
+
onClick: () => onMove(index, index + 1),
|
|
4684
|
+
children: jsx(IconArrowDown, { "aria-hidden": "true" })
|
|
4685
|
+
})] }), onRemove === void 0 ? null : jsx(Button, {
|
|
4686
|
+
type: "button",
|
|
4687
|
+
variant: "ghost",
|
|
4688
|
+
size: "icon",
|
|
4689
|
+
"aria-label": texts.remove(index + 1),
|
|
4690
|
+
disabled: !canRemove,
|
|
4691
|
+
"data-testid": at(`remove:${index}`),
|
|
4692
|
+
onClick: () => onRemove(index),
|
|
4693
|
+
children: jsx(IconTrash, { "aria-hidden": "true" })
|
|
4694
|
+
})]
|
|
4695
|
+
})]
|
|
4696
|
+
}, elementKeys?.[index] ?? index))
|
|
4697
|
+
}), onAdd === void 0 ? null : jsxs(Button, {
|
|
4698
|
+
type: "button",
|
|
4699
|
+
variant: "outline",
|
|
4700
|
+
size: "sm",
|
|
4701
|
+
disabled: !canAdd,
|
|
4702
|
+
"data-testid": at("add"),
|
|
4703
|
+
onClick: onAdd,
|
|
4704
|
+
children: [jsx(IconPlus, { "aria-hidden": "true" }), texts.add]
|
|
4705
|
+
})]
|
|
4706
|
+
});
|
|
4707
|
+
}
|
|
4708
|
+
function RepeaterDisplay(props) {
|
|
4709
|
+
const texts = useRepeaterTexts();
|
|
4710
|
+
const { value, renderElement, testIds } = props;
|
|
4711
|
+
if (value.length === 0) return jsx("span", {
|
|
4712
|
+
className: "text-muted-foreground",
|
|
4713
|
+
"data-testid": testIds.display,
|
|
4714
|
+
children: texts.empty
|
|
4715
|
+
});
|
|
4716
|
+
return jsx("ol", {
|
|
4717
|
+
className: "space-y-2",
|
|
4718
|
+
"data-testid": testIds.display,
|
|
4719
|
+
children: value.map((_, index) => jsx("li", {
|
|
4720
|
+
className: "rounded-md border border-input p-3",
|
|
4721
|
+
children: renderElement?.(index)
|
|
4722
|
+
}, index))
|
|
4723
|
+
});
|
|
4724
|
+
}
|
|
4725
|
+
//#endregion
|
|
4369
4726
|
//#region src/fields/link-keys-display.tsx
|
|
4370
4727
|
const isRecord$1 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4371
4728
|
function qualify(name) {
|
|
@@ -4695,12 +5052,13 @@ function TextareaInput({ name, id, value, onChange, testid, placeholder, disable
|
|
|
4695
5052
|
//#region src/fields/default-renderers.ts
|
|
4696
5053
|
function legacyField(props) {
|
|
4697
5054
|
const name = optionFieldName(props.path);
|
|
4698
|
-
const texts = props.field
|
|
5055
|
+
const { texts, zone } = props.field;
|
|
4699
5056
|
return Object.freeze({
|
|
4700
5057
|
name,
|
|
4701
5058
|
meta: props.meta,
|
|
4702
5059
|
ui: props.ui,
|
|
4703
|
-
...texts === void 0 ? {} : { texts }
|
|
5060
|
+
...texts === void 0 ? {} : { texts },
|
|
5061
|
+
...zone === void 0 ? {} : { zone }
|
|
4704
5062
|
});
|
|
4705
5063
|
}
|
|
4706
5064
|
function legacyOptions(options, field) {
|
|
@@ -4763,9 +5121,12 @@ function input(renderer) {
|
|
|
4763
5121
|
field: legacyField(props),
|
|
4764
5122
|
resource: props.resource.id,
|
|
4765
5123
|
record: props.record,
|
|
5124
|
+
values: props.form,
|
|
4766
5125
|
relationSeeds: props.relationSeeds,
|
|
4767
5126
|
fixedFilters: props.fixedFilters,
|
|
5127
|
+
optionSubtitle: props.optionSubtitle,
|
|
4768
5128
|
metaSources: props.metaSources,
|
|
5129
|
+
...props.baseline === void 0 ? {} : { baseline: props.baseline },
|
|
4769
5130
|
link: props.link
|
|
4770
5131
|
});
|
|
4771
5132
|
};
|
|
@@ -4818,6 +5179,12 @@ function enumName(ui) {
|
|
|
4818
5179
|
}
|
|
4819
5180
|
function RegistryEnumInput(props) {
|
|
4820
5181
|
const app = useOptionalApp();
|
|
5182
|
+
const meta = props.field.meta;
|
|
5183
|
+
const sources = useFieldMetaSources({
|
|
5184
|
+
record: props.record,
|
|
5185
|
+
values: props.form,
|
|
5186
|
+
extra: props.metaSources
|
|
5187
|
+
});
|
|
4821
5188
|
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
5189
|
return createElement(EnumPicker, {
|
|
4823
5190
|
enumName: props.enumName,
|
|
@@ -4833,7 +5200,14 @@ function RegistryEnumInput(props) {
|
|
|
4833
5200
|
ariaInvalid: props.issues.some(isErrorIssue),
|
|
4834
5201
|
ariaDescribedBy: props.accessibility.description,
|
|
4835
5202
|
ariaErrorMessage: props.accessibility.error,
|
|
4836
|
-
ariaLabelledBy: props.accessibility.label
|
|
5203
|
+
ariaLabelledBy: props.accessibility.label,
|
|
5204
|
+
use: {
|
|
5205
|
+
params: enumParamsOf(meta?.enumParams),
|
|
5206
|
+
narrow: narrowEntriesOf(meta?.narrow),
|
|
5207
|
+
sources,
|
|
5208
|
+
mode: props.record === void 0 ? "create" : "edit",
|
|
5209
|
+
baseline: props.baseline ?? props.record
|
|
5210
|
+
}
|
|
4837
5211
|
});
|
|
4838
5212
|
}
|
|
4839
5213
|
function enumAware(renderer, layout) {
|
|
@@ -4885,6 +5259,10 @@ const dateTime = {
|
|
|
4885
5259
|
Display: DateTimeDisplay,
|
|
4886
5260
|
Input: DateTimeInput
|
|
4887
5261
|
};
|
|
5262
|
+
const time = {
|
|
5263
|
+
Display: TimeDisplay,
|
|
5264
|
+
Input: TimeInput
|
|
5265
|
+
};
|
|
4888
5266
|
const en = {
|
|
4889
5267
|
Display: EnumDisplay,
|
|
4890
5268
|
Input: EnumInput
|
|
@@ -4923,6 +5301,8 @@ const shadcnFieldImplementations = Object.freeze({
|
|
|
4923
5301
|
dateTime: scalar(dateTime),
|
|
4924
5302
|
"date-time": scalar(dateTime),
|
|
4925
5303
|
"default:date-time": scalar(dateTime),
|
|
5304
|
+
time: scalar(time),
|
|
5305
|
+
"default:time": scalar(time),
|
|
4926
5306
|
enum: enumAware(en),
|
|
4927
5307
|
json: scalar({
|
|
4928
5308
|
Display: JsonDisplay,
|
|
@@ -4936,7 +5316,17 @@ const shadcnFieldImplementations = Object.freeze({
|
|
|
4936
5316
|
richText: scalar(rich, { size: "full" }),
|
|
4937
5317
|
"rich-text": scalar(rich, { size: "full" }),
|
|
4938
5318
|
"default:rich-text": scalar(rich, { size: "full" }),
|
|
4939
|
-
file: scalarOrCollection(file, { size: "full" })
|
|
5319
|
+
file: scalarOrCollection(file, { size: "full" }),
|
|
5320
|
+
object: Object.freeze({
|
|
5321
|
+
Input: ObjectGroupInput,
|
|
5322
|
+
Display: ObjectGroupDisplay,
|
|
5323
|
+
chrome: true
|
|
5324
|
+
}),
|
|
5325
|
+
array: Object.freeze({
|
|
5326
|
+
CollectionInput: RepeaterInput,
|
|
5327
|
+
CollectionDisplay: RepeaterDisplay,
|
|
5328
|
+
chrome: true
|
|
5329
|
+
})
|
|
4940
5330
|
});
|
|
4941
5331
|
//#endregion
|
|
4942
5332
|
//#region src/forms/declarative-display.tsx
|
|
@@ -5166,7 +5556,8 @@ const OPERATOR_LABELS = {
|
|
|
5166
5556
|
has: "has",
|
|
5167
5557
|
hasAny: "has any of",
|
|
5168
5558
|
hasAll: "has all of",
|
|
5169
|
-
hasNone: "has none of"
|
|
5559
|
+
hasNone: "has none of",
|
|
5560
|
+
some: "has an item where"
|
|
5170
5561
|
};
|
|
5171
5562
|
function formatOperatorLabel(op, chromeT) {
|
|
5172
5563
|
return chromeT ? chromeT(`filters.operators.${op}`, { defaultValue: OPERATOR_LABELS[op] }) : OPERATOR_LABELS[op];
|
|
@@ -5700,6 +6091,7 @@ function PeekRecord({ target, testid, row }) {
|
|
|
5700
6091
|
function DeclaredPeekBody({ target, testid, record, frameRecord, def, capabilityFor, fieldVisible, view: View, builtin, open, openable, t }) {
|
|
5701
6092
|
const host = useContext(PeekHostContext);
|
|
5702
6093
|
const title = recordDisplayName(record, def?.displayField);
|
|
6094
|
+
const subtitle = useRecordSubtitle(target)(record) ?? void 0;
|
|
5703
6095
|
const setLabel = host?.setLabel;
|
|
5704
6096
|
useEffect(() => setLabel?.(title), [setLabel, title]);
|
|
5705
6097
|
const controller = useFormController({
|
|
@@ -5735,6 +6127,7 @@ function DeclaredPeekBody({ target, testid, record, frameRecord, def, capability
|
|
|
5735
6127
|
children: [builtin ? jsx(PeekTitle, {
|
|
5736
6128
|
testid,
|
|
5737
6129
|
title,
|
|
6130
|
+
subtitle,
|
|
5738
6131
|
open: openable ? open : void 0
|
|
5739
6132
|
}) : null, jsx(Suspense, {
|
|
5740
6133
|
fallback: null,
|
|
@@ -5747,11 +6140,26 @@ function DeclaredPeekBody({ target, testid, record, frameRecord, def, capability
|
|
|
5747
6140
|
})]
|
|
5748
6141
|
});
|
|
5749
6142
|
}
|
|
5750
|
-
function PeekTitle({ testid, title, open }) {
|
|
5751
|
-
|
|
6143
|
+
function PeekTitle({ testid, title, subtitle, open }) {
|
|
6144
|
+
const heading = open === void 0 ? jsx("p", {
|
|
5752
6145
|
className: "text-sm font-semibold",
|
|
5753
6146
|
children: title
|
|
6147
|
+
}) : jsx(PeekTitleButton, {
|
|
6148
|
+
testid,
|
|
6149
|
+
title,
|
|
6150
|
+
open
|
|
6151
|
+
});
|
|
6152
|
+
if (subtitle === void 0) return heading;
|
|
6153
|
+
return jsxs("div", {
|
|
6154
|
+
className: "flex flex-col gap-0.5",
|
|
6155
|
+
children: [heading, jsx("p", {
|
|
6156
|
+
"data-testid": `${testid}:subtitle`,
|
|
6157
|
+
className: "text-xs text-muted-foreground",
|
|
6158
|
+
children: subtitle
|
|
6159
|
+
})]
|
|
5754
6160
|
});
|
|
6161
|
+
}
|
|
6162
|
+
function PeekTitleButton({ testid, title, open }) {
|
|
5755
6163
|
return jsx("button", {
|
|
5756
6164
|
type: "button",
|
|
5757
6165
|
"data-testid": `${testid}:title`,
|
|
@@ -5779,6 +6187,8 @@ function DefaultPeekBody({ target, testid, row, open }) {
|
|
|
5779
6187
|
const projected = useProjectedRecord(target, dtoRow);
|
|
5780
6188
|
const record = projected.value ?? {};
|
|
5781
6189
|
const title = recordDisplayName(record, def?.displayField);
|
|
6190
|
+
const subtitleOf = useRecordSubtitle(target);
|
|
6191
|
+
const subtitle = projected.status === "ready" ? subtitleOf(record) ?? void 0 : void 0;
|
|
5782
6192
|
const setLabel = host?.setLabel;
|
|
5783
6193
|
useEffect(() => setLabel?.(title), [setLabel, title]);
|
|
5784
6194
|
const columns = useMemo(() => {
|
|
@@ -5810,6 +6220,7 @@ function DefaultPeekBody({ target, testid, row, open }) {
|
|
|
5810
6220
|
children: [jsx(PeekTitle, {
|
|
5811
6221
|
testid,
|
|
5812
6222
|
title,
|
|
6223
|
+
subtitle,
|
|
5813
6224
|
open
|
|
5814
6225
|
}), columns.length === 0 ? null : jsx("dl", {
|
|
5815
6226
|
className: "grid gap-1.5",
|