@burojs/react 0.4.0 → 0.5.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 +15 -6
- package/dist/flows-runtime.cjs +1162 -0
- package/dist/flows-runtime.cjs.map +1 -0
- package/dist/flows-runtime.d.cts +153 -0
- package/dist/flows-runtime.d.ts +153 -0
- package/dist/flows-runtime.js +1157 -0
- package/dist/flows-runtime.js.map +1 -0
- package/dist/index.cjs +1629 -3862
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2259 -723
- package/dist/index.d.ts +2259 -723
- package/dist/index.js +1412 -3692
- package/dist/index.js.map +1 -1
- package/dist/present-flow-BM8vaiZX.cjs +10152 -0
- package/dist/present-flow-BM8vaiZX.cjs.map +1 -0
- package/dist/present-flow-pFzbn0cZ.js +9015 -0
- package/dist/present-flow-pFzbn0cZ.js.map +1 -0
- package/dist/types-DH3beUOO.d.cts +488 -0
- package/dist/types-DH3beUOO.d.ts +488 -0
- package/package.json +24 -6
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
2
|
+
import { _ as InlineFlowHolder, a as FormSubmitResult, c as FieldBinding, d as ResolvedIssue, f as CheckGateRequest, g as PlacementRuntime, h as useCheckGate, i as FormSteps, l as FormValues, m as UseCheckGateResult, n as FormControllerFailure, o as UseFormControllerFormOptions, p as CheckGateState, r as FormDraftState, s as UseFormControllerRecordOptions, t as FormController, u as RelationFilterOpt, v as InlineLease } from "./types-DH3beUOO.cjs";
|
|
3
|
+
import { ActionDI, ActionDataAccess, ActionFlow, AnyFrameHandle, AppAuditEventInput, AppContext, AppDefinition, AppRuntime, ApplicationSnapshot, Audit, AuthCheckResult, AuthProvider, AuthResult, Availability, BatchedQueryOperation, BlockLookup, BulkTarget, Capability, CapabilityDecision, CheckOutcome, CheckSurface, CompiledFlow, CompiledScreen, CountDescriptor, CountPolicy, CreateOneDescriptor, CustomMutationHandle, CustomQueryHandle, DataError, DataProvider, DataProviderSessionSnapshot, DataQueryKey, DataSessionController, DataSessionController as DataSessionController$1, DataSessionSnapshot, DataSessionState, DataSessionTransitionParticipant, DataSessionTransitionParticipant as DataSessionTransitionParticipant$1, DeleteManyDescriptor, DeleteOneDescriptor, Dispatcher, DispatcherEffects, DocContent, DocsConfig, EntityRef, EnumValue, ErasedMutationDescriptor, ErasedQueryDescriptor, ErasedResourceHandle, ExportFormat, ExportHandle, ExportRequest, Exporter, FieldAccessMap, FieldContextSources, FieldDeclaration, FieldDefBase, FieldOption, FieldReach, FilterExpression, FilterGroup, FilterPredicateOp, FixedFilterInput, FlowControlState, FlowGateAnswer, FlowRef, FlowResult, FlowRun, FlowTarget, FrameHandle, FrameKind, I18nCaps, InferBlockData, InferBlockProps, InferCreateInput, InferCustomInput, InferCustomOutput, InferSchemaOutput, InferUpdateInput, ItemActionPlacement, LayerRuntime, LayerStatus, LayoutSize, ListAccess, ListDescriptor, LivePlan, ManifestResolution, ManyDescriptor, MutationResultFor, NodeState, OneDescriptor, PageRequires, PanelTone, PermissionMap, PlanScreenInput, PortableObject, PortableProjection, PortableSnapshotManifest, PortableValue, QueryContext, QueryResultFor, QuickHost, RecordCodecError, RecordCodecOutcome, RegistryReader, RegistryResource, RelationCandidate, RequestContext, ResolvedDocTopic, ResolvedFixedFilter, ResourceDef, ResourceFieldMap, ResourceHandle, ResourceRecordCodec, ResourceRefInput, RouteDescriptor as RouteDescriptor$1, Row, RuleContext, SavedViewDef, ScreenMode, ScreenPlan, ScreenSources, SearchDecl, SlotMap, SnapshotEntityTargetInput, SortExpression, SourceState, StandardSchemaV1, TaskRunFailure, TaskRunReport, UIActivationContext, UIActivationSurface, UIPresentAnchor, UIPresentHost, UIPresentRequest, UIPresentResult, UIPresentationRuntime, UiSettingCardinality, UiSettingCollection, UiSettingEntryPermissions, UiSettingScope, UiSettingSingleton, UiSettingTypeDefinition, UiSettingsAdapter, UiSettingsIssue, UiSettingsSnapshot, UiSettingsStore, UpdateManyDescriptor, UpdateOneDescriptor, ValidationIssue, ValidationIssues, createDataSession, createResourceRecordCodec, normalizeServerRecordIssues } from "@burojs/core";
|
|
3
4
|
import { Query, QueryClient, UseMutationOptions, UseMutationResult, UseQueryOptions, UseQueryResult } from "@tanstack/react-query";
|
|
4
5
|
import * as React from "react";
|
|
5
|
-
import { ComponentType, ReactElement, ReactNode } from "react";
|
|
6
|
+
import { ComponentType, Context, ReactElement, ReactNode, RefObject } from "react";
|
|
6
7
|
import { Resolver, SliceDefinition } from "@burojs/context";
|
|
7
8
|
import { I18nFacade, ResourceI18n } from "@burojs/i18n-core";
|
|
8
9
|
import { FileRef, FileStorageAdapter, ResolveCtx } from "@burojs/file-storage";
|
|
@@ -72,6 +73,75 @@ interface LiveCoordinator {
|
|
|
72
73
|
dispose(): Promise<void>;
|
|
73
74
|
}
|
|
74
75
|
//#endregion
|
|
76
|
+
//#region src/data/live/query-live-observer.d.ts
|
|
77
|
+
interface QueryLiveObserverState {
|
|
78
|
+
readonly live: LiveState;
|
|
79
|
+
/** Only observer-detected protocol violations synthesize query failure. */
|
|
80
|
+
readonly protocolError?: DataError;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Reduces a descriptor's shared live lease into its canonical TanStack cache
|
|
84
|
+
* entry. It owns no provider resources beyond its lease and becomes inert as
|
|
85
|
+
* soon as that lease is released, which prevents retired session work from
|
|
86
|
+
* writing into a replacement cache partition.
|
|
87
|
+
*/
|
|
88
|
+
declare class QueryLiveObserver<T extends ErasedQueryDescriptor = ErasedQueryDescriptor> {
|
|
89
|
+
#private;
|
|
90
|
+
readonly identity: string;
|
|
91
|
+
constructor(args: {
|
|
92
|
+
readonly descriptor: T;
|
|
93
|
+
readonly runtime: DataRuntimeContextValue;
|
|
94
|
+
readonly queryClient: QueryClient;
|
|
95
|
+
});
|
|
96
|
+
getState: () => QueryLiveObserverState;
|
|
97
|
+
subscribe: (listener: () => void) => (() => void);
|
|
98
|
+
/** Whether a regular query should execute after the selected live plan is ready. */
|
|
99
|
+
get queryEnabled(): boolean;
|
|
100
|
+
execute(signal: AbortSignal): Promise<QueryResultFor<T>>;
|
|
101
|
+
dispose(): void;
|
|
102
|
+
}
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/data/live/live-queries.d.ts
|
|
105
|
+
/** One consumer's hold on the shared observer of a descriptor. */
|
|
106
|
+
interface LiveQueryRetention {
|
|
107
|
+
readonly observer: QueryLiveObserver;
|
|
108
|
+
/** Drops this hold. Idempotent; the last release disposes the observer. */
|
|
109
|
+
release(): void;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The runtime's one `QueryLiveObserver` per descriptor identity and session
|
|
113
|
+
* generation, shared by every mounted consumer of that descriptor and kept
|
|
114
|
+
* alive while any of them retains it. Invariant: `queryFn` resolves the
|
|
115
|
+
* observer when the request runs, never when the options were built, because
|
|
116
|
+
* TanStack runs the `queryFn` of whichever consumer rendered last.
|
|
117
|
+
*/
|
|
118
|
+
interface LiveQueryRegistry {
|
|
119
|
+
/**
|
|
120
|
+
* Retains the shared observer for `descriptor` at the current session
|
|
121
|
+
* generation, creating it (and acquiring its live lease) on the first hold.
|
|
122
|
+
* Call it from a committed effect, and only for an enabled query.
|
|
123
|
+
*/
|
|
124
|
+
retain(descriptor: ErasedQueryDescriptor): LiveQueryRetention;
|
|
125
|
+
/**
|
|
126
|
+
* The TanStack `queryFn` for `descriptor`. It executes through the retained
|
|
127
|
+
* observer of the current generation when a consumer holds one, and falls
|
|
128
|
+
* back to a plain `executeQuery` when none does (a disabled query's manual
|
|
129
|
+
* `refetch()`, for instance).
|
|
130
|
+
*
|
|
131
|
+
* During a session-generation change there is a short window between the
|
|
132
|
+
* old observer retiring and the consumer's effect retaining the new one; a
|
|
133
|
+
* request started there also takes the fallback. That is harmless: the
|
|
134
|
+
* transition's own `cancelQueries()` cancels it, or its `clear()` has
|
|
135
|
+
* already detached the query it would write to, and the re-retained
|
|
136
|
+
* observer runs the next generation's first fetch itself.
|
|
137
|
+
*/
|
|
138
|
+
queryFn(descriptor: ErasedQueryDescriptor): (context: {
|
|
139
|
+
readonly signal: AbortSignal;
|
|
140
|
+
}) => Promise<unknown>;
|
|
141
|
+
/** Number of live entries, for diagnostics and tests. */
|
|
142
|
+
readonly size: number;
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
75
145
|
//#region src/data/provider-registry.d.ts
|
|
76
146
|
interface ProviderServiceRef {
|
|
77
147
|
readonly id: string;
|
|
@@ -96,6 +166,13 @@ interface DataRuntimeContextValue {
|
|
|
96
166
|
readonly providers: DataProviderRegistry;
|
|
97
167
|
readonly batchCoordinator: BatchCoordinator;
|
|
98
168
|
readonly liveCoordinator: LiveCoordinator;
|
|
169
|
+
/**
|
|
170
|
+
* One shared live query observer per descriptor and session generation,
|
|
171
|
+
* retained by the query hooks.
|
|
172
|
+
*
|
|
173
|
+
* @internal
|
|
174
|
+
*/
|
|
175
|
+
readonly liveQueries: LiveQueryRegistry;
|
|
99
176
|
readonly liveSetupTimeoutMs: number;
|
|
100
177
|
/** Present only in React trees configured with a native AuthProvider. */
|
|
101
178
|
readonly authController?: AuthController;
|
|
@@ -215,6 +292,10 @@ declare function useIsAuthenticated(): UseQueryResult<AuthCheckResult, DataError
|
|
|
215
292
|
declare function useLogin(): UseMutationResult<AuthResult, DataError, unknown>;
|
|
216
293
|
declare function useLogout(): UseMutationResult<AuthResult, DataError, unknown>;
|
|
217
294
|
//#endregion
|
|
295
|
+
//#region src/auth/context.d.ts
|
|
296
|
+
/** The auth controller, or `null` when `BuroProvider` has no `authProvider`. Never throws. */
|
|
297
|
+
declare function useOptionalAuthController(): AuthController | null;
|
|
298
|
+
//#endregion
|
|
218
299
|
//#region src/hooks/data/use-query-descriptor.d.ts
|
|
219
300
|
type NativeQueryOptions<TData, TSelected = TData> = Omit<UseQueryOptions<TData, DataError, TSelected, DataQueryKey>, 'queryKey' | 'queryFn' | 'placeholderData' | 'refetchInterval'> & {
|
|
220
301
|
/**
|
|
@@ -259,6 +340,14 @@ type UseOneOptions<R extends AnyResource$6, TSelected = QueryResultFor<OneDescri
|
|
|
259
340
|
declare function useOne<R extends AnyResource$6, TSelected = QueryResultFor<OneDescriptor<R>>>(resource: R, options: UseOneOptions<R, TSelected>): NativeQueryResult<QueryResultFor<OneDescriptor<R>>, TSelected>;
|
|
260
341
|
declare function useOne<TSelected = QueryResultFor<OneDescriptor<ErasedResourceHandle>>>(resource: string, options: UseOneOptions<ErasedResourceHandle, TSelected>): NativeQueryResult<QueryResultFor<OneDescriptor<ErasedResourceHandle>>, TSelected>;
|
|
261
342
|
//#endregion
|
|
343
|
+
//#region src/hooks/data/retry-record-read.d.ts
|
|
344
|
+
/**
|
|
345
|
+
* Record reads retry only what the provider called retryable, at most twice.
|
|
346
|
+
* TanStack's default — three retries, about seven seconds before an error
|
|
347
|
+
* shows — would also retry a `not-found` or a `forbidden` that cannot succeed.
|
|
348
|
+
*/
|
|
349
|
+
declare function retryRecordRead(failureCount: number, error: DataError): boolean;
|
|
350
|
+
//#endregion
|
|
262
351
|
//#region src/hooks/data/use-many.d.ts
|
|
263
352
|
type AnyResource$5 = ResourceHandle<unknown, Record<string, FieldDefBase>, string, string>;
|
|
264
353
|
type UseManyOptions<R extends AnyResource$5, TSelected = QueryResultFor<ManyDescriptor<R>>> = {
|
|
@@ -369,23 +458,12 @@ type UseCreateOneOptions<R extends AnyResource$2> = NativeMutationOptions<Mutati
|
|
|
369
458
|
}> & {
|
|
370
459
|
readonly providerOptionsOverride?: PortableObject;
|
|
371
460
|
};
|
|
372
|
-
type UseCreateManyOptions<R extends AnyResource$2> = NativeMutationOptions<MutationResultFor<CreateManyDescriptor<R>>, {
|
|
373
|
-
readonly values: readonly InferCreateInput<R>[];
|
|
374
|
-
}> & {
|
|
375
|
-
readonly providerOptionsOverride?: PortableObject;
|
|
376
|
-
};
|
|
377
461
|
declare function useCreateOne<R extends AnyResource$2>(resource: R, options?: UseCreateOneOptions<R>): UseMutationResult<MutationResultFor<CreateOneDescriptor<R>>, DataError, {
|
|
378
462
|
readonly values: InferCreateInput<R>;
|
|
379
463
|
}>;
|
|
380
464
|
declare function useCreateOne(resource: string, options?: UseCreateOneOptions<ErasedResourceHandle>): UseMutationResult<MutationResultFor<CreateOneDescriptor<ErasedResourceHandle>>, DataError, {
|
|
381
465
|
readonly values: unknown;
|
|
382
466
|
}>;
|
|
383
|
-
declare function useCreateMany<R extends AnyResource$2>(resource: R, options?: UseCreateManyOptions<R>): UseMutationResult<MutationResultFor<CreateManyDescriptor<R>>, DataError, {
|
|
384
|
-
readonly values: readonly InferCreateInput<R>[];
|
|
385
|
-
}>;
|
|
386
|
-
declare function useCreateMany(resource: string, options?: UseCreateManyOptions<ErasedResourceHandle>): UseMutationResult<MutationResultFor<CreateManyDescriptor<ErasedResourceHandle>>, DataError, {
|
|
387
|
-
readonly values: readonly unknown[];
|
|
388
|
-
}>;
|
|
389
467
|
//#endregion
|
|
390
468
|
//#region src/hooks/data/use-update.d.ts
|
|
391
469
|
type AnyResource$1 = ResourceHandle<any, Record<string, FieldDefBase>, string, string>;
|
|
@@ -434,6 +512,258 @@ type UseCustomMutationOptions<TInput, TOutput> = NativeMutationOptions<TOutput,
|
|
|
434
512
|
/** Resolves a trusted custom mutation and its declaration-owned effects. */
|
|
435
513
|
declare function useCustomMutation<THandle extends CustomMutationHandle<unknown, unknown>>(handle: THandle, options?: UseCustomMutationOptions<InferCustomInput<THandle>, InferCustomOutput<THandle>>): UseMutationResult<InferCustomOutput<THandle>, DataError, InferCustomInput<THandle>>;
|
|
436
514
|
//#endregion
|
|
515
|
+
//#region src/frames/view-props.d.ts
|
|
516
|
+
/** Reads `frames.<id>.<key>` (the block convention, foundation 12). */
|
|
517
|
+
type FrameTranslate = (key: string, options?: {
|
|
518
|
+
readonly params?: Record<string, unknown>;
|
|
519
|
+
readonly count?: number;
|
|
520
|
+
}) => string;
|
|
521
|
+
/**
|
|
522
|
+
* The attributes of the styling contract a node frame spreads on its root: `data-buro-node`,
|
|
523
|
+
* `data-buro-key`, `data-buro-tone`, `data-buro-state` (spec 3.5).
|
|
524
|
+
*/
|
|
525
|
+
type FrameNodeAttributes = Readonly<Record<`data-buro-${string}`, string>>;
|
|
526
|
+
/** The slots a record frame view receives: `body` always rendered, every other slot or `null`. */
|
|
527
|
+
type RecordFrameSlots<S extends SlotMap> = {
|
|
528
|
+
readonly body: ReactElement;
|
|
529
|
+
} & { readonly [K in Exclude<keyof S & string, 'body'>]: ReactElement | null; };
|
|
530
|
+
/** What a record frame's view is rendered with (spec 3.3). */
|
|
531
|
+
interface RecordFrameViewProps<F extends AnyFrameHandle = FrameHandle<'record'>> {
|
|
532
|
+
/**
|
|
533
|
+
* Each slot's planned tree inside its framework wrapper; `null` when the slot is optional and
|
|
534
|
+
* omitted, absent in this mode (create) or planned empty. `body` holds the form in edit and
|
|
535
|
+
* create.
|
|
536
|
+
*/
|
|
537
|
+
readonly slots: RecordFrameSlots<F['slots']>;
|
|
538
|
+
readonly host: 'page' | 'sheet' | 'dialog';
|
|
539
|
+
readonly mode: 'show' | 'edit' | 'create';
|
|
540
|
+
readonly screen: {
|
|
541
|
+
readonly resource: string;
|
|
542
|
+
readonly entry: 'route' | 'quick';
|
|
543
|
+
};
|
|
544
|
+
/** The screen's record as the user may see it; `undefined` before it is read and in create. */
|
|
545
|
+
readonly record: Readonly<Record<string, unknown>> | undefined;
|
|
546
|
+
readonly t: FrameTranslate;
|
|
547
|
+
}
|
|
548
|
+
/** What a peek frame's view is rendered with (spec 3.9). */
|
|
549
|
+
interface PeekFrameViewProps<F extends AnyFrameHandle = FrameHandle<'peek'>> {
|
|
550
|
+
readonly slots: { readonly [K in keyof F['slots'] & string]: ReactElement | null; };
|
|
551
|
+
/** The one row the peek read, filtered as the peek shows it. */
|
|
552
|
+
readonly record: Readonly<Record<string, unknown>>;
|
|
553
|
+
/** Opens the record's `quick.show` through the entry gate (the title click). */
|
|
554
|
+
open(): void;
|
|
555
|
+
readonly t: FrameTranslate;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* What a list frame's view is rendered with (P7-34): the planned trees of its slots (`null` when a
|
|
559
|
+
* slot is omitted or planned empty) and the resource's registry name. The rows are not a prop: a
|
|
560
|
+
* frame arranges the framework's pieces (`<ListControls/>`, `<ListBody/>`, …), which read the list
|
|
561
|
+
* controller the framework owns outside the frame.
|
|
562
|
+
*/
|
|
563
|
+
interface ListFrameViewProps<F extends AnyFrameHandle = FrameHandle<'list'>> {
|
|
564
|
+
readonly slots: { readonly [K in keyof F['slots'] & string]: ReactElement | null; };
|
|
565
|
+
readonly resource: string;
|
|
566
|
+
readonly t: FrameTranslate;
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* What a page frame's view is rendered with (P7 3.14): the page's slots as rendered elements
|
|
570
|
+
* (`body` always), the page label and its parsed `route` params. The framework owns the page's
|
|
571
|
+
* `<h1>`, its access gate and `NavChrome`; the view arranges the slots inside the page body and
|
|
572
|
+
* renders no heading of its own.
|
|
573
|
+
*/
|
|
574
|
+
interface PageFrameViewProps<F extends AnyFrameHandle = FrameHandle<'page'>> {
|
|
575
|
+
readonly slots: { readonly [K in keyof F['slots'] & string]: ReactElement | null; };
|
|
576
|
+
/** The page's label, resolved (the framework draws it as the `<h1>`). */
|
|
577
|
+
readonly label: string;
|
|
578
|
+
/** The page's parsed params: the same values `l.ref('route', …)` reads. */
|
|
579
|
+
readonly params: Readonly<Record<string, unknown>>;
|
|
580
|
+
readonly t: FrameTranslate;
|
|
581
|
+
}
|
|
582
|
+
/** What a panel frame's view is rendered with (spec 3.5). */
|
|
583
|
+
interface PanelFrameViewProps {
|
|
584
|
+
/**
|
|
585
|
+
* The panel's content inside the framework's body element; `null` when closed. While pending,
|
|
586
|
+
* the framework's skeleton.
|
|
587
|
+
*/
|
|
588
|
+
readonly body: ReactElement | null;
|
|
589
|
+
readonly title?: string;
|
|
590
|
+
readonly description?: string;
|
|
591
|
+
readonly tone?: PanelTone;
|
|
592
|
+
readonly icon?: string;
|
|
593
|
+
readonly collapsible: boolean;
|
|
594
|
+
readonly open: boolean;
|
|
595
|
+
/** Opens or closes a collapsible panel; the engine calls the same function to reveal an error. */
|
|
596
|
+
onToggle(next: boolean): void;
|
|
597
|
+
readonly errorCount: number;
|
|
598
|
+
readonly mode: ScreenMode;
|
|
599
|
+
/** The id to put on the title element: the body is labelled by it. */
|
|
600
|
+
readonly titleId: string;
|
|
601
|
+
/** The id of the framework's body element, for the toggle's `aria-controls`. */
|
|
602
|
+
readonly bodyId: string;
|
|
603
|
+
/** The node's «i», or `null`. */
|
|
604
|
+
readonly info: ReactElement | null;
|
|
605
|
+
readonly nodeAttributes: FrameNodeAttributes;
|
|
606
|
+
readonly t: FrameTranslate;
|
|
607
|
+
}
|
|
608
|
+
/** One tab of a tabs frame. */
|
|
609
|
+
interface FrameTab {
|
|
610
|
+
readonly key: string;
|
|
611
|
+
readonly title: string;
|
|
612
|
+
readonly errorCount: number;
|
|
613
|
+
/** Only the active tab's panel is rendered (demand is the planner's). */
|
|
614
|
+
readonly panel: ReactElement | null;
|
|
615
|
+
}
|
|
616
|
+
/** What a tabs frame's view is rendered with (spec 3.5). */
|
|
617
|
+
interface TabsFrameViewProps {
|
|
618
|
+
readonly tabs: readonly FrameTab[];
|
|
619
|
+
readonly active: string;
|
|
620
|
+
onSelect(key: string): void;
|
|
621
|
+
readonly info: ReactElement | null;
|
|
622
|
+
readonly nodeAttributes: FrameNodeAttributes;
|
|
623
|
+
readonly t: FrameTranslate;
|
|
624
|
+
}
|
|
625
|
+
/** One step of a steps frame. */
|
|
626
|
+
interface FrameStep {
|
|
627
|
+
readonly key: string;
|
|
628
|
+
readonly title: string;
|
|
629
|
+
readonly errorCount: number;
|
|
630
|
+
readonly state: 'current' | 'complete' | 'reachable' | 'locked';
|
|
631
|
+
/**
|
|
632
|
+
* Outside a wizard, every step's whole panel; inside, the current step's body only (the frame
|
|
633
|
+
* draws its heading), `null` for the others.
|
|
634
|
+
*/
|
|
635
|
+
readonly panel: ReactElement | null;
|
|
636
|
+
readonly description?: string;
|
|
637
|
+
/** The id to put on the step's heading: the step's body is labelled by it. */
|
|
638
|
+
readonly titleId: string;
|
|
639
|
+
/** The step panel's «i», or `null`. */
|
|
640
|
+
readonly info: ReactElement | null;
|
|
641
|
+
/** The step panel's styling attributes (`data-buro-node="panel"`, its key, tone and state). */
|
|
642
|
+
readonly nodeAttributes: FrameNodeAttributes;
|
|
643
|
+
}
|
|
644
|
+
/** What a steps frame's view is rendered with (spec 3.5). */
|
|
645
|
+
interface StepsFrameViewProps {
|
|
646
|
+
/** A create whose root is this steps node: one step at a time. */
|
|
647
|
+
readonly wizard: boolean;
|
|
648
|
+
readonly steps: readonly FrameStep[];
|
|
649
|
+
readonly current: string;
|
|
650
|
+
goTo(key: string): void;
|
|
651
|
+
back(): void;
|
|
652
|
+
/** Validates the current step, then moves on. */
|
|
653
|
+
next(): void;
|
|
654
|
+
/** Attach to the current step's heading: the framework focuses it when the step changes. */
|
|
655
|
+
readonly headingRef: RefObject<HTMLElement | null>;
|
|
656
|
+
readonly info: ReactElement | null;
|
|
657
|
+
readonly nodeAttributes: FrameNodeAttributes;
|
|
658
|
+
readonly t: FrameTranslate;
|
|
659
|
+
}
|
|
660
|
+
/** The props a frame's view receives, by the frame's kind. */
|
|
661
|
+
type FrameViewProps<F extends AnyFrameHandle = AnyFrameHandle> = F['for'] extends 'record' ? RecordFrameViewProps<F> : F['for'] extends 'peek' ? PeekFrameViewProps<F> : F['for'] extends 'list' ? ListFrameViewProps<F> : F['for'] extends 'page' ? PageFrameViewProps<F> : F['for'] extends 'panel' ? PanelFrameViewProps : F['for'] extends 'tabs' ? TabsFrameViewProps : F['for'] extends 'steps' ? StepsFrameViewProps : never;
|
|
662
|
+
//#endregion
|
|
663
|
+
//#region src/frames/implementation.d.ts
|
|
664
|
+
/**
|
|
665
|
+
* A frame's view, registered in `<BuroProvider frameImplementations>` (spec 3.2). Without a type
|
|
666
|
+
* argument, the view of any frame.
|
|
667
|
+
*/
|
|
668
|
+
interface FrameImplementation<F extends AnyFrameHandle = any> {
|
|
669
|
+
/** `<namespace>:<name>`. */
|
|
670
|
+
readonly id: string;
|
|
671
|
+
readonly frame: EntityRef;
|
|
672
|
+
readonly for: FrameKind;
|
|
673
|
+
/** The frame handle `implementFrame` was given. */
|
|
674
|
+
readonly definition: F;
|
|
675
|
+
readonly component?: ComponentType<FrameViewProps<F>>;
|
|
676
|
+
readonly load?: () => Promise<{
|
|
677
|
+
readonly default: ComponentType<FrameViewProps<F>>;
|
|
678
|
+
}>;
|
|
679
|
+
}
|
|
680
|
+
/** The app's frame views, keyed by frame id. */
|
|
681
|
+
type FrameImplementationCatalog = Readonly<Record<string, FrameImplementation<any>>>;
|
|
682
|
+
/**
|
|
683
|
+
* The view of a frame: `component`, or `load` (a module whose default export is the view,
|
|
684
|
+
* requested when a screen first renders it). Register the result through
|
|
685
|
+
* `composeFrameImplementations` on `<BuroProvider frameImplementations>`.
|
|
686
|
+
*
|
|
687
|
+
* @throws TypeError when `frame` is not a frame handle, or when both or neither of `load` and
|
|
688
|
+
* `component` are given.
|
|
689
|
+
*/
|
|
690
|
+
declare function implementFrame<F extends AnyFrameHandle>(frame: F, impl: {
|
|
691
|
+
readonly component: ComponentType<FrameViewProps<F>>;
|
|
692
|
+
readonly load?: never;
|
|
693
|
+
} | {
|
|
694
|
+
readonly load: NonNullable<FrameImplementation<F>['load']>;
|
|
695
|
+
readonly component?: never;
|
|
696
|
+
}): FrameImplementation<F>;
|
|
697
|
+
/**
|
|
698
|
+
* The app's frame views as one catalogue, keyed by frame id: takes `implementFrame` results.
|
|
699
|
+
* A duplicate id is a development error and the later entry wins; an entry for a built-in
|
|
700
|
+
* (`buro:`) frame is a development error and is dropped — the app's default frame is chosen in
|
|
701
|
+
* `defineAppDefinition({ frames })`, never by replacing a built-in view (P6-9).
|
|
702
|
+
*
|
|
703
|
+
* @throws TypeError for an argument that is not an `implementFrame` result.
|
|
704
|
+
*/
|
|
705
|
+
declare function composeFrameImplementations(...entries: readonly FrameImplementation<any>[]): FrameImplementationCatalog;
|
|
706
|
+
//#endregion
|
|
707
|
+
//#region src/blocks/implementation.d.ts
|
|
708
|
+
/** Whether a prop of `B` is a `block()` prop, by its schema's output. */
|
|
709
|
+
type IsBlockProp<O> = O extends {
|
|
710
|
+
readonly block: EntityRef;
|
|
711
|
+
} ? true : false;
|
|
712
|
+
/**
|
|
713
|
+
* The props a block view receives: each prop's schema output, a `block()` prop as the rendered
|
|
714
|
+
* nested placement (`ReactElement`, `ReactElement[]` for a list).
|
|
715
|
+
*/
|
|
716
|
+
type BlockViewPropValues<B> = { [K in keyof InferBlockProps<B>]: InferBlockProps<B>[K] extends readonly (infer E)[] ? IsBlockProp<E> extends true ? readonly ReactElement[] : InferBlockProps<B>[K] : IsBlockProp<InferBlockProps<B>[K]> extends true ? ReactElement : InferBlockProps<B>[K]; };
|
|
717
|
+
/** The names of a block's `data` entries. */
|
|
718
|
+
type BlockDataEntryName<B> = keyof InferBlockData<B> & string;
|
|
719
|
+
/** What a block view is rendered with (spec 8.2). */
|
|
720
|
+
interface BlockViewProps<B> {
|
|
721
|
+
/** Each prop's schema output; a `block()` prop is the nested placement, rendered. */
|
|
722
|
+
readonly props: BlockViewPropValues<B>;
|
|
723
|
+
/** Ready values only: the framework chrome draws pending, failed and absent. */
|
|
724
|
+
readonly data: Readonly<Record<BlockDataEntryName<B>, unknown>>;
|
|
725
|
+
/** Reads `blocks.<id>.<key>`. */
|
|
726
|
+
readonly t: (key: string, options?: {
|
|
727
|
+
readonly params?: Record<string, unknown>;
|
|
728
|
+
readonly count?: number;
|
|
729
|
+
}) => string;
|
|
730
|
+
}
|
|
731
|
+
/** A block's view, registered in `<BuroProvider blockImplementations>` (spec 8.2). */
|
|
732
|
+
interface BlockImplementation<B = unknown> {
|
|
733
|
+
/** `<namespace>:<name>`. */
|
|
734
|
+
readonly id: string;
|
|
735
|
+
readonly block: EntityRef;
|
|
736
|
+
/** The block handle `implementBlock` was given (`renderBlock` validates props through it). */
|
|
737
|
+
readonly definition: B;
|
|
738
|
+
readonly load?: () => Promise<{
|
|
739
|
+
readonly default: ComponentType<BlockViewProps<B>>;
|
|
740
|
+
}>;
|
|
741
|
+
readonly component?: ComponentType<BlockViewProps<B>>;
|
|
742
|
+
}
|
|
743
|
+
type BlockImplementationCatalog = Readonly<Record<string, BlockImplementation<any>>>;
|
|
744
|
+
/**
|
|
745
|
+
* The view of a block: `load` (a module whose default export is the view, requested only when a
|
|
746
|
+
* placement mounts) or `component`. Register the result through `composeBlockImplementations`
|
|
747
|
+
* on `<BuroProvider blockImplementations>`.
|
|
748
|
+
*
|
|
749
|
+
* @throws TypeError when `block` is not a block handle, or when both or neither of `load` and
|
|
750
|
+
* `component` are given.
|
|
751
|
+
*/
|
|
752
|
+
declare function implementBlock<B>(block: B, impl: {
|
|
753
|
+
readonly load: NonNullable<BlockImplementation<B>['load']>;
|
|
754
|
+
readonly component?: never;
|
|
755
|
+
} | {
|
|
756
|
+
readonly component: ComponentType<BlockViewProps<B>>;
|
|
757
|
+
readonly load?: never;
|
|
758
|
+
}): BlockImplementation<B>;
|
|
759
|
+
/**
|
|
760
|
+
* The app's block views as one catalogue, keyed by block id: takes `implementBlock` results (not
|
|
761
|
+
* records). A duplicate id is a development error and the later entry wins.
|
|
762
|
+
*
|
|
763
|
+
* @throws TypeError for an argument that is not an `implementBlock` result.
|
|
764
|
+
*/
|
|
765
|
+
declare function composeBlockImplementations(...entries: readonly BlockImplementation<any>[]): BlockImplementationCatalog;
|
|
766
|
+
//#endregion
|
|
437
767
|
//#region src/fields/types.d.ts
|
|
438
768
|
/** The render surface requested by a field consumer. */
|
|
439
769
|
type FieldRenderSurface = 'input' | 'display';
|
|
@@ -475,7 +805,8 @@ interface FieldTestIds {
|
|
|
475
805
|
* domain format.
|
|
476
806
|
*/
|
|
477
807
|
interface FieldImplementationLayout {
|
|
478
|
-
|
|
808
|
+
/** The default width of a field this implementation renders (`ui.size` wins). */
|
|
809
|
+
readonly size?: LayoutSize;
|
|
479
810
|
}
|
|
480
811
|
/** Locale-aware, renderer-safe access to the active application content model. */
|
|
481
812
|
interface FieldI18n extends I18nCaps {
|
|
@@ -498,7 +829,12 @@ interface FieldRenderContext<TMeta extends Readonly<Record<string, unknown>> = R
|
|
|
498
829
|
readonly ui: FieldUiHints;
|
|
499
830
|
readonly options: readonly FieldOption[];
|
|
500
831
|
readonly i18n: FieldI18n;
|
|
501
|
-
|
|
832
|
+
/**
|
|
833
|
+
* What a portable condition reads against: the record, the values and the
|
|
834
|
+
* app scope. On an input surface `values` are the live form values; on a
|
|
835
|
+
* display surface there is no form, so `values` is the record itself.
|
|
836
|
+
*/
|
|
837
|
+
readonly sources: FieldContextSources;
|
|
502
838
|
readonly pending: boolean;
|
|
503
839
|
readonly touched: boolean;
|
|
504
840
|
readonly issues: ValidationIssues;
|
|
@@ -536,6 +872,13 @@ interface FieldImplementation<T, TMeta extends Readonly<Record<string, unknown>>
|
|
|
536
872
|
readonly CollectionInput?: ComponentType<CollectionInputProps<T, TMeta>>;
|
|
537
873
|
readonly CollectionDisplay?: ComponentType<CollectionDisplayProps<T, TMeta>>;
|
|
538
874
|
readonly layout?: FieldImplementationLayout;
|
|
875
|
+
/**
|
|
876
|
+
* The schema of the `meta` this implementation reads (P7 3.3): applied to the resolved `meta`
|
|
877
|
+
* (refs read) at render, so `props.meta` is the schema's output. A refusal renders the field
|
|
878
|
+
* misconfigured and blocks submit; `checkApp({ fieldImplementations })` checks literal metas
|
|
879
|
+
* ahead of time. Without one, the implementation receives the resolved record untyped.
|
|
880
|
+
*/
|
|
881
|
+
readonly meta?: StandardSchemaV1<unknown, TMeta>;
|
|
539
882
|
}
|
|
540
883
|
type FieldImplementationComponent = ComponentType<ScalarInputProps<unknown>> | ComponentType<ScalarDisplayProps<unknown>> | ComponentType<CollectionInputProps<unknown>> | ComponentType<CollectionDisplayProps<unknown>>;
|
|
541
884
|
type FieldImplementationSource = 'explicit' | 'format' | 'collection-format' | 'array-shell' | 'base' | 'fallback';
|
|
@@ -560,6 +903,8 @@ interface FieldImplementationDiagnostic {
|
|
|
560
903
|
}
|
|
561
904
|
interface ResolvedFieldImplementation {
|
|
562
905
|
readonly Component?: FieldImplementationComponent;
|
|
906
|
+
/** The catalogue entry the field resolved to (its `meta` schema, P7 3.3); absent on a fallback. */
|
|
907
|
+
readonly implementation?: FieldImplementation<any, any>;
|
|
563
908
|
readonly multiple: boolean;
|
|
564
909
|
readonly source: FieldImplementationSource;
|
|
565
910
|
readonly layout: FieldImplementationLayout;
|
|
@@ -693,30 +1038,57 @@ declare function UIInstanceProvider({ instance, presentation, children }: {
|
|
|
693
1038
|
readonly children: ReactNode;
|
|
694
1039
|
}): import("react/jsx-runtime").JSX.Element;
|
|
695
1040
|
//#endregion
|
|
696
|
-
//#region src/
|
|
697
|
-
/**
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
/**
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
*
|
|
718
|
-
|
|
719
|
-
|
|
1041
|
+
//#region src/quick/quick-stack.d.ts
|
|
1042
|
+
/** One entry of a quick overlay: a record's quick screen in a mode. */
|
|
1043
|
+
interface QuickEntry {
|
|
1044
|
+
readonly resource: string;
|
|
1045
|
+
readonly mode: 'show' | 'edit' | 'create';
|
|
1046
|
+
/** The record of `show` and `edit`; absent on `create`. */
|
|
1047
|
+
readonly recordId?: string;
|
|
1048
|
+
/** `create`'s trusted defaults (the caller's tier, P1b+P1c decision 7). */
|
|
1049
|
+
readonly defaults?: Readonly<Record<string, unknown>>;
|
|
1050
|
+
/**
|
|
1051
|
+
* `create`'s user input (a search text typed into a relation select): form values the user can
|
|
1052
|
+
* see and change, applied once to the fields the plan holds `active`, never a trusted default
|
|
1053
|
+
* (P6 plan ruling 7).
|
|
1054
|
+
*/
|
|
1055
|
+
readonly input?: Readonly<Record<string, unknown>>;
|
|
1056
|
+
/** The entry's record title once its screen has read it: what "Back to …" names. */
|
|
1057
|
+
readonly title?: string;
|
|
1058
|
+
}
|
|
1059
|
+
/** A created row, or `null`: what `useQuick().create` resolves with. */
|
|
1060
|
+
type QuickSettledRow = Readonly<Record<string, unknown>> | null;
|
|
1061
|
+
/**
|
|
1062
|
+
* The history of one quick overlay (spec 4.9): a stack of entries of which only the top is
|
|
1063
|
+
* mounted. A relation inside a sheet pushes; Back pops; Edit in `quick.show` replaces the top.
|
|
1064
|
+
* The history is never in the URL. An external store: `subscribe` / `getSnapshot` for
|
|
1065
|
+
* `useSyncExternalStore`, and `getSnapshot()` changes identity on every change.
|
|
1066
|
+
*
|
|
1067
|
+
* `settled` resolves once, with the row a `quick.create` saved or `null` when the overlay closed
|
|
1068
|
+
* without one.
|
|
1069
|
+
*/
|
|
1070
|
+
declare class QuickStack {
|
|
1071
|
+
private stack;
|
|
1072
|
+
private readonly listeners;
|
|
1073
|
+
private resolveSettled;
|
|
1074
|
+
private isSettled;
|
|
1075
|
+
readonly settled: Promise<QuickSettledRow>;
|
|
1076
|
+
constructor(first: QuickEntry);
|
|
1077
|
+
get entries(): readonly QuickEntry[];
|
|
1078
|
+
get top(): QuickEntry;
|
|
1079
|
+
push(entry: QuickEntry): void;
|
|
1080
|
+
/** Back: drops the top entry. A stack of one is never emptied (closing is the overlay's). */
|
|
1081
|
+
pop(): void;
|
|
1082
|
+
/** Switches the top entry in place (Edit ↔ show), keeping the depth. */
|
|
1083
|
+
replaceTop(entry: QuickEntry): void;
|
|
1084
|
+
/** Records the top entry's title once its record is read. */
|
|
1085
|
+
nameTop(title: string): void;
|
|
1086
|
+
/** Resolve `settled`, once: later calls change nothing. */
|
|
1087
|
+
settle(row: QuickSettledRow): void;
|
|
1088
|
+
subscribe: (listener: () => void) => (() => void);
|
|
1089
|
+
getSnapshot: () => readonly QuickEntry[];
|
|
1090
|
+
private publish;
|
|
1091
|
+
}
|
|
720
1092
|
//#endregion
|
|
721
1093
|
//#region src/ui/ui-presentations.d.ts
|
|
722
1094
|
/**
|
|
@@ -731,6 +1103,93 @@ interface UIPresentationHostProps {
|
|
|
731
1103
|
readonly component: ComponentType<Record<string, unknown>>;
|
|
732
1104
|
readonly props: Readonly<Record<string, unknown>>;
|
|
733
1105
|
readonly options: Readonly<Record<string, unknown>>;
|
|
1106
|
+
/** A popover's anchor, passed through by reference (`host: 'popover'` only). */
|
|
1107
|
+
readonly anchor?: UIPresentAnchor;
|
|
1108
|
+
}
|
|
1109
|
+
/** The reserved component key of a quick entry: resolved from `presentationHosts.screens.quick`. */
|
|
1110
|
+
declare const QUICK_COMPONENT = "buro:quick";
|
|
1111
|
+
/** The reserved component key of a peek: resolved from `presentationHosts.screens.peek`. */
|
|
1112
|
+
declare const PEEK_COMPONENT = "buro:peek";
|
|
1113
|
+
/** The reserved component key of a flow's host: resolved from `presentationHosts.screens.flow`. */
|
|
1114
|
+
declare const FLOW_COMPONENT = "buro:flow";
|
|
1115
|
+
/** The reserved component key of a modal action's block: resolved from `presentationHosts.screens.block`. */
|
|
1116
|
+
declare const BLOCK_COMPONENT = "buro:block";
|
|
1117
|
+
/**
|
|
1118
|
+
* What the block screen receives (P7 3.16): the block a modal action presents and its portable
|
|
1119
|
+
* props. For an item action the clicked row and its resource ride along: the screen reads the row
|
|
1120
|
+
* projected by field view, binds `ref('record', …)` from it, and draws nothing until that is decided.
|
|
1121
|
+
*/
|
|
1122
|
+
interface BlockScreenProps {
|
|
1123
|
+
readonly block: {
|
|
1124
|
+
readonly namespace: string;
|
|
1125
|
+
readonly id: string;
|
|
1126
|
+
};
|
|
1127
|
+
readonly props: Readonly<Record<string, unknown>>;
|
|
1128
|
+
readonly resource?: string;
|
|
1129
|
+
readonly record?: Row;
|
|
1130
|
+
readonly label?: string;
|
|
1131
|
+
}
|
|
1132
|
+
/** What the quick screen receives: the overlay's history, whose top entry it renders. */
|
|
1133
|
+
interface QuickScreenProps {
|
|
1134
|
+
readonly stack: QuickStack;
|
|
1135
|
+
}
|
|
1136
|
+
/** What the peek screen receives: the target and the key it previews. */
|
|
1137
|
+
interface PeekScreenProps {
|
|
1138
|
+
readonly target: string;
|
|
1139
|
+
readonly id?: string;
|
|
1140
|
+
readonly by?: {
|
|
1141
|
+
readonly field: string;
|
|
1142
|
+
readonly key: string;
|
|
1143
|
+
};
|
|
1144
|
+
}
|
|
1145
|
+
/** A flow the host starts itself (P4-C review I1): what to run, on what. */
|
|
1146
|
+
interface FlowStart {
|
|
1147
|
+
readonly target: FlowRef | FlowTarget;
|
|
1148
|
+
readonly record?: Row;
|
|
1149
|
+
readonly args?: Row;
|
|
1150
|
+
readonly selection?: {
|
|
1151
|
+
readonly ids: readonly string[];
|
|
1152
|
+
readonly count: number;
|
|
1153
|
+
};
|
|
1154
|
+
}
|
|
1155
|
+
/**
|
|
1156
|
+
* What a flow's host screen receives (P4 spec 4.15). Either a run its opener holds (`run` and
|
|
1157
|
+
* `compiled`: a `{ label, submit }` flow's outcome, drawn in a dialog), or a flow to start
|
|
1158
|
+
* (`start`): the host then owns the run, so the host outlives its opener — a row that left the
|
|
1159
|
+
* page, a menu item that closed — and its form, its draft and a pending write with it. `then`
|
|
1160
|
+
* runs through the opener's dispatcher scope (`effects`) after the host closed; `onSettle`
|
|
1161
|
+
* reports each outcome to the opener.
|
|
1162
|
+
*/
|
|
1163
|
+
interface FlowScreenProps {
|
|
1164
|
+
readonly run?: FlowRun;
|
|
1165
|
+
readonly start?: FlowStart;
|
|
1166
|
+
/** `'page'` and `'inline'` are the screen drawn in a route or a show tree (P6), not presented. */
|
|
1167
|
+
readonly host: 'dialog' | 'sheet' | 'page' | 'inline';
|
|
1168
|
+
readonly label: string;
|
|
1169
|
+
readonly title?: string;
|
|
1170
|
+
readonly compiled?: CompiledFlow;
|
|
1171
|
+
readonly record?: Row;
|
|
1172
|
+
readonly args?: Row;
|
|
1173
|
+
readonly selection?: {
|
|
1174
|
+
readonly ids: readonly string[];
|
|
1175
|
+
readonly count: number;
|
|
1176
|
+
};
|
|
1177
|
+
/** The effects of the dispatcher scope the flow was started in (4.13, I12). */
|
|
1178
|
+
readonly effects?: () => DispatcherEffects;
|
|
1179
|
+
readonly onSettle?: (result: FlowResult) => void;
|
|
1180
|
+
}
|
|
1181
|
+
/**
|
|
1182
|
+
* The UI kit's overlay screens (P3-6): the framework presents them under the reserved keys
|
|
1183
|
+
* `buro:quick`, `buro:peek` and `buro:flow` and resolves those keys from here only, never from
|
|
1184
|
+
* the app's `components`.
|
|
1185
|
+
*/
|
|
1186
|
+
interface UIPresentationScreens {
|
|
1187
|
+
readonly quick?: ComponentType<QuickScreenProps>;
|
|
1188
|
+
readonly peek?: ComponentType<PeekScreenProps>;
|
|
1189
|
+
/** A flow's host screen (P4 spec 4.15), in a dialog or a sheet. */
|
|
1190
|
+
readonly flow?: ComponentType<FlowScreenProps>;
|
|
1191
|
+
/** A modal action's block (P7 3.16), in a dialog or a sheet. */
|
|
1192
|
+
readonly block?: ComponentType<BlockScreenProps>;
|
|
734
1193
|
}
|
|
735
1194
|
/**
|
|
736
1195
|
* What a host declares it understands about its `options` record: a flat
|
|
@@ -763,7 +1222,10 @@ type UIPresentationHost = ComponentType<UIPresentationHostProps> & {
|
|
|
763
1222
|
* simply renders nothing (no crash, no console noise): that is the expected
|
|
764
1223
|
* shape for an app that has not wired concrete hosts (yet).
|
|
765
1224
|
*/
|
|
766
|
-
type UIPresentationHosts = Readonly<Partial<Record<
|
|
1225
|
+
type UIPresentationHosts = Readonly<Partial<Record<UIPresentHost, UIPresentationHost>>> & {
|
|
1226
|
+
/** The UI kit's overlay screens (`shadcnPresentationHosts.screens`). */
|
|
1227
|
+
readonly screens?: UIPresentationScreens;
|
|
1228
|
+
};
|
|
767
1229
|
interface UIPresentationsProps {
|
|
768
1230
|
readonly hosts: UIPresentationHosts;
|
|
769
1231
|
}
|
|
@@ -783,6 +1245,31 @@ interface UIPresentationsProps {
|
|
|
783
1245
|
*/
|
|
784
1246
|
declare function UIPresentations({ hosts }: UIPresentationsProps): ReactElement;
|
|
785
1247
|
//#endregion
|
|
1248
|
+
//#region src/ui/use-ui-present.d.ts
|
|
1249
|
+
/**
|
|
1250
|
+
* Reads the current activation: the surface from the nearest
|
|
1251
|
+
* `UIActivationSurfaceProvider` (defaulting to `{ type: 'global' }` when
|
|
1252
|
+
* there isn't one) plus a live snapshot of the app's resolver slices, if a
|
|
1253
|
+
* `BuroProvider` is mounted above. Outside one, `slices` is `{}` — this
|
|
1254
|
+
* hook (and `useUIPresent`, which is built on it) works standalone, e.g. in
|
|
1255
|
+
* a unit test that only wires up `UIPresentationRuntimeProvider`.
|
|
1256
|
+
*/
|
|
1257
|
+
declare function useCurrentUIActivation(): UIActivationContext;
|
|
1258
|
+
/** An imperative present request; `activation` is captured automatically and need not (usually) be supplied. */
|
|
1259
|
+
type UIPresentInput = Omit<UIPresentRequest, 'activation'> & {
|
|
1260
|
+
readonly activation?: Partial<UIActivationContext>;
|
|
1261
|
+
};
|
|
1262
|
+
type UIPresent = (request: UIPresentInput) => UIPresentResult;
|
|
1263
|
+
/**
|
|
1264
|
+
* Returns a `present` function that captures the current activation
|
|
1265
|
+
* (surface + resolver slices) at call time and forwards the request to the
|
|
1266
|
+
* `UIPresentationRuntime` supplied by the nearest `UIPresentationRuntimeProvider`.
|
|
1267
|
+
* A caller may override `surface` and/or `slices` explicitly via the
|
|
1268
|
+
* `activation` field of the request; anything left unset falls back to the
|
|
1269
|
+
* captured activation.
|
|
1270
|
+
*/
|
|
1271
|
+
declare function useUIPresent(): UIPresent;
|
|
1272
|
+
//#endregion
|
|
786
1273
|
//#region src/ui/mount.d.ts
|
|
787
1274
|
/**
|
|
788
1275
|
* Who renders the presentation stack.
|
|
@@ -790,8 +1277,10 @@ declare function UIPresentations({ hosts }: UIPresentationsProps): ReactElement;
|
|
|
790
1277
|
* `'framework'` (default) — `BuroProvider` mounts it beside `{children}`,
|
|
791
1278
|
* inside every framework provider. Presented components reach field
|
|
792
1279
|
* implementations, i18n, UI settings and the doc panel, but NOT providers the
|
|
793
|
-
* app mounts inside `{children}` (
|
|
794
|
-
*
|
|
1280
|
+
* app mounts inside `{children}` (the link component): those render strictly
|
|
1281
|
+
* below the framework's own mount. The dispatcher, the navigation guard and the
|
|
1282
|
+
* relation aggregator are mounted by `BuroProvider` around both, so they are
|
|
1283
|
+
* reachable in either mode.
|
|
795
1284
|
*
|
|
796
1285
|
* `'app'` — the app renders `<BuroPresentationOutlet/>` itself, typically as
|
|
797
1286
|
* the last child of its own provider stack. Presented components then render
|
|
@@ -847,12 +1336,30 @@ interface BuroProviderProps<TSlices extends Record<string, SliceDefinition> = Re
|
|
|
847
1336
|
*/
|
|
848
1337
|
resolver: Resolver<TSlices>;
|
|
849
1338
|
i18n: I18nFacade;
|
|
1339
|
+
/**
|
|
1340
|
+
* The `localStorage` key a language control (`useLanguageSwitch`,
|
|
1341
|
+
* `<LanguageSwitch>`) saves the chosen locale under. Read it back at boot the
|
|
1342
|
+
* same way (`loadLocale(key)`) so the choice survives a reload. Default
|
|
1343
|
+
* `'buro:language'`.
|
|
1344
|
+
*/
|
|
1345
|
+
languageStorageKey?: string;
|
|
850
1346
|
components: Record<string, unknown>;
|
|
851
1347
|
/**
|
|
852
1348
|
* Immutable, host-provided React field implementations. They are scoped to
|
|
853
1349
|
* this provider tree and are intentionally outside AppRuntime/manifests.
|
|
854
1350
|
*/
|
|
855
1351
|
fieldImplementations?: FieldImplementationCatalog;
|
|
1352
|
+
/**
|
|
1353
|
+
* The app's block views (`composeBlockImplementations(...)`), keyed by block id. The renderer
|
|
1354
|
+
* composes its built-in views first and these over them: an app entry with a built-in id
|
|
1355
|
+
* replaces that view (with a development notice).
|
|
1356
|
+
*/
|
|
1357
|
+
blockImplementations?: BlockImplementationCatalog;
|
|
1358
|
+
/**
|
|
1359
|
+
* The app's frame views (`composeFrameImplementations(...)`), keyed by frame id. The kit draws
|
|
1360
|
+
* the built-in (`buro:`) frames itself; an app entry for one is ignored (P6-9).
|
|
1361
|
+
*/
|
|
1362
|
+
frameImplementations?: FrameImplementationCatalog;
|
|
856
1363
|
/**
|
|
857
1364
|
* Article bodies for the documentation panel — the map of lazy loaders plus
|
|
858
1365
|
* an optional fallback locale.
|
|
@@ -885,8 +1392,10 @@ interface BuroProviderProps<TSlices extends Record<string, SliceDefinition> = Re
|
|
|
885
1392
|
* behavior: `BuroProvider` mounts `<UIPresentations/>` beside `{children}`.
|
|
886
1393
|
* `'app'` hands the mount to the app, which must render
|
|
887
1394
|
* `<BuroPresentationOutlet/>` inside its own provider stack — the only way a
|
|
888
|
-
* presented component can reach app-level providers (
|
|
889
|
-
*
|
|
1395
|
+
* presented component can reach app-level providers (the link component) as
|
|
1396
|
+
* the SAME instances the app tree uses. The dispatcher, the navigation guard
|
|
1397
|
+
* and the relation aggregator are the framework's own and reach presented
|
|
1398
|
+
* components in both modes.
|
|
890
1399
|
*/
|
|
891
1400
|
presentations?: PresentationsMode;
|
|
892
1401
|
/**
|
|
@@ -900,90 +1409,66 @@ interface BuroProviderProps<TSlices extends Record<string, SliceDefinition> = Re
|
|
|
900
1409
|
* Omitted → no events are emitted and no emission site does any work.
|
|
901
1410
|
*/
|
|
902
1411
|
audit?: Audit;
|
|
1412
|
+
/**
|
|
1413
|
+
* Overrides for the dispatcher's effects, merged per key over the defaults
|
|
1414
|
+
* `BuroProvider` supplies: `refetch` invalidates the `buro-data` queries,
|
|
1415
|
+
* `notify` reaches the notification sink a UI kit's toaster registers (a
|
|
1416
|
+
* no-op without one), `redirect` navigates through the `RouterAdapter` and is
|
|
1417
|
+
* skipped when it resolves to the current pathname with no query of its own
|
|
1418
|
+
* (the built-in delete fired from a filtered list), `setClipboard` and
|
|
1419
|
+
* `download` use the browser, `modal` presents through the presentation
|
|
1420
|
+
* runtime. `clearSelection` has no default — the caller owns the selection.
|
|
1421
|
+
* Read through a ref, so an inline object neither rebuilds the dispatcher nor
|
|
1422
|
+
* goes stale.
|
|
1423
|
+
*/
|
|
1424
|
+
effects?: Partial<DispatcherEffects>;
|
|
1425
|
+
/**
|
|
1426
|
+
* The relation aggregator `<BuroProvider>` mounts around the app and its overlays (when a
|
|
1427
|
+
* `dataRuntime` is given). `maxPage` is the largest page the application's provider serves:
|
|
1428
|
+
* an id batch is read in chunks of this many ids, and a `by` read asks for at most this many
|
|
1429
|
+
* rows. Default 100.
|
|
1430
|
+
*/
|
|
1431
|
+
relationBatch?: {
|
|
1432
|
+
readonly maxPage?: number;
|
|
1433
|
+
};
|
|
903
1434
|
children: ReactNode;
|
|
904
1435
|
}
|
|
905
|
-
declare function BuroProvider<TSlices extends Record<string, SliceDefinition>>({ app, dataRuntime, authProvider, uiSettings, resolver, i18n, components, fieldImplementations, docs, initialManifest, manifestHydrationScope, presentationHosts, presentations, audit, children }: BuroProviderProps<TSlices>): ReactElement;
|
|
1436
|
+
declare function BuroProvider<TSlices extends Record<string, SliceDefinition>>({ app, dataRuntime, authProvider, uiSettings, resolver, i18n, languageStorageKey, components, fieldImplementations, blockImplementations, frameImplementations, docs, initialManifest, manifestHydrationScope, presentationHosts, presentations, audit, effects, relationBatch, children }: BuroProviderProps<TSlices>): ReactElement;
|
|
906
1437
|
//#endregion
|
|
907
1438
|
//#region src/audit/context.d.ts
|
|
1439
|
+
/** What an application emits through: its own `app.*` events, and the correlation it shares. */
|
|
1440
|
+
interface AppAudit {
|
|
1441
|
+
/**
|
|
1442
|
+
* Emits an application event. Its `type` must start with `app.`: a framework type
|
|
1443
|
+
* (`form.submit`, `flow.submit`, `nav.enter`) is dropped — the framework emits those itself —
|
|
1444
|
+
* with a development `console.error` naming it.
|
|
1445
|
+
*/
|
|
1446
|
+
emit(input: AppAuditEventInput, options?: {
|
|
1447
|
+
readonly initiates?: boolean;
|
|
1448
|
+
}): void;
|
|
1449
|
+
/** The id shared by everything the current user action caused. */
|
|
1450
|
+
currentCorrelationId(): string;
|
|
1451
|
+
readonly sessionId: string;
|
|
1452
|
+
}
|
|
908
1453
|
/**
|
|
909
1454
|
* The application's audit emitter, or `null` when `<BuroProvider>` got no
|
|
910
1455
|
* `audit` prop.
|
|
911
1456
|
*
|
|
912
1457
|
* Call sites guard with `audit?.emit(...)`, and that guard is deliberate: it is
|
|
913
1458
|
* what makes an app without auditing pay nothing, because the work of building
|
|
914
|
-
* an event (a
|
|
1459
|
+
* an event (a list snapshot) never starts.
|
|
915
1460
|
*
|
|
916
1461
|
* Applications use it to write their own events into the same stream — custom
|
|
917
1462
|
* pages and hand-written components are otherwise blind spots by construction:
|
|
918
1463
|
*
|
|
919
1464
|
* const audit = useAudit();
|
|
920
1465
|
* audit?.emit({ type: 'app.export.started', payload: { format: 'xlsx' } });
|
|
921
|
-
*/
|
|
922
|
-
declare function useAudit(): Audit | null;
|
|
923
|
-
//#endregion
|
|
924
|
-
//#region src/audit/form-diff.d.ts
|
|
925
|
-
interface BuildFormDiffArgs {
|
|
926
|
-
/** Values as they were when the form opened (its baseline). */
|
|
927
|
-
readonly before: Readonly<Record<string, unknown>>;
|
|
928
|
-
/** Values at submit time. */
|
|
929
|
-
readonly after: Readonly<Record<string, unknown>>;
|
|
930
|
-
/** The form's field definitions, keyed by field name — the source of `sensitive`. */
|
|
931
|
-
readonly fields: Readonly<Record<string, unknown>>;
|
|
932
|
-
}
|
|
933
|
-
/**
|
|
934
|
-
* Build the `diff` of a `form.submit` audit event.
|
|
935
|
-
*
|
|
936
|
-
* Shared by both form hosts (`useDeclarativeForm` and `<ResourceForm>`) on
|
|
937
|
-
* purpose: two copies of the redaction branch is how a sensitive field ends up
|
|
938
|
-
* redacted on one path and not the other.
|
|
939
|
-
*
|
|
940
|
-
* A field the caller did not declare is redacted rather than emitted — an
|
|
941
|
-
* unknown field cannot be proven non-sensitive, and a create form can carry
|
|
942
|
-
* values for fields seeded from outside the declaration. `fields` is caller
|
|
943
|
-
* data too (its keys can be attacker-influenced the same way `before`/
|
|
944
|
-
* `after` can), so the lookup uses `Object.hasOwn` rather than an
|
|
945
|
-
* `=== undefined` check: a key like `toString` or `constructor` is NOT
|
|
946
|
-
* "undefined" on a plain object — it resolves through the prototype chain to
|
|
947
|
-
* a built-in function — and treating that as "known" would emit whatever
|
|
948
|
-
* value rode in under that name raw.
|
|
949
|
-
*/
|
|
950
|
-
declare function buildFormDiff(args: BuildFormDiffArgs): Record<string, AuditFieldDiff>;
|
|
951
|
-
//#endregion
|
|
952
|
-
//#region src/audit/use-form-submit-audit.d.ts
|
|
953
|
-
interface FormSubmitAuditArgs {
|
|
954
|
-
/** Values as the form opened — captured BEFORE the write, since a host may re-baseline after it. */
|
|
955
|
-
readonly before: Readonly<Record<string, unknown>>;
|
|
956
|
-
readonly after: Readonly<Record<string, unknown>>;
|
|
957
|
-
readonly fields: Readonly<Record<string, unknown>>;
|
|
958
|
-
readonly outcome: 'success' | 'error' | 'invalid';
|
|
959
|
-
readonly resource?: string;
|
|
960
|
-
readonly recordId?: string;
|
|
961
|
-
readonly view?: 'create' | 'edit';
|
|
962
|
-
/**
|
|
963
|
-
* A backend-reported error code (e.g. `'backend-500'`, design doc §4.1) —
|
|
964
|
-
* plumbing for a host to report WHY an `'error'` outcome happened, distinct
|
|
965
|
-
* from `audit-diff-build-failed` below (which means the audit machinery
|
|
966
|
-
* itself, not the submit, failed). Ignored on any other outcome.
|
|
967
|
-
*/
|
|
968
|
-
readonly errorCode?: string;
|
|
969
|
-
}
|
|
970
|
-
interface FormSubmitAudit {
|
|
971
|
-
/**
|
|
972
|
-
* False when the app configured no sink. Hosts check it before copying their
|
|
973
|
-
* values — that check is what makes an unaudited app pay nothing.
|
|
974
|
-
*/
|
|
975
|
-
readonly enabled: boolean;
|
|
976
|
-
readonly emit: (args: FormSubmitAuditArgs) => void;
|
|
977
|
-
}
|
|
978
|
-
/**
|
|
979
|
-
* The single place a `form.submit` event is constructed.
|
|
980
1466
|
*
|
|
981
|
-
*
|
|
982
|
-
*
|
|
983
|
-
*
|
|
984
|
-
* third host does not become a third copy.
|
|
1467
|
+
* Only `app.*` events pass (REF-29): the framework's own events go through an internal emitter,
|
|
1468
|
+
* so an application can never forge a `form.submit` or a `flow.submit`. The `Audit` object
|
|
1469
|
+
* `createAudit` returns is unchanged for the application's own transport code.
|
|
985
1470
|
*/
|
|
986
|
-
declare function
|
|
1471
|
+
declare function useAudit(): AppAudit | null;
|
|
987
1472
|
//#endregion
|
|
988
1473
|
//#region src/ui-settings/provider.d.ts
|
|
989
1474
|
interface UiSettingsProviderProps {
|
|
@@ -1102,6 +1587,13 @@ declare function useLayerRuntime(): LayerRuntime;
|
|
|
1102
1587
|
declare function useApplicationSnapshot(): ApplicationSnapshot;
|
|
1103
1588
|
declare function useProjection(target: SnapshotEntityTargetInput): PortableProjection | undefined;
|
|
1104
1589
|
declare function useLayerStatus(id: string): LayerStatus;
|
|
1590
|
+
/**
|
|
1591
|
+
* @internal The app's trusted block catalogue over the committed snapshot (P4-D): the built-in
|
|
1592
|
+
* blocks and every registered one. A flow's form and review tree compile against it, so
|
|
1593
|
+
* `l.place(appBlock)` resolves (spec 3.6). One lookup per snapshot, so a compile memoised by the
|
|
1594
|
+
* lookup hits across renders.
|
|
1595
|
+
*/
|
|
1596
|
+
declare function useFlowFormCatalog(): BlockLookup;
|
|
1105
1597
|
//#endregion
|
|
1106
1598
|
//#region src/context.d.ts
|
|
1107
1599
|
declare const I18nContext: import("react").Context<I18nFacade | null>;
|
|
@@ -1116,6 +1608,8 @@ interface ResourceContextValue {
|
|
|
1116
1608
|
resource?: string;
|
|
1117
1609
|
}
|
|
1118
1610
|
declare const ResourceContext: import("react").Context<ResourceContextValue>;
|
|
1611
|
+
/** Where the chosen locale is persisted unless `<BuroProvider languageStorageKey>` says otherwise. */
|
|
1612
|
+
declare const DEFAULT_LANGUAGE_STORAGE_KEY = "buro:language";
|
|
1119
1613
|
//#endregion
|
|
1120
1614
|
//#region src/data/action-data-access.d.ts
|
|
1121
1615
|
/** Runtime-owned action DI. Descriptor identity always comes from the current lease. */
|
|
@@ -1127,6 +1621,101 @@ declare function useApp(): AppRuntime;
|
|
|
1127
1621
|
//#region src/hooks/use-resource.d.ts
|
|
1128
1622
|
declare function useResource(ref: ResourceRefInput): RegistryResource | undefined;
|
|
1129
1623
|
//#endregion
|
|
1624
|
+
//#region src/frames/context.d.ts
|
|
1625
|
+
/** The app's frame catalogue; `{}` outside a provider. @internal */
|
|
1626
|
+
declare function useFrameImplementations(): FrameImplementationCatalog;
|
|
1627
|
+
//#endregion
|
|
1628
|
+
//#region src/frames/check-context.d.ts
|
|
1629
|
+
/** The kit's frame pieces a frame view places. */
|
|
1630
|
+
type FramePiece = 'RecordTitle' | 'RecordActions' | 'CopyId' | 'FormActions' | 'ListControls' | 'ListFilters' | 'ListFlows' | 'ListLive' | 'ListSavedViews' | 'ListColumns' | 'ListExport' | 'ListCreate' | 'ListBody' | 'ListBulkBar';
|
|
1631
|
+
/**
|
|
1632
|
+
* What a frame's pieces report to (`@internal`): the record frame host counts their mounts to
|
|
1633
|
+
* check a custom frame's obligations at runtime (P6-15), and `checkFrame` renders a view
|
|
1634
|
+
* alone with `stub` set, so each piece draws a marker instead of reading the record chrome.
|
|
1635
|
+
*/
|
|
1636
|
+
interface FrameCheckValue {
|
|
1637
|
+
/** Draw `<span data-check-piece>` instead of the piece (`checkFrame`). */
|
|
1638
|
+
readonly stub: boolean;
|
|
1639
|
+
/** Records a mount; the returned function records the unmount. */
|
|
1640
|
+
mount(piece: FramePiece): () => void;
|
|
1641
|
+
}
|
|
1642
|
+
/** @internal */
|
|
1643
|
+
declare const FrameCheckContext: import("react").Context<FrameCheckValue | null>;
|
|
1644
|
+
/** @internal Records the calling piece's mount while it is mounted; returns the context. */
|
|
1645
|
+
declare function useFramePiece(piece: FramePiece): FrameCheckValue | null;
|
|
1646
|
+
//#endregion
|
|
1647
|
+
//#region src/frames/use-frame-t.d.ts
|
|
1648
|
+
/** A frame view's `t`: reads `frames.<id>.<key>` (the block convention, foundation 12). @internal */
|
|
1649
|
+
declare function useFrameT(id: string): FrameTranslate;
|
|
1650
|
+
//#endregion
|
|
1651
|
+
//#region src/blocks/use-placement.d.ts
|
|
1652
|
+
/** A placement as its host draws it (spec 8.1, 8.2). */
|
|
1653
|
+
interface PlacementView {
|
|
1654
|
+
readonly state: 'absent' | 'pending' | 'ready' | 'failed';
|
|
1655
|
+
/**
|
|
1656
|
+
* Refetches what failed. Absent for a refused prop and for a block without a view: Retry
|
|
1657
|
+
* cannot help them.
|
|
1658
|
+
*/
|
|
1659
|
+
readonly retry?: () => void;
|
|
1660
|
+
readonly error?: unknown;
|
|
1661
|
+
readonly block: EntityRef;
|
|
1662
|
+
/** The app's view of the block (`<BuroProvider blockImplementations>`), if it has one. */
|
|
1663
|
+
readonly appImplementation?: BlockImplementation<any>;
|
|
1664
|
+
/** What the view is rendered with, once the placement is ready. */
|
|
1665
|
+
readonly viewProps?: BlockViewProps<unknown>;
|
|
1666
|
+
}
|
|
1667
|
+
/**
|
|
1668
|
+
* A placement of the screen being rendered, by its key (a nested placement by its derived key,
|
|
1669
|
+
* `<host>.<prop>`): its state over the plan (access, `when`, its sources) and its own mount (props
|
|
1670
|
+
* validated, `data` entries), the app's view of its block and the props the view receives.
|
|
1671
|
+
* `controller` defaults to the record frame's, else to the custom page's body around it.
|
|
1672
|
+
*/
|
|
1673
|
+
declare function usePlacement(key: string, controller?: Pick<FormController, 'plan' | 'placement' | 'retry'>): PlacementView;
|
|
1674
|
+
//#endregion
|
|
1675
|
+
//#region src/forms/controller/use-page-screen.d.ts
|
|
1676
|
+
interface PageScreen {
|
|
1677
|
+
/** The page's one plan; empty for a failure marker. */
|
|
1678
|
+
readonly plan: ScreenPlan;
|
|
1679
|
+
/** Refetches only the failed requests under these source names (`block:<key>` for a placement). */
|
|
1680
|
+
retry(sources: readonly string[]): void;
|
|
1681
|
+
/** A placement's runtime at mount, by key. */
|
|
1682
|
+
placement(key: string): PlacementRuntime | undefined;
|
|
1683
|
+
/** Provides the page to `usePlacement(key)` below it, as a record frame does on a record. */
|
|
1684
|
+
readonly PlacementScope: (props: {
|
|
1685
|
+
readonly children: ReactNode;
|
|
1686
|
+
}) => ReactElement;
|
|
1687
|
+
}
|
|
1688
|
+
/**
|
|
1689
|
+
* @internal The resolver and planner half of a custom page's body (P1b+P1c decision 52), for the
|
|
1690
|
+
* page host: the screen's sources resolved with no record and no form values, the access of the
|
|
1691
|
+
* signed-in user (no resource rules: a page has none), and the page's one `planScreen` call, with
|
|
1692
|
+
* what is open from the surrounding `ScreenStateProvider` and the placements' block data. As on a
|
|
1693
|
+
* record, the plan's `blockDemand` is fed back to the resolver, so a placement under a panel whose
|
|
1694
|
+
* access is pending or denied never has its `data` requested. A `null` screen (a failure marker)
|
|
1695
|
+
* resolves and plans nothing.
|
|
1696
|
+
*/
|
|
1697
|
+
declare function usePageScreen(compiled: CompiledScreen | null): PageScreen;
|
|
1698
|
+
//#endregion
|
|
1699
|
+
//#region src/forms/controller/route-source.d.ts
|
|
1700
|
+
/**
|
|
1701
|
+
* The `route` source of the screen below (spec 4.5): `{ id }` from the record route on show and
|
|
1702
|
+
* edit, `{}` on its create, a page's declared params from the page host. Only those routes
|
|
1703
|
+
* provide it; any other mount — a `<RecordScreen>` outside the record route, a nested screen —
|
|
1704
|
+
* reads `{}`. Values are what the route parsed (a page param's schema may coerce); `''` reads
|
|
1705
|
+
* `null` (the resolver normalises it).
|
|
1706
|
+
*
|
|
1707
|
+
* @internal Provided by `@burojs/ui-shadcn`'s record route and page host.
|
|
1708
|
+
*/
|
|
1709
|
+
declare const RouteSourceContext: import("react").Context<Readonly<Record<string, unknown>> | null>;
|
|
1710
|
+
//#endregion
|
|
1711
|
+
//#region src/blocks/use-route-list-implementation.d.ts
|
|
1712
|
+
/**
|
|
1713
|
+
* The app's view of the built-in `buro:related-list` block (`<BuroProvider blockImplementations>`),
|
|
1714
|
+
* or `undefined`: an app entry replaces the list view everywhere, the route list included, so
|
|
1715
|
+
* `ResourceListPage` renders it instead of the built-in view.
|
|
1716
|
+
*/
|
|
1717
|
+
declare function useRouteListImplementation(): BlockImplementation<any> | undefined;
|
|
1718
|
+
//#endregion
|
|
1130
1719
|
//#region src/fields/provider.d.ts
|
|
1131
1720
|
interface FieldImplementationProviderProps {
|
|
1132
1721
|
readonly fieldImplementations?: FieldImplementationCatalog;
|
|
@@ -1145,6 +1734,29 @@ declare function useFieldImplementationCatalog(): FieldImplementationCatalog;
|
|
|
1145
1734
|
declare function resolveFieldImplementation(catalog: FieldImplementationCatalog, input: UseFieldImplementationArgs): ResolvedFieldImplementation;
|
|
1146
1735
|
declare function useFieldImplementation(input: UseFieldImplementationArgs): ResolvedFieldImplementation;
|
|
1147
1736
|
//#endregion
|
|
1737
|
+
//#region src/fields/field-implementation.d.ts
|
|
1738
|
+
type MetaOf<S extends StandardSchemaV1> = InferSchemaOutput<S> extends Readonly<Record<string, unknown>> ? InferSchemaOutput<S> : never;
|
|
1739
|
+
/**
|
|
1740
|
+
* A field implementation whose `meta` is typed by a schema (P7 3.3): the schema's output is the
|
|
1741
|
+
* type of `props.meta` in every surface, and the framework applies the schema to the resolved
|
|
1742
|
+
* `meta` at render — a refusal renders the field misconfigured, never the implementation.
|
|
1743
|
+
*
|
|
1744
|
+
* ```tsx
|
|
1745
|
+
* const hsCode = fieldImplementation({
|
|
1746
|
+
* meta: z.object({ origin: z.string().nullable() }),
|
|
1747
|
+
* Input: ({ meta: { origin } }) => <CodePicker origin={origin} />,
|
|
1748
|
+
* });
|
|
1749
|
+
* ```
|
|
1750
|
+
*/
|
|
1751
|
+
declare function fieldImplementation<const S extends StandardSchemaV1, T = unknown>(implementation: {
|
|
1752
|
+
readonly meta: S;
|
|
1753
|
+
readonly Input?: ComponentType<ScalarInputProps<T, MetaOf<S>>>;
|
|
1754
|
+
readonly Display?: ComponentType<ScalarDisplayProps<T, MetaOf<S>>>;
|
|
1755
|
+
readonly CollectionInput?: ComponentType<CollectionInputProps<T, MetaOf<S>>>;
|
|
1756
|
+
readonly CollectionDisplay?: ComponentType<CollectionDisplayProps<T, MetaOf<S>>>;
|
|
1757
|
+
readonly layout?: FieldImplementationLayout;
|
|
1758
|
+
}): FieldImplementation<T, MetaOf<S>>;
|
|
1759
|
+
//#endregion
|
|
1148
1760
|
//#region src/fields/define-field-with-implementation.d.ts
|
|
1149
1761
|
type FieldDeclarationOverrides<TMeta extends Readonly<Record<string, unknown>>> = Omit<FieldDeclaration, 'type' | 'format' | 'meta'> & {
|
|
1150
1762
|
readonly meta?: TMeta;
|
|
@@ -1163,6 +1775,69 @@ interface DefinedField<TMeta extends Readonly<Record<string, unknown>> = Readonl
|
|
|
1163
1775
|
*/
|
|
1164
1776
|
declare function defineFieldWithImplementation<TMeta extends Readonly<Record<string, unknown>> = Readonly<Record<string, unknown>>>(declaration: FieldDeclaration, implementation: FieldImplementation<any, TMeta>): DefinedField<TMeta>;
|
|
1165
1777
|
//#endregion
|
|
1778
|
+
//#region src/fields/use-field-meta.d.ts
|
|
1779
|
+
/**
|
|
1780
|
+
* What a field's input receives as `meta` (P7 3.2, 3.3): its refs read from the owner's sources,
|
|
1781
|
+
* then the implementation's schema over the result. `pending` while a source or an asynchronous
|
|
1782
|
+
* schema is; `failed` once a source failed or the schema refused it, with the reason a
|
|
1783
|
+
* development message names.
|
|
1784
|
+
*/
|
|
1785
|
+
type FieldMetaState = {
|
|
1786
|
+
readonly status: 'ready';
|
|
1787
|
+
readonly meta: Readonly<Record<string, unknown>>;
|
|
1788
|
+
} | {
|
|
1789
|
+
readonly status: 'pending';
|
|
1790
|
+
} | {
|
|
1791
|
+
readonly status: 'failed';
|
|
1792
|
+
readonly reason: string;
|
|
1793
|
+
};
|
|
1794
|
+
/**
|
|
1795
|
+
* The sources a field's `meta` reads when its owner supplies none of its own: `record` (the
|
|
1796
|
+
* record the field renders from, `null` in create), `values` (the live form values), `scope` and
|
|
1797
|
+
* `user`. An owner's own states (`extra`: a form controller's projected `record` and `values`, a
|
|
1798
|
+
* flow's `with` and `args`) replace these by name, so a field decided pending by P5 stays pending.
|
|
1799
|
+
*
|
|
1800
|
+
* @internal
|
|
1801
|
+
*/
|
|
1802
|
+
declare function useFieldMetaSources(input: {
|
|
1803
|
+
readonly record: Readonly<Record<string, unknown>> | undefined;
|
|
1804
|
+
readonly values: Readonly<Record<string, unknown>> | undefined;
|
|
1805
|
+
readonly extra?: ScreenSources | undefined;
|
|
1806
|
+
}): ScreenSources;
|
|
1807
|
+
/**
|
|
1808
|
+
* A field's `meta` as its implementation receives it (P7 3.2, 3.3). `implementation` is the
|
|
1809
|
+
* catalogue entry the field resolved to: its `meta` schema, when it declares one, is applied to
|
|
1810
|
+
* the resolved meta, and an asynchronous schema keeps the state `pending` until it settles.
|
|
1811
|
+
* The same state object is returned while the values the refs read are the same.
|
|
1812
|
+
*
|
|
1813
|
+
* @internal
|
|
1814
|
+
*/
|
|
1815
|
+
declare function useFieldMeta(field: Pick<FieldDeclaration, 'meta'>, implementation: FieldImplementation<unknown> | undefined, sources: ScreenSources): FieldMetaState;
|
|
1816
|
+
//#endregion
|
|
1817
|
+
//#region src/fields/use-candidates-access.d.ts
|
|
1818
|
+
/**
|
|
1819
|
+
* Whether a relation's select may read its target under its candidates (P7 3.4): every field a
|
|
1820
|
+
* candidate names must be one its user may view in the target. A predicate on a hidden field is
|
|
1821
|
+
* never sent — it would filter on data the user cannot see, and the rows offered would tell.
|
|
1822
|
+
*/
|
|
1823
|
+
type CandidatesAccess = {
|
|
1824
|
+
readonly status: 'pending';
|
|
1825
|
+
} | {
|
|
1826
|
+
readonly status: 'allowed';
|
|
1827
|
+
} | {
|
|
1828
|
+
readonly status: 'forbidden';
|
|
1829
|
+
readonly field: string;
|
|
1830
|
+
};
|
|
1831
|
+
/**
|
|
1832
|
+
* `pending` while the permission map loads and a field decision depends on it; `forbidden`, with
|
|
1833
|
+
* the first such field, when a candidate names a field the user may not view; else `allowed`.
|
|
1834
|
+
* No candidates is `allowed` whatever the map says. A target the application lacks is closed
|
|
1835
|
+
* (every field hidden), so a candidate on it is `forbidden`.
|
|
1836
|
+
*
|
|
1837
|
+
* @internal
|
|
1838
|
+
*/
|
|
1839
|
+
declare function useCandidatesAccess(target: string, candidates: readonly RelationCandidate[] | undefined): CandidatesAccess;
|
|
1840
|
+
//#endregion
|
|
1166
1841
|
//#region src/hooks/use-doc.d.ts
|
|
1167
1842
|
/**
|
|
1168
1843
|
* Contextual documentation for one address, resolved at render time.
|
|
@@ -1370,12 +2045,11 @@ declare function useVisibilityCtx(): AppContext;
|
|
|
1370
2045
|
* standalone" precedent: a headless hook meant to be instantiable via a bare
|
|
1371
2046
|
* `renderHook(() => useX(...))`, with no wrapper, needs graceful
|
|
1372
2047
|
* degradation rather than `useCtx`'s hard `must be used within a
|
|
1373
|
-
* BuroProvider` throw. `
|
|
1374
|
-
*
|
|
1375
|
-
*
|
|
1376
|
-
*
|
|
1377
|
-
*
|
|
1378
|
-
* passing once the controller starts reading a visibility ctx.
|
|
2048
|
+
* BuroProvider` throw. The form controller (`useFormController`) is the
|
|
2049
|
+
* consumer: a form with no predicate `required`/`disabled` fields must not
|
|
2050
|
+
* need a full app `BuroProvider` tree just to mount and be unit-tested —
|
|
2051
|
+
* `renderHook(() => useFormController(...))` tests (no wrapper) keep passing
|
|
2052
|
+
* while the controller reads a visibility ctx.
|
|
1379
2053
|
*
|
|
1380
2054
|
* Inside a real `BuroProvider`, this reads the same live resolver snapshot
|
|
1381
2055
|
* `useVisibilityCtx` does (including reactivity to slice updates), just
|
|
@@ -1386,29 +2060,6 @@ declare function useVisibilityCtx(): AppContext;
|
|
|
1386
2060
|
*/
|
|
1387
2061
|
declare function useOptionalVisibilityCtx(): AppContext;
|
|
1388
2062
|
//#endregion
|
|
1389
|
-
//#region src/hooks/use-visible-templates.d.ts
|
|
1390
|
-
/**
|
|
1391
|
-
* The document types a user may be offered for `resource` right now.
|
|
1392
|
-
*
|
|
1393
|
-
* `templates.items` filtered by each entry's `visible` predicate against the
|
|
1394
|
-
* live app context (`{ permissions, scope, user }`) — the seam that makes a
|
|
1395
|
-
* type set follow scope. The hook re-runs when the context slices move, so a
|
|
1396
|
-
* picker built on it narrows the moment the user switches market, tenant or
|
|
1397
|
-
* role, with no code in the picker that knows about any of them.
|
|
1398
|
-
*
|
|
1399
|
-
* Returns `[]` for an unknown resource and for a resource that declares no
|
|
1400
|
-
* `templates` — "no types on offer", which is the honest answer for a resource
|
|
1401
|
-
* that has none, and lets a caller render its picker unconditionally.
|
|
1402
|
-
*
|
|
1403
|
-
* ⚠️ **This is the OFFER, not an authorization boundary.** A type hidden here
|
|
1404
|
-
* is still renderable by a record that already carries it (a row that exists
|
|
1405
|
-
* has to stay readable) and still reachable by a hand-typed create URL — the
|
|
1406
|
-
* page-level guard remains the host's, exactly as `ResourceConfig.visible`
|
|
1407
|
-
* gates navigation rather than routes. Use a capability rule where the
|
|
1408
|
-
* boundary has to hold.
|
|
1409
|
-
*/
|
|
1410
|
-
declare function useVisibleTemplates(resource: string): DocumentTemplate[];
|
|
1411
|
-
//#endregion
|
|
1412
2063
|
//#region src/hooks/use-capability.d.ts
|
|
1413
2064
|
interface UseCapabilityArgs {
|
|
1414
2065
|
/** Resource whose rules apply. */
|
|
@@ -1460,6 +2111,131 @@ declare function useCapabilityResolver(resource: string, record?: unknown, mode?
|
|
|
1460
2111
|
*/
|
|
1461
2112
|
declare function useCapability(capability: Capability, args: UseCapabilityArgs): CapabilityDecision;
|
|
1462
2113
|
//#endregion
|
|
2114
|
+
//#region src/hooks/url-state/codec.d.ts
|
|
2115
|
+
type ResourceFilter = FilterExpression<ErasedResourceHandle>;
|
|
2116
|
+
type ResourceSort = SortExpression<ErasedResourceHandle>;
|
|
2117
|
+
/**
|
|
2118
|
+
* Deliberate bounds for untrusted URL AST payloads. The values are large
|
|
2119
|
+
* enough for an interactive list, while preventing a pasted URL from making
|
|
2120
|
+
* server rendering or the first client render do unbounded recursive work.
|
|
2121
|
+
*/
|
|
2122
|
+
declare const RESOURCE_URL_STATE_LIMITS: {
|
|
2123
|
+
readonly maxEncodedBytes: 16384;
|
|
2124
|
+
readonly maxFilters: 50;
|
|
2125
|
+
readonly maxFilterDepth: 16;
|
|
2126
|
+
readonly maxFilterNodes: 200;
|
|
2127
|
+
readonly maxSortEntries: 20;
|
|
2128
|
+
};
|
|
2129
|
+
/** Typed, router-independent state for an interactive resource list. */
|
|
2130
|
+
/**
|
|
2131
|
+
* Suffixes of a list namespace that are not list state (P3-26): `?<namespace>.open=<id>`, a
|
|
2132
|
+
* placement's deep link, is page state. A list write keeps them; the codec ignores them.
|
|
2133
|
+
*/
|
|
2134
|
+
declare const RESERVED_LIST_SUFFIXES: readonly ["open"];
|
|
2135
|
+
interface ResourceUrlState {
|
|
2136
|
+
filters: readonly ResourceFilter[];
|
|
2137
|
+
/** The builder group. `filters` above is the PINNED slot — always ANDed. */
|
|
2138
|
+
filterGroup: FilterGroup;
|
|
2139
|
+
sort: ResourceSort;
|
|
2140
|
+
page: number;
|
|
2141
|
+
pageSize: number;
|
|
2142
|
+
search: string;
|
|
2143
|
+
visibleColumns: string[] | null;
|
|
2144
|
+
}
|
|
2145
|
+
/**
|
|
2146
|
+
* Kept temporarily as a source-level migration seam for the list controller.
|
|
2147
|
+
* URL AST values preserve their JSON primitive type and no longer use this
|
|
2148
|
+
* hint for serialization or decoding.
|
|
2149
|
+
*/
|
|
2150
|
+
type FieldType = 'string' | 'number' | 'boolean' | 'enum' | 'relation' | 'date';
|
|
2151
|
+
interface CodecOptions {
|
|
2152
|
+
/** Resource key — used as the parameter namespace prefix. */
|
|
2153
|
+
resource: string;
|
|
2154
|
+
/** Values equal to these defaults are omitted from the URL. */
|
|
2155
|
+
defaults: ResourceUrlState;
|
|
2156
|
+
/** @deprecated AST envelopes preserve primitive value types directly. */
|
|
2157
|
+
fieldTypes?: Record<string, FieldType>;
|
|
2158
|
+
}
|
|
2159
|
+
/** Serialize one resource's URL slice. AST state is versioned JSON/base64url. */
|
|
2160
|
+
declare function serializeResourceState(state: ResourceUrlState, opts: CodecOptions): URLSearchParams;
|
|
2161
|
+
/** Decode one resource's URL slice; malformed AST envelopes reset atomically. */
|
|
2162
|
+
declare function deserializeResourceState(params: URLSearchParams, opts: CodecOptions): ResourceUrlState;
|
|
2163
|
+
//#endregion
|
|
2164
|
+
//#region src/hooks/url-state/hidden-predicates.d.ts
|
|
2165
|
+
type Expression = FilterExpression<ErasedResourceHandle>;
|
|
2166
|
+
/** Every field an expression names, in order, duplicates kept out. */
|
|
2167
|
+
declare function filterFields(expression: Expression): readonly string[];
|
|
2168
|
+
//#endregion
|
|
2169
|
+
//#region src/hooks/use-field-access.d.ts
|
|
2170
|
+
/**
|
|
2171
|
+
* Every declared field's view and edit decision for the signed-in user (P5 spec 3.4) — the one
|
|
2172
|
+
* `resolveFieldAccess`, never a second branch. `reach: 'record'` decides over `row` (absent: a
|
|
2173
|
+
* create); `'every'` decides for every row at once (the record probe), and ignores `row`.
|
|
2174
|
+
* Memoised by the rules, the user, the scope, the permission map and the row (Known finding 19).
|
|
2175
|
+
* A loading map makes every guarded field `pending`; a resource the registry lacks decides
|
|
2176
|
+
* nothing (`{}`).
|
|
2177
|
+
*/
|
|
2178
|
+
declare function useFieldAccess(resource: string, reach: FieldReach, row?: unknown): FieldAccessMap;
|
|
2179
|
+
/**
|
|
2180
|
+
* The one list predicate of a resource (P5 spec 3.7, decision P5-18): field view in any-record
|
|
2181
|
+
* reach and `column` rules, both with the record probe. Every list surface — the controller's
|
|
2182
|
+
* columns and filter offer, the table, the export dialog, the picker and the palette — reads it.
|
|
2183
|
+
* `pending` while the map loads and a decision depends on it; a resource the registry lacks is
|
|
2184
|
+
* closed (no field, no column).
|
|
2185
|
+
*/
|
|
2186
|
+
declare function useListAccess(resource: string): ListAccess;
|
|
2187
|
+
/**
|
|
2188
|
+
* A list row as view code may read it (P5 spec 3.6.6, plan ruling 9): every field its user may
|
|
2189
|
+
* not view for every row left out — the id kept. For `renderCell`, `rowHref`, cell renderers and
|
|
2190
|
+
* selection-aware views; rules, item-action gates and action handlers keep the row as read
|
|
2191
|
+
* (policy). Memoised per row object while the decisions hold (Known finding 21: a row is never
|
|
2192
|
+
* projected with decisions computed for another).
|
|
2193
|
+
*/
|
|
2194
|
+
declare function useViewRow(resource: string): <T extends object>(row: T) => T;
|
|
2195
|
+
//#endregion
|
|
2196
|
+
//#region src/hooks/use-projected-record.d.ts
|
|
2197
|
+
/** A record as view code may read it: the fields its user may view, or nothing yet. */
|
|
2198
|
+
interface ProjectedRecord {
|
|
2199
|
+
/** `pending` while a decision a read depends on is undecided, or the row is placeholder data. */
|
|
2200
|
+
readonly status: 'pending' | 'ready';
|
|
2201
|
+
/** The row without every field its user may not view (the id kept); `null` for no row. */
|
|
2202
|
+
readonly value: Readonly<Record<string, unknown>> | null;
|
|
2203
|
+
}
|
|
2204
|
+
/**
|
|
2205
|
+
* One record of `resource`, projected by field view in record reach (P5 spec 3.6): a title, a
|
|
2206
|
+
* recent label, a breadcrumb or a peek reads this and never the row as read. `pending` while any
|
|
2207
|
+
* decision is undecided (an undecided field is never shown) and for placeholder data — rows of the
|
|
2208
|
+
* previous record or page never decide a title (Known finding 21). Decisions are keyed by the row
|
|
2209
|
+
* object they were computed for.
|
|
2210
|
+
*/
|
|
2211
|
+
declare function useProjectedRecord(resource: string, row: unknown, opts?: {
|
|
2212
|
+
readonly placeholder?: boolean;
|
|
2213
|
+
}): ProjectedRecord;
|
|
2214
|
+
/**
|
|
2215
|
+
* A record's title as view code may show it (P5 spec 3.6, decision P5-27): `useRecordTitle` over
|
|
2216
|
+
* the projected row, so a display field or a `recordTitle` hook never reads a field its user may
|
|
2217
|
+
* not view. A hidden or undecided title falls back to the `#id` form.
|
|
2218
|
+
*/
|
|
2219
|
+
declare function useProjectedTitle(resource: string | undefined, id: unknown, row: unknown, opts?: {
|
|
2220
|
+
readonly placeholder?: boolean;
|
|
2221
|
+
}): string;
|
|
2222
|
+
//#endregion
|
|
2223
|
+
//#region src/policy-side-channel.d.ts
|
|
2224
|
+
/**
|
|
2225
|
+
* The record as read, for policy: item-action gates and the flows a record page starts.
|
|
2226
|
+
* `fallback` (the controller's own projected `record`) when none was attached.
|
|
2227
|
+
*
|
|
2228
|
+
* @internal `@burojs/ui-shadcn` reads it; view code never does.
|
|
2229
|
+
*/
|
|
2230
|
+
declare function policyRecordOf(controller: object, fallback?: Readonly<Record<string, unknown>>): Readonly<Record<string, unknown>> | undefined;
|
|
2231
|
+
/**
|
|
2232
|
+
* The rows as read, for policy: selection, bulk and item-action gates. `fallback` (the
|
|
2233
|
+
* controller's own `rows`) when none was attached, as for a hand-written controller.
|
|
2234
|
+
*
|
|
2235
|
+
* @internal `@burojs/ui-shadcn` reads it; view code never does.
|
|
2236
|
+
*/
|
|
2237
|
+
declare function policyRowsOf<T extends Record<string, unknown>>(controller: object, fallback: T[]): T[];
|
|
2238
|
+
//#endregion
|
|
1463
2239
|
//#region src/hooks/use-availability.d.ts
|
|
1464
2240
|
/**
|
|
1465
2241
|
* One resolver bound to a resource, for callers that ask about MANY operations
|
|
@@ -1496,18 +2272,23 @@ declare function useAvailability(resource: string, operation: string, record?: u
|
|
|
1496
2272
|
//#region src/hooks/use-app-actions.d.ts
|
|
1497
2273
|
interface AppActionEntry {
|
|
1498
2274
|
readonly name: string;
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
readonly
|
|
2275
|
+
/** The declared default; a renderer resolves `appActions.<name>` in the bundle over it. */
|
|
2276
|
+
readonly label: string;
|
|
2277
|
+
/** `'flow'`: an app flow (P4); run it with `useAction({ appAction: name })`. */
|
|
2278
|
+
readonly kind: 'modal' | 'link' | 'flow';
|
|
2279
|
+
/** `kind: 'modal'`: the block the action presents (P7 3.16), with its portable props. */
|
|
2280
|
+
readonly block?: EntityRef;
|
|
1505
2281
|
readonly props?: Readonly<Record<string, unknown>>;
|
|
1506
|
-
readonly
|
|
2282
|
+
readonly host?: 'dialog' | 'sheet';
|
|
1507
2283
|
readonly to?: string;
|
|
1508
2284
|
readonly icon?: string;
|
|
1509
2285
|
/** Present when a rule allows it but disables it; the rule's own reason. */
|
|
1510
2286
|
readonly disabledReason?: string;
|
|
2287
|
+
/**
|
|
2288
|
+
* A flow hosted on a custom page (`host: { page }`, P7 3.15): the page's own path. Its control
|
|
2289
|
+
* is a guarded link, not a runner; the entry exists only for a user who may open the page.
|
|
2290
|
+
*/
|
|
2291
|
+
readonly hostHref?: string;
|
|
1511
2292
|
}
|
|
1512
2293
|
/**
|
|
1513
2294
|
* Every app-level action (`defineAppAction`, `registerAppAction`) the
|
|
@@ -1525,6 +2306,10 @@ interface AppActionEntry {
|
|
|
1525
2306
|
* the resource argument) without inventing a second gating engine next to
|
|
1526
2307
|
* `useAvailabilityGate`.
|
|
1527
2308
|
*
|
|
2309
|
+
* An app flow (`kind: 'flow'`, P4) is gated by the flow's own gate (`resolveFlowGate`: its
|
|
2310
|
+
* `requires`, its mutation's `requires`, and the same `action/run` rules at the same address),
|
|
2311
|
+
* the one gate its button and `useAction` run; while permissions load it is left out.
|
|
2312
|
+
*
|
|
1528
2313
|
* Rule-hidden (or absent) actions are dropped from the list entirely; a rule
|
|
1529
2314
|
* that allows-but-disables an action keeps it in the list with its
|
|
1530
2315
|
* `disabledReason` set so a caller can render it inert instead of missing.
|
|
@@ -1538,12 +2323,14 @@ declare function useSetSlice<TName extends string = string>(name: TName): (value
|
|
|
1538
2323
|
declare function useT(): (key: string, options?: {
|
|
1539
2324
|
resource?: string;
|
|
1540
2325
|
params?: Record<string, unknown>;
|
|
2326
|
+
count?: number;
|
|
1541
2327
|
}) => string;
|
|
1542
2328
|
/**
|
|
1543
2329
|
* Provider-OPTIONAL translator. Behaves like {@link useT} when mounted inside a
|
|
1544
2330
|
* `BuroProvider`, but does NOT throw when there is no i18n context —
|
|
1545
|
-
* instead it returns the supplied `defaultValue` (interpolated with `params
|
|
1546
|
-
* falling back to the raw
|
|
2331
|
+
* instead it returns the supplied `defaultValue` (interpolated with `params`,
|
|
2332
|
+
* and with `count` as `{{count}}` when one is given), falling back to the raw
|
|
2333
|
+
* key.
|
|
1547
2334
|
*
|
|
1548
2335
|
* Use this for components that ship in `@burojs/ui-shadcn` yet may render
|
|
1549
2336
|
* standalone (outside the provider) — e.g. `<LoginForm>` on a pre-auth screen,
|
|
@@ -1554,13 +2341,13 @@ declare function useOptionalT(): (key: string, options?: {
|
|
|
1554
2341
|
resource?: string;
|
|
1555
2342
|
params?: Record<string, unknown>;
|
|
1556
2343
|
defaultValue?: string;
|
|
2344
|
+
count?: number;
|
|
1557
2345
|
}) => string;
|
|
1558
2346
|
/**
|
|
1559
2347
|
* The active locale code (e.g. `'ru'` / `'en'`), or `'en'` when no i18n
|
|
1560
|
-
* provider is mounted. Powers
|
|
1561
|
-
*
|
|
1562
|
-
*
|
|
1563
|
-
* standalone.
|
|
2348
|
+
* provider is mounted. Powers locale-dependent formatting and re-renders a
|
|
2349
|
+
* component on a language switch. Provider-optional so ui-shadcn components
|
|
2350
|
+
* can render standalone.
|
|
1564
2351
|
*/
|
|
1565
2352
|
declare function useLocale(): string;
|
|
1566
2353
|
/**
|
|
@@ -1568,8 +2355,8 @@ declare function useLocale(): string;
|
|
|
1568
2355
|
*
|
|
1569
2356
|
* The difference from {@link useLocale} is the whole point: `useLocale`
|
|
1570
2357
|
* collapses "the app is running in English" and "there is no app" into the same
|
|
1571
|
-
* `'en'`, which is fine for
|
|
1572
|
-
* last resort
|
|
2358
|
+
* `'en'`, which is fine for picking a label language (English is a defensible
|
|
2359
|
+
* last resort) and wrong for anything that has its own fallback to
|
|
1573
2360
|
* fall back TO. A caller that already knows what "nobody chose a locale" means
|
|
1574
2361
|
* for it — `@burojs/ui-shadcn`'s `Intl` formatters resolve a stored preference
|
|
1575
2362
|
* in that case — must be able to tell the two apart, and with `useLocale` it
|
|
@@ -1587,6 +2374,11 @@ declare function useOptionalLocale(): string | undefined;
|
|
|
1587
2374
|
* so the choice survives a real reload. No-op without a provider.
|
|
1588
2375
|
*/
|
|
1589
2376
|
declare function useChangeLocale(): (locale: string) => void;
|
|
2377
|
+
/**
|
|
2378
|
+
* The `localStorage` key a language control persists the chosen locale under:
|
|
2379
|
+
* `<BuroProvider languageStorageKey>`, or `'buro:language'` without one.
|
|
2380
|
+
*/
|
|
2381
|
+
declare function useLanguageStorageKey(): string;
|
|
1590
2382
|
/**
|
|
1591
2383
|
* Render-time translator, resource-scoped and provider-optional. The canonical
|
|
1592
2384
|
* name for the i18n content model (react-admin `useTranslate` / i18next `t`).
|
|
@@ -1596,6 +2388,7 @@ declare function useChangeLocale(): (locale: string) => void;
|
|
|
1596
2388
|
declare function useTranslate(): (key: string, options?: {
|
|
1597
2389
|
resource?: string;
|
|
1598
2390
|
params?: Record<string, unknown>;
|
|
2391
|
+
count?: number;
|
|
1599
2392
|
}) => string;
|
|
1600
2393
|
/**
|
|
1601
2394
|
* The `has` + `t` capabilities bound to the ambient resource, for the pure
|
|
@@ -1657,8 +2450,20 @@ interface TestIdBuilder {
|
|
|
1657
2450
|
listToolbar: (resource: string) => string;
|
|
1658
2451
|
listAction: (resource: string, actionName: string) => string;
|
|
1659
2452
|
listSearch: (resource: string) => string;
|
|
2453
|
+
/** The filter bar's "Some saved filters were not applied" notice (P5 spec 3.7). */
|
|
2454
|
+
listPredicatesDropped: (resource: string) => string;
|
|
2455
|
+
/** A list frame's slot, around its planned tree (P7-34). */
|
|
2456
|
+
listSlot: (resource: string, slot: string) => string;
|
|
2457
|
+
/** A resource-level flow on the route list's toolbar (P7-31). */
|
|
2458
|
+
listFlow: (resource: string, flowName: string) => string;
|
|
2459
|
+
/** The toolbar's overflow menu of resource-level flows. */
|
|
2460
|
+
listFlowsMenu: (resource: string) => string;
|
|
1660
2461
|
listFilter: (resource: string, fieldName: string) => string;
|
|
1661
2462
|
listTable: (resource: string) => string;
|
|
2463
|
+
/** A `related-list` card (`view: 'cards'`): the placement key and the row id. */
|
|
2464
|
+
relatedCard: (key: string, recordId: string) => string;
|
|
2465
|
+
/** A `related-list` timeline entry (`view: 'timeline'`): the placement key and the row id. */
|
|
2466
|
+
timelineEntry: (key: string, recordId: string) => string;
|
|
1662
2467
|
listRow: (resource: string, recordId: string) => string;
|
|
1663
2468
|
listCell: (resource: string, recordId: string, fieldName: string) => string;
|
|
1664
2469
|
listRowAction: (resource: string, recordId: string, actionName: string) => string;
|
|
@@ -1694,39 +2499,64 @@ interface TestIdBuilder {
|
|
|
1694
2499
|
pageEdit: (resource: string, recordId: string) => string;
|
|
1695
2500
|
pageCreate: (resource: string) => string;
|
|
1696
2501
|
/**
|
|
1697
|
-
* The
|
|
1698
|
-
*
|
|
1699
|
-
* document type. Keyed by RESOURCE and not by the offending value: the value
|
|
2502
|
+
* The notice a record screen renders for a record whose discriminator value
|
|
2503
|
+
* no declared type holds (P1b+P1c decision 64). Keyed by RESOURCE and not by the offending value: the value
|
|
1700
2504
|
* is by definition one the application does not know, so a testid built from
|
|
1701
2505
|
* it could not be written down in advance by the test that looks for it.
|
|
1702
2506
|
*/
|
|
1703
2507
|
unsupportedDocumentType: (resource: string) => string;
|
|
1704
|
-
resourceTab: (resource: string, tabKey: string, recordId?: string) => string;
|
|
1705
|
-
subresourceTabs: (parentResource: string) => string;
|
|
1706
|
-
subresourceTab: (tabKey: string) => string;
|
|
1707
|
-
subresourceBody: (childResource: string) => string;
|
|
1708
|
-
form: (resource: string, view: string, recordId?: string) => string;
|
|
1709
2508
|
/**
|
|
1710
|
-
*
|
|
1711
|
-
*
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
2509
|
+
* A quick overlay (sheet or dialog; P3-21) by its top entry: `quick-sheet:<resource>:<id>`, or
|
|
2510
|
+
* `quick-sheet:<resource>` for a create.
|
|
2511
|
+
*/
|
|
2512
|
+
quickSheet: (resource: string, recordId?: string) => string;
|
|
2513
|
+
/** The quick sheet's Back (when its history is deeper than one entry). */
|
|
2514
|
+
quickBack: () => string;
|
|
2515
|
+
/** The quick overlay's close button. */
|
|
2516
|
+
quickClose: () => string;
|
|
2517
|
+
/** The quick overlay's "Open as page" link. */
|
|
2518
|
+
quickOpenPage: () => string;
|
|
2519
|
+
/** A peek (the hover preview of a relation display's record, P3-22): `peek:<resource>:<key>`. */
|
|
2520
|
+
peek: (resource: string, key: string) => string;
|
|
2521
|
+
/**
|
|
2522
|
+
* A flow's host (P4 spec 4.15) and its controls, by the flow's identity
|
|
2523
|
+
* (`'<ns>:<resource>/actions/<name>'`, `'app/<name>'`): `flow-host:<flowId>`, and
|
|
2524
|
+
* `flow-<control>:<flowId>` for each control.
|
|
1718
2525
|
*/
|
|
1719
|
-
|
|
2526
|
+
flowHost: (flowId: string) => string;
|
|
2527
|
+
/** The page-hosted flow's route body (P6): `page-flow:<flowId>`. */
|
|
2528
|
+
pageFlow: (flowId: string) => string;
|
|
2529
|
+
/** An inline flow's placement (P6): `inline-flow:<flowId>:<placement key>`. */
|
|
2530
|
+
inlineFlow: (flowId: string, key: string) => string;
|
|
2531
|
+
flowSubmit: (flowId: string) => string;
|
|
2532
|
+
flowBack: (flowId: string) => string;
|
|
2533
|
+
/** The footer's Cancel: closes through the dismiss guard. */
|
|
2534
|
+
flowCancel: (flowId: string) => string;
|
|
2535
|
+
/** The header's ✕, and an outcome screen's Close. */
|
|
2536
|
+
flowClose: (flowId: string) => string;
|
|
2537
|
+
/** The outcome message (rejected, failed, unknown, busy). */
|
|
2538
|
+
flowOutcome: (flowId: string) => string;
|
|
2539
|
+
flowCheckAgain: (flowId: string) => string;
|
|
2540
|
+
flowSendAsNew: (flowId: string) => string;
|
|
2541
|
+
flowStartOver: (flowId: string) => string;
|
|
2542
|
+
flowResend: (flowId: string) => string;
|
|
2543
|
+
/** The draft-found banner of a flow's form, and its two buttons (`:restore`, `:discard`). */
|
|
2544
|
+
flowDraft: (flowId: string) => string;
|
|
2545
|
+
/** A bulk flow's per-outcome summary. */
|
|
2546
|
+
bulkSummary: (resource: string, actionName: string) => string;
|
|
2547
|
+
form: (resource: string, view: string, recordId?: string) => string;
|
|
1720
2548
|
formField: (resource: string, view: string, fieldName: string) => string;
|
|
1721
2549
|
formFieldInput: (resource: string, view: string, fieldName: string) => string;
|
|
1722
2550
|
formFieldError: (resource: string, view: string, fieldName: string) => string;
|
|
1723
2551
|
formFieldLocked: (resource: string, view: string, fieldName: string) => string;
|
|
2552
|
+
/** A field leaf its user may not read the value of: the label and the restriction, no value. */
|
|
2553
|
+
formFieldRestricted: (resource: string, view: string, fieldName: string) => string;
|
|
1724
2554
|
/**
|
|
1725
2555
|
* A field's help text — the hint under the input, resolved from the i18n
|
|
1726
|
-
* `
|
|
2556
|
+
* `fields.<name>.description` slot or from the field's description.
|
|
1727
2557
|
*
|
|
1728
2558
|
* ⚠️ This one was the other way round: the id was spelled identically on
|
|
1729
|
-
* both sides and simply never rendered.
|
|
2559
|
+
* both sides and simply never rendered. the old record form drew the hint
|
|
1730
2560
|
* paragraph with an `id` (for `aria-describedby`) and no `data-testid`, so
|
|
1731
2561
|
* `form.field(x).help()` had matched nothing since it was written. The
|
|
1732
2562
|
* producer was added at SP9 task 5, which is what lets a browser test assert
|
|
@@ -1754,6 +2584,8 @@ interface TestIdBuilder {
|
|
|
1754
2584
|
* Auto-save / draft-found banner (B7.1). Rendered above the form's
|
|
1755
2585
|
* field stack on mount when a non-stale localStorage draft exists.
|
|
1756
2586
|
*/
|
|
2587
|
+
/** One option of the built-in type offer of a typed create (P1b+P1c decision 24). */
|
|
2588
|
+
typeOffer: (resource: string, type: string) => string;
|
|
1757
2589
|
formDraftBanner: (resource: string, view: string) => string;
|
|
1758
2590
|
/** Restore button inside the draft banner (B7.1). */
|
|
1759
2591
|
formDraftRestore: (resource: string, view: string) => string;
|
|
@@ -1788,13 +2620,28 @@ interface TestIdBuilder {
|
|
|
1788
2620
|
* element inside it that does.
|
|
1789
2621
|
*
|
|
1790
2622
|
* The trigger takes the TARGET resource, not (resource, view, field): the
|
|
1791
|
-
* component composes it from `to`. Inside a
|
|
2623
|
+
* component composes it from `to`. Inside a record form the trigger's
|
|
1792
2624
|
* id is overridden with `formFieldInput(resource, view, field)` — the form
|
|
1793
2625
|
* passes its own `testid` prop so a field's input is addressable the same
|
|
1794
2626
|
* way whatever its kind — while every child of the popover keeps the
|
|
1795
2627
|
* per-target prefix below. Both facts are asserted in that same test.
|
|
1796
2628
|
*/
|
|
1797
2629
|
pickerTrigger: (targetResource: string) => string;
|
|
2630
|
+
/**
|
|
2631
|
+
* The select's "view" button (P6-28): the target resource and the form field that holds the key,
|
|
2632
|
+
* `relation-view:<target>:<field>`.
|
|
2633
|
+
*/
|
|
2634
|
+
relationView: (targetResource: string, field: string) => string;
|
|
2635
|
+
/** The select's "+ create" button (P6-29): `relation-create:<target>:<field>`. */
|
|
2636
|
+
relationCreate: (targetResource: string, field: string) => string;
|
|
2637
|
+
/**
|
|
2638
|
+
* What the select says in place of its options while it must not read (P7 3.4): which field to
|
|
2639
|
+
* choose first, or that its candidates name a field the user may not see.
|
|
2640
|
+
* `relation-candidates-hint:<resource>:<field>`.
|
|
2641
|
+
*/
|
|
2642
|
+
relationCandidatesHint: (resource: string, field: string) => string;
|
|
2643
|
+
/** A chip of a to-many select (P7 3.5): `relation-many-chip:<resource>:<field>:<id>`. */
|
|
2644
|
+
relationManyChip: (resource: string, field: string, id: string) => string;
|
|
1798
2645
|
/** The popover's search box. */
|
|
1799
2646
|
pickerSearch: (targetResource: string) => string;
|
|
1800
2647
|
/** The popover's result list (the popover content itself carries no id). */
|
|
@@ -1815,12 +2662,6 @@ interface TestIdBuilder {
|
|
|
1815
2662
|
pickerDialogSearch: (targetResource: string) => string;
|
|
1816
2663
|
/** The disabled trigger rendered when the target resource is unregistered. */
|
|
1817
2664
|
pickerUnregistered: (targetResource: string) => string;
|
|
1818
|
-
actionConfirmDialog: (resource: string, scope: string, actionName: string, recordId?: string) => string;
|
|
1819
|
-
actionConfirmYes: (resource: string, scope: string, actionName: string) => string;
|
|
1820
|
-
actionConfirmNo: (resource: string, scope: string, actionName: string) => string;
|
|
1821
|
-
formModal: (resource: string, scope: string, actionName: string, recordId?: string) => string;
|
|
1822
|
-
formModalSubmit: (resource: string, scope: string, actionName: string) => string;
|
|
1823
|
-
formModalCancel: (resource: string, scope: string, actionName: string) => string;
|
|
1824
2665
|
childrenTable: (resource: string, view: string, fieldName: string) => string;
|
|
1825
2666
|
childrenRow: (resource: string, view: string, fieldName: string, index: number) => string;
|
|
1826
2667
|
childrenAdd: (resource: string, view: string, fieldName: string) => string;
|
|
@@ -1867,20 +2708,6 @@ declare function useTestIds(): TestIdBuilder;
|
|
|
1867
2708
|
*/
|
|
1868
2709
|
declare function useRecordTitle(resource: string | undefined, id: unknown, record?: unknown): string;
|
|
1869
2710
|
//#endregion
|
|
1870
|
-
//#region src/hooks/use-action.d.ts
|
|
1871
|
-
interface UseActionResult {
|
|
1872
|
-
run: () => Promise<void>;
|
|
1873
|
-
isRunning: boolean;
|
|
1874
|
-
error: Error | null;
|
|
1875
|
-
}
|
|
1876
|
-
interface UseActionArgs<TRecord, R extends ResourceHandle<any, any, any, any> = ResourceHandle<any, any, any, any>> {
|
|
1877
|
-
resource: R;
|
|
1878
|
-
record: TRecord;
|
|
1879
|
-
values?: Partial<TRecord>;
|
|
1880
|
-
dispatcher: Dispatcher;
|
|
1881
|
-
}
|
|
1882
|
-
declare function useAction<TRecord = unknown, R extends ResourceHandle<any, any, any, any> = ResourceHandle<any, any, any, any>>(action: Action<TRecord>, args: UseActionArgs<TRecord, R>): UseActionResult;
|
|
1883
|
-
//#endregion
|
|
1884
2711
|
//#region src/hooks/use-task-run.d.ts
|
|
1885
2712
|
/**
|
|
1886
2713
|
* DRIVES ONE PIECE OF WORK AND KEEPS A {@link TaskRunReport} A VIEW CAN RENDER.
|
|
@@ -1893,8 +2720,8 @@ declare function useAction<TRecord = unknown, R extends ResourceHandle<any, any,
|
|
|
1893
2720
|
*
|
|
1894
2721
|
* That is deliberate and it is what makes this not an operations affordance.
|
|
1895
2722
|
* The two callers this framework already has for it are a polled server-side
|
|
1896
|
-
* run and a client-side `for` loop over selected rows (
|
|
1897
|
-
*
|
|
2723
|
+
* run and a client-side `for` loop over selected rows (a bulk flow has its own
|
|
2724
|
+
* per-outcome summary since P4) — nothing about a poll or a loop appears
|
|
1898
2725
|
* anywhere below.
|
|
1899
2726
|
*/
|
|
1900
2727
|
/** What a running task tells the report. Handed to the task; never held afterwards. */
|
|
@@ -1964,6 +2791,16 @@ interface UseChecksOptions {
|
|
|
1964
2791
|
readonly debounceMs?: number;
|
|
1965
2792
|
readonly enabled?: boolean;
|
|
1966
2793
|
readonly actionName?: string;
|
|
2794
|
+
/**
|
|
2795
|
+
* The screen's `with` sources the checks read, by name (P2 4.10). Pass a stable object: a
|
|
2796
|
+
* new one re-runs the inline pass.
|
|
2797
|
+
*/
|
|
2798
|
+
readonly sources?: Readonly<Record<string, SourceState>>;
|
|
2799
|
+
}
|
|
2800
|
+
/** The values one authoritative pass evaluates, when they are not the render's. */
|
|
2801
|
+
interface CheckPassValues {
|
|
2802
|
+
readonly values: Record<string, unknown>;
|
|
2803
|
+
readonly saved?: Record<string, unknown>;
|
|
1967
2804
|
}
|
|
1968
2805
|
interface UseChecksResult {
|
|
1969
2806
|
readonly inlineIssues: ValidationIssues;
|
|
@@ -1977,89 +2814,28 @@ interface UseChecksResult {
|
|
|
1977
2814
|
* empty because nothing was evaluated — a caller MUST NOT read that as
|
|
1978
2815
|
* "nothing fired" and proceed. Check `outcome.aborted` before
|
|
1979
2816
|
* `outcome.blockers`.
|
|
2817
|
+
*
|
|
2818
|
+
* `over` evaluates the given values (and saved record) instead of the ones
|
|
2819
|
+
* this render passed: a submit decides on exactly the values it submits.
|
|
1980
2820
|
*/
|
|
1981
|
-
readonly runNow: () => Promise<CheckOutcome>;
|
|
2821
|
+
readonly runNow: (over?: CheckPassValues) => Promise<CheckOutcome>;
|
|
1982
2822
|
}
|
|
1983
2823
|
declare function useChecks(options: UseChecksOptions): UseChecksResult;
|
|
1984
2824
|
//#endregion
|
|
1985
|
-
//#region src/
|
|
1986
|
-
interface
|
|
1987
|
-
|
|
1988
|
-
readonly
|
|
1989
|
-
readonly
|
|
1990
|
-
readonly record?: Record<string, unknown>;
|
|
1991
|
-
readonly actionName?: string;
|
|
1992
|
-
/** An existing `action.confirm` message; becomes the dialog header. */
|
|
1993
|
-
readonly header?: string | null;
|
|
1994
|
-
}
|
|
1995
|
-
interface CheckGateState {
|
|
2825
|
+
//#region src/hooks/use-refresh.d.ts
|
|
2826
|
+
interface UseRefreshResult {
|
|
2827
|
+
/** Invalidates every native data query and resolves once the active ones have refetched. */
|
|
2828
|
+
readonly refresh: () => Promise<void>;
|
|
2829
|
+
readonly isRefreshing: boolean;
|
|
1996
2830
|
/**
|
|
1997
|
-
*
|
|
1998
|
-
*
|
|
1999
|
-
*
|
|
2000
|
-
* reaches the per-resource entry `resources.<name>.checks.<id>` when a
|
|
2001
|
-
* resource is bound.
|
|
2002
|
-
*
|
|
2003
|
-
* It must travel WITH the state rather than being passed to the dialog
|
|
2004
|
-
* separately — the ambient `ResourceContext` is not a substitute. Only
|
|
2005
|
-
* `<ResourceShow>` and `<ResourceForm>` mount one, so an action gated from a
|
|
2006
|
-
* LIST ROW has no ambient resource at all, and the same check would render
|
|
2007
|
-
* translated on a show page and untranslated in the list. (Exactly the bug
|
|
2008
|
-
* `useResolvedLabel` in `action-button.tsx` carries a comment about.)
|
|
2009
|
-
*
|
|
2010
|
-
* Optional because a resource-less host — `<DeclarativeForm>` builds this
|
|
2011
|
-
* shape by hand — genuinely has no resource to name.
|
|
2831
|
+
* False without a native data runtime: there is nothing to refresh and `refresh` is a no-op.
|
|
2832
|
+
* A bare `QueryClientProvider` does not count — only the data runtime's own query client holds
|
|
2833
|
+
* the queries this hook invalidates.
|
|
2012
2834
|
*/
|
|
2013
|
-
readonly
|
|
2014
|
-
readonly open: boolean;
|
|
2015
|
-
readonly busy: boolean;
|
|
2016
|
-
readonly header: string | null;
|
|
2017
|
-
readonly blockers: ValidationIssues;
|
|
2018
|
-
readonly confirmable: ValidationIssues;
|
|
2019
|
-
readonly proceed: () => void;
|
|
2020
|
-
readonly cancel: () => void;
|
|
2021
|
-
}
|
|
2022
|
-
interface UseCheckGateResult {
|
|
2023
|
-
readonly run: (request: CheckGateRequest) => Promise<'proceed' | 'cancel'>;
|
|
2024
|
-
readonly state: CheckGateState;
|
|
2025
|
-
}
|
|
2026
|
-
/**
|
|
2027
|
-
* Imperative pre-flight gate. `run()` evaluates the resource's checks for the
|
|
2028
|
-
* surface, and resolves immediately with 'proceed' when there is nothing to say.
|
|
2029
|
-
* Otherwise it opens (the host renders the dialog off `state`) and resolves once
|
|
2030
|
-
* the user decides. One dialog: an existing `action.confirm` becomes its header
|
|
2031
|
-
* rather than a second prompt.
|
|
2032
|
-
*/
|
|
2033
|
-
declare function useCheckGate(resource: string): UseCheckGateResult;
|
|
2034
|
-
//#endregion
|
|
2035
|
-
//#region src/hooks/use-bulk-action.d.ts
|
|
2036
|
-
interface UseBulkActionResult {
|
|
2037
|
-
/** Resolves with the dispatched result, or `undefined` if the dispatch itself failed. */
|
|
2038
|
-
run: () => Promise<ActionResult | undefined>;
|
|
2039
|
-
isRunning: boolean;
|
|
2040
|
-
error: Error | null;
|
|
2041
|
-
}
|
|
2042
|
-
interface UseBulkActionArgs<TRecord, R extends ResourceHandle<any, any, any, any> = ResourceHandle<any, any, any, any>> {
|
|
2043
|
-
resource: R;
|
|
2044
|
-
records: TRecord[];
|
|
2045
|
-
/** Every selected id — see {@link BulkActionDI.ids}. */
|
|
2046
|
-
ids: string[];
|
|
2047
|
-
dispatcher: Dispatcher;
|
|
2835
|
+
readonly available: boolean;
|
|
2048
2836
|
}
|
|
2049
|
-
/**
|
|
2050
|
-
|
|
2051
|
-
* result flows through the host dispatcher's effects pipeline (notify,
|
|
2052
|
-
* clearSelection, refetch, redirect). Mirrors `useAction` API surface
|
|
2053
|
-
* (`{ run, isRunning, error }`) so call sites stay symmetric.
|
|
2054
|
-
*
|
|
2055
|
-
* The dispatcher's `Action` union doesn't currently include
|
|
2056
|
-
* `BulkActionHandler` (single-record vs bulk DI shape), but at runtime
|
|
2057
|
-
* both share `kind: 'handler'` and an identical handler-returning-result
|
|
2058
|
-
* contract. We cast at the dispatcher boundary so the runtime `kind`
|
|
2059
|
-
* guard still passes; the dispatcher itself doesn't read the DI shape
|
|
2060
|
-
* — handlers do — so the cast is sound.
|
|
2061
|
-
*/
|
|
2062
|
-
declare function useBulkAction<TRecord = unknown, R extends ResourceHandle<any, any, any, any> = ResourceHandle<any, any, any, any>>(action: BulkActionHandler<TRecord>, args: UseBulkActionArgs<TRecord, R>): UseBulkActionResult;
|
|
2837
|
+
/** Refetches all data the app is showing: a header "Refresh" control, or any custom trigger. */
|
|
2838
|
+
declare function useRefresh(): UseRefreshResult;
|
|
2063
2839
|
//#endregion
|
|
2064
2840
|
//#region src/hooks/use-local-storage.d.ts
|
|
2065
2841
|
/**
|
|
@@ -2082,14 +2858,17 @@ declare function useLocalStorage<T>(key: string, initial?: T): [T | undefined, (
|
|
|
2082
2858
|
//#endregion
|
|
2083
2859
|
//#region src/hooks/router/router-adapter.d.ts
|
|
2084
2860
|
/**
|
|
2085
|
-
* The framework's whole dependency on a router
|
|
2861
|
+
* The framework's whole dependency on a router: where the app is and how to
|
|
2862
|
+
* move. It is the router's only binding — route matching, the active nav item,
|
|
2863
|
+
* breadcrumbs, URL state and every framework navigation read or write through
|
|
2864
|
+
* it — and `LinkComponentProvider` only renders anchors. Mount it with
|
|
2865
|
+
* `RouterAdapterProvider`.
|
|
2086
2866
|
*
|
|
2087
|
-
*
|
|
2088
|
-
*
|
|
2089
|
-
* hooks. Links were already injected through `LinkComponentProvider`; this is
|
|
2090
|
-
* the same idea for location and navigation.
|
|
2867
|
+
* Every member is app-space: `pathname` without the router's basename, and
|
|
2868
|
+
* `push` / `replace` take a path the router prefixes itself.
|
|
2091
2869
|
*/
|
|
2092
2870
|
interface RouterAdapter {
|
|
2871
|
+
/** The current path, without the router's basename. */
|
|
2093
2872
|
pathname: string;
|
|
2094
2873
|
searchParams: URLSearchParams;
|
|
2095
2874
|
/** Navigate without adding a history entry — used for URL-state sync. */
|
|
@@ -2100,8 +2879,77 @@ interface RouterAdapterProviderProps {
|
|
|
2100
2879
|
adapter: RouterAdapter;
|
|
2101
2880
|
children: React.ReactNode;
|
|
2102
2881
|
}
|
|
2882
|
+
/**
|
|
2883
|
+
* Binds your router to the framework. Required: mount it **above**
|
|
2884
|
+
* `<BuroProvider>`, once for the whole app. Without it no route matches
|
|
2885
|
+
* (`<NavAreaPage>` renders not-found and says so in development), no nav item
|
|
2886
|
+
* is active, and every framework navigation falls back to a full page load.
|
|
2887
|
+
* The default `redirect` and the navigation guard's "Leave" read the adapter
|
|
2888
|
+
* from where `<BuroProvider>` sits, so one mounted inside it is invisible to
|
|
2889
|
+
* them. `LinkComponentProvider` (`@burojs/ui-shadcn`) only renders anchors;
|
|
2890
|
+
* it is not a router binding.
|
|
2891
|
+
*
|
|
2892
|
+
* react-router (v7; v6 exports the same hooks from `react-router-dom`):
|
|
2893
|
+
*
|
|
2894
|
+
* ```tsx
|
|
2895
|
+
* import { RouterAdapterProvider } from '@burojs/react';
|
|
2896
|
+
* import * as React from 'react';
|
|
2897
|
+
* import { useLocation, useNavigate, useSearchParams } from 'react-router';
|
|
2898
|
+
*
|
|
2899
|
+
* export function ReactRouterAdapter({ children }: { children: React.ReactNode }) {
|
|
2900
|
+
* const location = useLocation();
|
|
2901
|
+
* const navigate = useNavigate();
|
|
2902
|
+
* const [searchParams] = useSearchParams();
|
|
2903
|
+
* const adapter = React.useMemo(
|
|
2904
|
+
* () => ({
|
|
2905
|
+
* pathname: location.pathname,
|
|
2906
|
+
* searchParams,
|
|
2907
|
+
* replace: (url: string) => navigate(url, { replace: true }),
|
|
2908
|
+
* push: (url: string) => navigate(url),
|
|
2909
|
+
* }),
|
|
2910
|
+
* [location.pathname, searchParams, navigate],
|
|
2911
|
+
* );
|
|
2912
|
+
* return <RouterAdapterProvider adapter={adapter}>{children}</RouterAdapterProvider>;
|
|
2913
|
+
* }
|
|
2914
|
+
* ```
|
|
2915
|
+
*
|
|
2916
|
+
* Next App Router (a client component):
|
|
2917
|
+
*
|
|
2918
|
+
* ```tsx
|
|
2919
|
+
* 'use client';
|
|
2920
|
+
* import { RouterAdapterProvider } from '@burojs/react';
|
|
2921
|
+
* import { usePathname, useRouter, useSearchParams } from 'next/navigation';
|
|
2922
|
+
* import * as React from 'react';
|
|
2923
|
+
*
|
|
2924
|
+
* export function NextRouterAdapter({ children }: { children: React.ReactNode }) {
|
|
2925
|
+
* const router = useRouter();
|
|
2926
|
+
* const pathname = usePathname();
|
|
2927
|
+
* const search = useSearchParams();
|
|
2928
|
+
* const adapter = React.useMemo(
|
|
2929
|
+
* () => ({
|
|
2930
|
+
* pathname,
|
|
2931
|
+
* searchParams: new URLSearchParams(search.toString()),
|
|
2932
|
+
* replace: (url: string) => router.replace(url, { scroll: false }),
|
|
2933
|
+
* push: (url: string) => router.push(url),
|
|
2934
|
+
* }),
|
|
2935
|
+
* [pathname, search, router],
|
|
2936
|
+
* );
|
|
2937
|
+
* return <RouterAdapterProvider adapter={adapter}>{children}</RouterAdapterProvider>;
|
|
2938
|
+
* }
|
|
2939
|
+
* ```
|
|
2940
|
+
*
|
|
2941
|
+
* Then: `<ReactRouterAdapter><BuroProvider app={app}>…</BuroProvider></ReactRouterAdapter>`.
|
|
2942
|
+
*/
|
|
2103
2943
|
declare function RouterAdapterProvider({ adapter, children }: RouterAdapterProviderProps): React.ReactElement;
|
|
2104
2944
|
declare function useRouterAdapter(): RouterAdapter;
|
|
2945
|
+
/**
|
|
2946
|
+
* The router adapter, or `null` when none is mounted.
|
|
2947
|
+
*
|
|
2948
|
+
* `useRouterAdapter` throws by design — URL state that silently never persists
|
|
2949
|
+
* is worse than a crash. Audit is the opposite case: an app with no router is
|
|
2950
|
+
* legitimate, and auditing must never be the thing that breaks it.
|
|
2951
|
+
*/
|
|
2952
|
+
declare function useOptionalRouterAdapter(): RouterAdapter | null;
|
|
2105
2953
|
//#endregion
|
|
2106
2954
|
//#region src/hooks/use-debounced-value.d.ts
|
|
2107
2955
|
/**
|
|
@@ -2308,6 +3156,11 @@ interface UseEnumValuesResult {
|
|
|
2308
3156
|
declare function useEnumValues(enumName: string): UseEnumValuesResult;
|
|
2309
3157
|
//#endregion
|
|
2310
3158
|
//#region src/hooks/relation-aggregator.d.ts
|
|
3159
|
+
/**
|
|
3160
|
+
* The most keys of one `by` read when the application declares no provider maximum: a batch asks
|
|
3161
|
+
* for `2 × keys` rows, so it is read in chunks of half this many keys.
|
|
3162
|
+
*/
|
|
3163
|
+
declare const RELATION_BATCH_MAX_PAGE = 100;
|
|
2311
3164
|
/**
|
|
2312
3165
|
* A resolved relation record. Mirrors the shape used by the legacy
|
|
2313
3166
|
* per-cell `useRelatedRecord` (see the deleted
|
|
@@ -2326,22 +3179,25 @@ interface UseRelatedRecordResult {
|
|
|
2326
3179
|
* surfaces a per-id error (a dangling FK degrades to `record: undefined`
|
|
2327
3180
|
* instead, matching today's fail-soft display behaviour). */
|
|
2328
3181
|
error: Error | null;
|
|
3182
|
+
/**
|
|
3183
|
+
* True when the key matched more than one row of the target (a `by` key the backend does not
|
|
3184
|
+
* keep unique): `record` stays undefined, the display renders the key muted, and one
|
|
3185
|
+
* development error names the target, the field and the key. Never picks either row.
|
|
3186
|
+
*/
|
|
3187
|
+
ambiguous: boolean;
|
|
2329
3188
|
}
|
|
2330
|
-
|
|
2331
|
-
|
|
3189
|
+
/** Options of `useRelatedRecord`: the target field the key holds, and the display's resolve. */
|
|
3190
|
+
interface UseRelatedRecordOptions {
|
|
3191
|
+
/** The target field the key is matched on; the target's id field when absent. */
|
|
3192
|
+
readonly by?: string;
|
|
3193
|
+
/** `'lazy'` registers nothing and reads nothing (spec 4.3); `'eager'` is the default. */
|
|
3194
|
+
readonly resolve?: 'eager' | 'lazy';
|
|
2332
3195
|
}
|
|
2333
3196
|
/**
|
|
2334
|
-
*
|
|
2335
|
-
*
|
|
2336
|
-
* instead of holding its own react-query observer; this component renders
|
|
2337
|
-
* one `<ResourceBatch>` per resource that currently has un-resolved
|
|
2338
|
-
* registered ids.
|
|
2339
|
-
*/
|
|
2340
|
-
declare function RelationAggregatorProvider({ children }: RelationAggregatorProviderProps): ReactElement;
|
|
2341
|
-
/**
|
|
2342
|
-
* Resolve a single record by `(targetResource, id)` for relation display.
|
|
3197
|
+
* Resolve a single record by `(targetResource, key)` for relation display: by the target's id
|
|
3198
|
+
* field, or by `options.by` (one batched `where <by> in [...]` list read per pair and flush).
|
|
2343
3199
|
*
|
|
2344
|
-
*
|
|
3200
|
+
* Under a `<BuroProvider>` with a data runtime (which mounts the aggregator): registers demand
|
|
2345
3201
|
* (refcounted) and reads from the shared external store via
|
|
2346
3202
|
* `useSyncExternalStore` — NO react-query observer per call. All calls for
|
|
2347
3203
|
* the same resource on screen share ONE batched `getList(id in [...])`.
|
|
@@ -2355,52 +3211,16 @@ declare function RelationAggregatorProvider({ children }: RelationAggregatorProv
|
|
|
2355
3211
|
* render; behaviour is selected by branching on VALUES (`store`, `idStr`),
|
|
2356
3212
|
* never by skipping a hook call.
|
|
2357
3213
|
*/
|
|
2358
|
-
declare function useRelatedRecord(targetResource: string, id: string | number | null | undefined): UseRelatedRecordResult;
|
|
3214
|
+
declare function useRelatedRecord(targetResource: string, id: string | number | null | undefined, options?: UseRelatedRecordOptions): UseRelatedRecordResult;
|
|
2359
3215
|
//#endregion
|
|
2360
|
-
//#region src/hooks/url-state/
|
|
2361
|
-
type ResourceFilter = FilterExpression<ErasedResourceHandle>;
|
|
2362
|
-
type ResourceSort = SortExpression<ErasedResourceHandle>;
|
|
3216
|
+
//#region src/hooks/url-state/list-state-store.d.ts
|
|
2363
3217
|
/**
|
|
2364
|
-
*
|
|
2365
|
-
*
|
|
2366
|
-
* server rendering or the first client render do unbounded recursive work.
|
|
3218
|
+
* Where a list keeps its state (P1b+P1c decision 58): `'memory'`, which never touches the URL, or
|
|
3219
|
+
* the URL under a namespace (`{ url: 'lines' }` writes `?lines.page=2`).
|
|
2367
3220
|
*/
|
|
2368
|
-
|
|
2369
|
-
readonly
|
|
2370
|
-
readonly maxFilters: 50;
|
|
2371
|
-
readonly maxFilterDepth: 16;
|
|
2372
|
-
readonly maxFilterNodes: 200;
|
|
2373
|
-
readonly maxSortEntries: 20;
|
|
3221
|
+
type ListState = 'memory' | {
|
|
3222
|
+
readonly url: string;
|
|
2374
3223
|
};
|
|
2375
|
-
/** Typed, router-independent state for an interactive resource list. */
|
|
2376
|
-
interface ResourceUrlState {
|
|
2377
|
-
filters: readonly ResourceFilter[];
|
|
2378
|
-
/** The builder group. `filters` above is the PINNED slot — always ANDed. */
|
|
2379
|
-
filterGroup: FilterGroup;
|
|
2380
|
-
sort: ResourceSort;
|
|
2381
|
-
page: number;
|
|
2382
|
-
pageSize: number;
|
|
2383
|
-
search: string;
|
|
2384
|
-
visibleColumns: string[] | null;
|
|
2385
|
-
}
|
|
2386
|
-
/**
|
|
2387
|
-
* Kept temporarily as a source-level migration seam for the list controller.
|
|
2388
|
-
* URL AST values preserve their JSON primitive type and no longer use this
|
|
2389
|
-
* hint for serialization or decoding.
|
|
2390
|
-
*/
|
|
2391
|
-
type FieldType = 'string' | 'number' | 'boolean' | 'enum' | 'relation' | 'date';
|
|
2392
|
-
interface CodecOptions {
|
|
2393
|
-
/** Resource key — used as the parameter namespace prefix. */
|
|
2394
|
-
resource: string;
|
|
2395
|
-
/** Values equal to these defaults are omitted from the URL. */
|
|
2396
|
-
defaults: ResourceUrlState;
|
|
2397
|
-
/** @deprecated AST envelopes preserve primitive value types directly. */
|
|
2398
|
-
fieldTypes?: Record<string, FieldType>;
|
|
2399
|
-
}
|
|
2400
|
-
/** Serialize one resource's URL slice. AST state is versioned JSON/base64url. */
|
|
2401
|
-
declare function serializeResourceState(state: ResourceUrlState, opts: CodecOptions): URLSearchParams;
|
|
2402
|
-
/** Decode one resource's URL slice; malformed AST envelopes reset atomically. */
|
|
2403
|
-
declare function deserializeResourceState(params: URLSearchParams, opts: CodecOptions): ResourceUrlState;
|
|
2404
3224
|
//#endregion
|
|
2405
3225
|
//#region src/hooks/url-state/use-resource-url-state.d.ts
|
|
2406
3226
|
/**
|
|
@@ -2485,7 +3305,7 @@ interface SetterOptions {
|
|
|
2485
3305
|
*
|
|
2486
3306
|
* Cross-resource isolation: params NOT prefixed with `<resource>.` are
|
|
2487
3307
|
* preserved verbatim on every update. Two list views on the same page
|
|
2488
|
-
* (
|
|
3308
|
+
* (`related-list` placements in URL state) can each call this hook for their
|
|
2489
3309
|
* own resource without colliding.
|
|
2490
3310
|
*
|
|
2491
3311
|
* Cold deep links: the initial render reads the router adapter's
|
|
@@ -2515,7 +3335,24 @@ interface SetterOptions {
|
|
|
2515
3335
|
declare function useResourceUrlState(resource: string, opts?: {
|
|
2516
3336
|
defaults?: Partial<ResourceUrlState>;
|
|
2517
3337
|
fieldTypes?: Record<string, FieldType>;
|
|
3338
|
+
/**
|
|
3339
|
+
* Where the state lives: the URL under `?<resource>.` by default, the URL under another
|
|
3340
|
+
* namespace (`{ url: 'lines' }`), or `'memory'`, which never writes the URL.
|
|
3341
|
+
*/
|
|
3342
|
+
state?: ListState;
|
|
3343
|
+
/**
|
|
3344
|
+
* The list's field view (P5 spec 3.7): a filter, group leaf or sort entry naming a field for
|
|
3345
|
+
* which `visible` is false is dropped when the state is read — before any chip or request —
|
|
3346
|
+
* and from every write. Once `ready` (the list's decisions are settled) the address is
|
|
3347
|
+
* rewritten without it, as a `replace`, through the same writer. Absent: nothing is dropped.
|
|
3348
|
+
*/
|
|
3349
|
+
predicates?: {
|
|
3350
|
+
readonly visible: (field: string) => boolean;
|
|
3351
|
+
readonly ready: boolean;
|
|
3352
|
+
};
|
|
2518
3353
|
}): ResourceUrlState & {
|
|
3354
|
+
/** How many predicates on hidden fields the address has carried and lost so far. */
|
|
3355
|
+
droppedPredicates: number;
|
|
2519
3356
|
setFilters: (filters: readonly FilterExpression<ErasedResourceHandle>[], options?: SetterOptions) => void;
|
|
2520
3357
|
setFilterGroup: (group: FilterGroup, options?: SetterOptions) => void;
|
|
2521
3358
|
setSort: (sort: ResourceUrlState['sort'], options?: SetterOptions) => void;
|
|
@@ -2747,6 +3584,13 @@ declare function useSavedViews(resource: string): UseSavedViewsResult;
|
|
|
2747
3584
|
*/
|
|
2748
3585
|
interface ApplyViewToUrlStateOptions {
|
|
2749
3586
|
defaults?: Omit<Partial<ResourceUrlState>, 'page'>;
|
|
3587
|
+
/**
|
|
3588
|
+
* The list's field view (P5 spec 3.7): a filter, group leaf or sort entry the view (or a
|
|
3589
|
+
* default) carries on a field for which `visible` is false is dropped BEFORE any setter is
|
|
3590
|
+
* called, so a view saved by a user who may see the field never writes its value into the
|
|
3591
|
+
* address bar, history or a chip. Absent: nothing is dropped.
|
|
3592
|
+
*/
|
|
3593
|
+
visible?: (field: string) => boolean;
|
|
2750
3594
|
}
|
|
2751
3595
|
/**
|
|
2752
3596
|
* Subset of the `useResourceUrlState` return value the helper needs.
|
|
@@ -2810,7 +3654,9 @@ interface ApplyViewUrlStateSetters {
|
|
|
2810
3654
|
* pageSize, search, visibleColumns). That keeps it trivially unit-testable
|
|
2811
3655
|
* with a mock urlState.
|
|
2812
3656
|
*/
|
|
2813
|
-
declare function applyViewToUrlState(view: SavedViewDef, urlState: ApplyViewUrlStateSetters, options?: ApplyViewToUrlStateOptions):
|
|
3657
|
+
declare function applyViewToUrlState(view: SavedViewDef, urlState: ApplyViewUrlStateSetters, options?: ApplyViewToUrlStateOptions): {
|
|
3658
|
+
readonly dropped: number;
|
|
3659
|
+
};
|
|
2814
3660
|
//#endregion
|
|
2815
3661
|
//#region src/hooks/command-palette/use-command-palette.d.ts
|
|
2816
3662
|
/**
|
|
@@ -2875,122 +3721,57 @@ interface UseCommandPaletteOptions {
|
|
|
2875
3721
|
*/
|
|
2876
3722
|
declare function useCommandPalette(opts?: UseCommandPaletteOptions): UseCommandPaletteResult;
|
|
2877
3723
|
//#endregion
|
|
2878
|
-
//#region src/
|
|
2879
|
-
/**
|
|
2880
|
-
* Storage shape for one entry in the "recently visited" list.
|
|
2881
|
-
*
|
|
2882
|
-
* - `resource` — registry name of the resource (e.g. `document_document`).
|
|
2883
|
-
* - `id` — record id, always coerced to string for stable storage shape
|
|
2884
|
-
* even when adopters use numeric ids.
|
|
2885
|
-
* - `label` — human-readable display label resolved at write time
|
|
2886
|
-
* (alias → name → title → label → fallback to id). Captured at write
|
|
2887
|
-
* so the Recent group survives even if the record is later deleted
|
|
2888
|
-
* server-side; the navigation will 404 but the entry still renders
|
|
2889
|
-
* and identifies which record it referenced.
|
|
2890
|
-
* - `visitedAt` — ISO timestamp of the most-recent visit. Updated on
|
|
2891
|
-
* each call to `useTrackRecentRecord`.
|
|
2892
|
-
*/
|
|
2893
|
-
interface RecentRecord {
|
|
2894
|
-
resource: string;
|
|
2895
|
-
id: string;
|
|
2896
|
-
label: string;
|
|
2897
|
-
visitedAt: string;
|
|
2898
|
-
}
|
|
3724
|
+
//#region src/flows/row-batch.d.ts
|
|
2899
3725
|
/**
|
|
2900
|
-
*
|
|
2901
|
-
*
|
|
2902
|
-
*
|
|
2903
|
-
*
|
|
2904
|
-
* 1. Current v1 envelope `{ version: 1, items: RecentRecord[] }`.
|
|
2905
|
-
* 2. Legacy / defensive bare-array form (migrated on next write).
|
|
2906
|
-
* 3. Anything else / parse failure → treated as empty list.
|
|
3726
|
+
* One row's record as the flows of a list page see it (plan ruling 15): `covered` — every ref the
|
|
3727
|
+
* row flows' `when` and pre-click checks read is a field of the list DTO, so the list row is
|
|
3728
|
+
* the record; `ready` — the page's one batched read returned this row (`row`); `pending` — that
|
|
3729
|
+
* read has not answered for this id (or the id is not in the page's batch, Known finding 21).
|
|
2907
3730
|
*/
|
|
2908
|
-
interface
|
|
2909
|
-
|
|
2910
|
-
|
|
3731
|
+
interface FlowRowState {
|
|
3732
|
+
readonly status: 'covered' | 'pending' | 'ready';
|
|
3733
|
+
readonly row?: Row;
|
|
2911
3734
|
}
|
|
2912
3735
|
/**
|
|
2913
|
-
*
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
* - Fires on mount and re-fires whenever `record.id` changes — a
|
|
2946
|
-
* single component instance navigating between two records still
|
|
2947
|
-
* produces two entries.
|
|
2948
|
-
* - Dedupes by `(resource, id)`: revisiting the same record bumps its
|
|
2949
|
-
* `visitedAt` and moves it to the front instead of creating a
|
|
2950
|
-
* duplicate.
|
|
2951
|
-
* - FIFO-evicts the oldest entry when the list exceeds `limit`
|
|
2952
|
-
* (default 5).
|
|
2953
|
-
* - Waits for a real record before writing — calling with
|
|
2954
|
-
* `record === undefined | null` (typical loading state) is a no-op.
|
|
2955
|
-
* - SSR-safe: a missing `window` short-circuits before any storage
|
|
2956
|
-
* call, so the hook is safe to import from server components.
|
|
2957
|
-
* - Storage write errors (quota / private mode) are swallowed silently;
|
|
2958
|
-
* the palette continues to function with whatever the last successful
|
|
2959
|
-
* write left behind.
|
|
2960
|
-
*
|
|
2961
|
-
* Companion reader: `getRecentRecords(userId)` is the synchronous
|
|
2962
|
-
* equivalent for the palette's Recent group — the palette re-reads on
|
|
2963
|
-
* every render (cheap; a localStorage read is sub-microsecond).
|
|
2964
|
-
*
|
|
2965
|
-
* Example:
|
|
2966
|
-
* ```tsx
|
|
2967
|
-
* function DocumentShowPage({ params }: { params: { id: string } }) {
|
|
2968
|
-
* const { record } = useFetchRecord('document_document', params.id);
|
|
2969
|
-
* useTrackRecentRecord('document_document', record);
|
|
2970
|
-
* return <ResourceShow record={record} />;
|
|
2971
|
-
* }
|
|
2972
|
-
* ```
|
|
2973
|
-
*/
|
|
2974
|
-
declare function useTrackRecentRecord(resource: string, record: {
|
|
2975
|
-
id?: unknown;
|
|
2976
|
-
[key: string]: unknown;
|
|
2977
|
-
} | null | undefined, opts?: UseTrackRecentRecordOptions): void;
|
|
2978
|
-
/**
|
|
2979
|
-
* Synchronous read of the Recent list for the given user. Safe to call
|
|
2980
|
-
* during render; SSR-safe (returns `[]` when `window` is undefined).
|
|
2981
|
-
*
|
|
2982
|
-
* Typical use: the palette's Recent group calls this on every render
|
|
2983
|
-
* to populate its rows. localStorage reads are sub-microsecond so the
|
|
2984
|
-
* cost is negligible; we don't subscribe to storage events.
|
|
2985
|
-
*/
|
|
2986
|
-
declare function getRecentRecords(userId: string | null | undefined): RecentRecord[];
|
|
3736
|
+
* The per-page batched pre-click read of a list (P4 spec 4.17, I8; plan ruling 15): one per
|
|
3737
|
+
* list page, around its rows. When every ref the page's row flows read in `when` and their
|
|
3738
|
+
* pre-click checks is a field of the list DTO, nothing is read and every row is `covered`;
|
|
3739
|
+
* otherwise the page's ids are read in ONE `many` (the runtime's query key holds the session,
|
|
3740
|
+
* the scope, the resource and the ids) and a row is `pending` until the read made for THIS page's
|
|
3741
|
+
* ids answered for it (Known finding 21: another page's answer never decides a row). A `with`
|
|
3742
|
+
* source is never read here: it loads at the click, or when a row menu opens.
|
|
3743
|
+
*/
|
|
3744
|
+
declare function useFlowRowBatch(resource: string, ids: readonly string[], flows: readonly CompiledFlow[]): {
|
|
3745
|
+
readonly state: (id: string) => FlowRowState;
|
|
3746
|
+
readonly reader: ReactElement | null;
|
|
3747
|
+
};
|
|
3748
|
+
/** @internal The list page's batch, for the row flows below it. */
|
|
3749
|
+
interface FlowRowBatchValue {
|
|
3750
|
+
readonly resource: string;
|
|
3751
|
+
readonly state: (id: string) => FlowRowState;
|
|
3752
|
+
}
|
|
3753
|
+
/** @internal Provided by the list page (`ResourceList`) around its rows. */
|
|
3754
|
+
declare const FlowRowBatchContext: import("react").Context<FlowRowBatchValue | null>;
|
|
3755
|
+
/** What a row (or a record surface without a run) shows for one flow, before any click. */
|
|
3756
|
+
interface FlowRowControl {
|
|
3757
|
+
readonly state: FlowControlState;
|
|
3758
|
+
readonly reason?: string;
|
|
3759
|
+
/** The record the flow runs on: the batch's row when it read one, else the given row. */
|
|
3760
|
+
readonly record?: Row;
|
|
3761
|
+
/**
|
|
3762
|
+
* Why an `absent` control is absent: the flow's gate (no oracle: indistinguishable from a flow
|
|
3763
|
+
* that does not exist) or its own `when` over this record. A page-hosted flow's route answers
|
|
3764
|
+
* the first with not-found and the second with "not available" (P6).
|
|
3765
|
+
*/
|
|
3766
|
+
readonly cause?: 'gate' | 'when';
|
|
3767
|
+
}
|
|
2987
3768
|
/**
|
|
2988
|
-
*
|
|
2989
|
-
*
|
|
2990
|
-
*
|
|
2991
|
-
*
|
|
3769
|
+
* @internal What a flow's control shows on a row, decided without a run and without a request
|
|
3770
|
+
* (4.17, I8): the gate (undecided while permissions load), then the row's batch state (pending
|
|
3771
|
+
* until the page's one read answered), then `when` and the pre-click checks over the row. A
|
|
3772
|
+
* condition reading a `with` name is decided at click, when the run reads it.
|
|
2992
3773
|
*/
|
|
2993
|
-
declare function
|
|
3774
|
+
declare function useFlowRowResolver(resource: string): (name: string, record: Row | undefined) => FlowRowControl;
|
|
2994
3775
|
//#endregion
|
|
2995
3776
|
//#region src/hooks/use-item-actions.d.ts
|
|
2996
3777
|
/**
|
|
@@ -3007,12 +3788,16 @@ interface ResolvedItemAction extends ItemActionPlacement {
|
|
|
3007
3788
|
variant: 'default' | 'destructive';
|
|
3008
3789
|
disabled: boolean;
|
|
3009
3790
|
disabledReason?: string;
|
|
3791
|
+
/**
|
|
3792
|
+
* A flow (P4-C): its control as the row decides it before any click — the flow's gate, the
|
|
3793
|
+
* page's batched read and its pre-click checks (`undecided` and `pending` render busy).
|
|
3794
|
+
*/
|
|
3795
|
+
flow?: FlowRowControl;
|
|
3010
3796
|
}
|
|
3011
3797
|
declare const RENDER_TIME_DATA: ActionDataAccess;
|
|
3012
3798
|
/**
|
|
3013
|
-
* Build a minimal ActionDI for evaluating
|
|
3014
|
-
*
|
|
3015
|
-
* coupling — link/modal kinds never hit the dispatcher.
|
|
3799
|
+
* Build a minimal ActionDI for evaluating a link's `to` and a modal's `props` functions at
|
|
3800
|
+
* render time.
|
|
3016
3801
|
*
|
|
3017
3802
|
* MOVED here from `@burojs/ui-shadcn`'s `action-button.tsx` (Task 6), which
|
|
3018
3803
|
* defined this identically as a package-private function. `useItemActions` and
|
|
@@ -3160,9 +3945,12 @@ type FilterKind = {
|
|
|
3160
3945
|
{
|
|
3161
3946
|
kind: 'enum-values';
|
|
3162
3947
|
values: readonly string[];
|
|
3163
|
-
} |
|
|
3948
|
+
} |
|
|
3949
|
+
/** `by`: the target field the column holds (`meta.by`); options write its values. */
|
|
3950
|
+
{
|
|
3164
3951
|
kind: 'relation';
|
|
3165
3952
|
to: string;
|
|
3953
|
+
by?: string;
|
|
3166
3954
|
};
|
|
3167
3955
|
/**
|
|
3168
3956
|
* One filterable field as surfaced by `filters.available` — the
|
|
@@ -3220,7 +4008,34 @@ interface ResourceListController {
|
|
|
3220
4008
|
*/
|
|
3221
4009
|
def: ResourceDef | undefined;
|
|
3222
4010
|
/**
|
|
3223
|
-
* The
|
|
4011
|
+
* The one list predicate (P5 spec 3.7): field view in any-record reach and `column` rules,
|
|
4012
|
+
* decided with the record probe. `pending` while the permission map loads and a decision
|
|
4013
|
+
* depends on it — the controller then offers no column, sends no read and reports loading.
|
|
4014
|
+
*/
|
|
4015
|
+
access: ListAccess;
|
|
4016
|
+
/**
|
|
4017
|
+
* How many predicates on fields its user may not view the list dropped — from the address and
|
|
4018
|
+
* from applied saved views (P5 spec 3.7). A host shows one notice while it is above zero.
|
|
4019
|
+
*/
|
|
4020
|
+
droppedPredicates: number;
|
|
4021
|
+
/**
|
|
4022
|
+
* The read is forbidden (P5 spec 3.7): an author predicate (`fixedFilters`) or a function
|
|
4023
|
+
* search names a field its user may not view. No request is sent; `rows` is empty and there is
|
|
4024
|
+
* no total.
|
|
4025
|
+
*/
|
|
4026
|
+
isForbidden: boolean;
|
|
4027
|
+
/**
|
|
4028
|
+
* A row as view code may read it (P5 spec 3.6.6, plan ruling 9): every field its user may not
|
|
4029
|
+
* view for every row left out, the id kept; one object per row. {@link rows} are already
|
|
4030
|
+
* projected this way; `viewRow` projects a row that came from elsewhere (a selected record, a
|
|
4031
|
+
* row of a selection snapshot). Selection, bulk and item-action gates are policy and read the
|
|
4032
|
+
* rows as read, which this hook keeps off its public type.
|
|
4033
|
+
*/
|
|
4034
|
+
viewRow: (row: RowRecord) => RowRecord;
|
|
4035
|
+
/**
|
|
4036
|
+
* The rows on screen, each coerced to {@link RowRecord} and projected by its user's field
|
|
4037
|
+
* access (P5 spec 3.6.6): a field the user may not view for every row is not on a row, so a
|
|
4038
|
+
* list slot, a card grid or a custom body reading `rows` cannot draw it. Empty array
|
|
3224
4039
|
* (never `undefined`) while loading or on a resource with no rows.
|
|
3225
4040
|
* Moved from the `rows` memo, `_list-body.tsx:1310-1316`.
|
|
3226
4041
|
*
|
|
@@ -3442,6 +4257,17 @@ interface ResourceListController {
|
|
|
3442
4257
|
/** Free-text search box value (`_list-body.tsx`'s `search`). */
|
|
3443
4258
|
search: string;
|
|
3444
4259
|
setSearch: (query: string) => void;
|
|
4260
|
+
/**
|
|
4261
|
+
* The search declaration the list composes `search` with: the controller's `search` option
|
|
4262
|
+
* (a placement's own search box), else the resource's `views.list.search`. An export and a
|
|
4263
|
+
* count compose with it, so they describe the rows the list shows.
|
|
4264
|
+
*/
|
|
4265
|
+
searchDecl?: SearchDecl;
|
|
4266
|
+
/**
|
|
4267
|
+
* Whether the list has a search for this user: a declared search set with every field its
|
|
4268
|
+
* user may not view removed and none left is no search (P5 spec 3.7) — a host hides the box.
|
|
4269
|
+
*/
|
|
4270
|
+
searchEnabled: boolean;
|
|
3445
4271
|
/**
|
|
3446
4272
|
* `true` when the search, any pinned filter, the builder group, or
|
|
3447
4273
|
* {@link ResourceListController.providerQuery} is active. Moved from
|
|
@@ -3852,6 +4678,22 @@ interface UseResourceListOptions {
|
|
|
3852
4678
|
* omit to use the declared value untouched.
|
|
3853
4679
|
*/
|
|
3854
4680
|
refetchInterval?: number | false;
|
|
4681
|
+
/**
|
|
4682
|
+
* Where the list keeps its state (P1b+P1c decision 58): by default the URL under the
|
|
4683
|
+
* resource's registry key (`?<resource>.page=2`), so bookmarks keep working; `{ url: prefix }`
|
|
4684
|
+
* namespaces it under another prefix; `'memory'` never writes the URL (a list inside a custom
|
|
4685
|
+
* block view, which must not write the record page's query string).
|
|
4686
|
+
*/
|
|
4687
|
+
state?: ListState;
|
|
4688
|
+
/**
|
|
4689
|
+
* The default columns, in place of the target's `views.list.columns` (a `related-list`
|
|
4690
|
+
* placement's `columns`). Column rules still apply.
|
|
4691
|
+
*/
|
|
4692
|
+
columns?: readonly string[];
|
|
4693
|
+
/** The default page size, in place of the target's `views.list.pageSize`. */
|
|
4694
|
+
pageSize?: number;
|
|
4695
|
+
/** The search, in place of the target's `views.list.search` (a placement's own search box). */
|
|
4696
|
+
search?: SearchDecl;
|
|
3855
4697
|
}
|
|
3856
4698
|
/**
|
|
3857
4699
|
* Data-connected list controller for `resource`.
|
|
@@ -3990,6 +4832,433 @@ declare function ResourceListProvider({ value, children }: ResourceListProviderP
|
|
|
3990
4832
|
*/
|
|
3991
4833
|
declare function useResourceListContext(): ResourceListController;
|
|
3992
4834
|
//#endregion
|
|
4835
|
+
//#region src/dispatch/dispatcher-context.d.ts
|
|
4836
|
+
interface DispatcherProviderProps {
|
|
4837
|
+
/** Merged per key over the enclosing dispatcher's effects (over the defaults at the root). */
|
|
4838
|
+
readonly effects?: Partial<DispatcherEffects>;
|
|
4839
|
+
readonly children: ReactNode;
|
|
4840
|
+
}
|
|
4841
|
+
/**
|
|
4842
|
+
* A nested dispatcher scope: `effects` merged per key over the enclosing
|
|
4843
|
+
* dispatcher's. For a subtree that needs a different effect, and for tests that
|
|
4844
|
+
* spy on effects. Must be rendered inside a `BuroProvider`.
|
|
4845
|
+
*/
|
|
4846
|
+
declare function DispatcherProvider({ effects, children }: DispatcherProviderProps): ReactElement;
|
|
4847
|
+
/** The nearest dispatcher. `BuroProvider` always mounts one. */
|
|
4848
|
+
declare function useDispatcher(): Dispatcher;
|
|
4849
|
+
/**
|
|
4850
|
+
* @internal The effects the nearest dispatcher scope resolves to, read at call time: a nested
|
|
4851
|
+
* scope that replaces one effect (a quick entry's `redirect`) passes what it does not handle to
|
|
4852
|
+
* its parent's.
|
|
4853
|
+
*/
|
|
4854
|
+
declare function useDispatcherEffects(): () => DispatcherEffects;
|
|
4855
|
+
//#endregion
|
|
4856
|
+
//#region src/ui/present-block.d.ts
|
|
4857
|
+
/** What a modal action opens (P7 3.16): the block screen's props, in a dialog or a sheet. */
|
|
4858
|
+
interface PresentBlockInput extends BlockScreenProps {
|
|
4859
|
+
readonly host: 'dialog' | 'sheet';
|
|
4860
|
+
/** The activation the block is opened under; the ambient one when omitted. */
|
|
4861
|
+
readonly activation?: Partial<ReturnType<typeof useCurrentUIActivation>>;
|
|
4862
|
+
}
|
|
4863
|
+
/**
|
|
4864
|
+
* @internal Opens a modal action's block in the UI kit's `screens.block` (P7 3.16): the framework's
|
|
4865
|
+
* own opener for the reserved `buro:block` key, which an app's `useUIPresent` refuses. The opener's
|
|
4866
|
+
* dismiss scope becomes the overlay's parent, as for every overlay (P3-30), so closing a quick
|
|
4867
|
+
* sheet asks about a dirty block above it. `{ ok: false }` when nothing could be presented.
|
|
4868
|
+
*/
|
|
4869
|
+
declare function usePresentBlock(): (input: PresentBlockInput) => UIPresentResult;
|
|
4870
|
+
//#endregion
|
|
4871
|
+
//#region src/navigation/resolve-route.d.ts
|
|
4872
|
+
/**
|
|
4873
|
+
* Resolve a `RouteDescriptor` (string or object form) into an app-space URL.
|
|
4874
|
+
*
|
|
4875
|
+
* - string: returned as-is.
|
|
4876
|
+
* - object: the target's canonical href via `hrefFor` (nesting-aware: a
|
|
4877
|
+
* resource behind nav groups lives at its group-prefixed path), plus every
|
|
4878
|
+
* non-id `param` in the query and `filters` encoded in the target list's
|
|
4879
|
+
* own URL format. An unregistered target keeps the literal `/<resource>…`
|
|
4880
|
+
* form, so a descriptor pointing outside the registry still resolves.
|
|
4881
|
+
*
|
|
4882
|
+
* The one resolver every navigation goes through: link actions, the
|
|
4883
|
+
* dispatcher's default `redirect`, the record pages' navigation targets and
|
|
4884
|
+
* the navigation guard's "leave".
|
|
4885
|
+
*/
|
|
4886
|
+
declare function resolveRoute(to: RouteDescriptor$1, registry?: AppRuntime['registry']): string;
|
|
4887
|
+
//#endregion
|
|
4888
|
+
//#region src/navigation/use-page-access.d.ts
|
|
4889
|
+
/**
|
|
4890
|
+
* The decision about a page's `requires` (P7 3.13): `allowed` — the user holds the pair, or the
|
|
4891
|
+
* page asks for none; `pending` — the permission map is absent or still loading, so nothing is
|
|
4892
|
+
* decided and nothing may be read; `denied` — the map is decided and the user lacks the pair
|
|
4893
|
+
* (a map that failed to load decides nothing in the user's favour either).
|
|
4894
|
+
*/
|
|
4895
|
+
type PageAccess = 'allowed' | 'pending' | 'denied';
|
|
4896
|
+
/**
|
|
4897
|
+
* {@link usePageAccess} over a permission map. A page without `requires` is `allowed` whatever the
|
|
4898
|
+
* map says. Fail closed: no map, or a map still loading, is `pending`.
|
|
4899
|
+
*/
|
|
4900
|
+
declare function pageAccessFor(page: {
|
|
4901
|
+
readonly requires?: PageRequires | undefined;
|
|
4902
|
+
}, permissions: PermissionMap | undefined): PageAccess;
|
|
4903
|
+
/**
|
|
4904
|
+
* Whether the current user may open `page` (P7 3.13). Every entry to a page (the sidebar, the
|
|
4905
|
+
* palette, the group index), the route itself and a flow hosted on the page ask this one question,
|
|
4906
|
+
* so a page the user cannot open has no entry and its route is the framework not-found.
|
|
4907
|
+
*/
|
|
4908
|
+
declare function usePageAccess(page: {
|
|
4909
|
+
readonly requires?: PageRequires | undefined;
|
|
4910
|
+
}): PageAccess;
|
|
4911
|
+
//#endregion
|
|
4912
|
+
//#region src/flows/page-flow-gate.d.ts
|
|
4913
|
+
/**
|
|
4914
|
+
* A flow with no record (an app flow, or a resource-level flow) as a page asks about it (P7
|
|
4915
|
+
* 3.15): the flow compiled, and its gate (`resolveFlowGate`, P4 4.17) decided before anything is
|
|
4916
|
+
* read — `undecided` while the permission map loads, `absent` for a flow that is not offered.
|
|
4917
|
+
* `compiled` is `null` for a flow the application does not declare (fail closed: `absent`).
|
|
4918
|
+
*/
|
|
4919
|
+
interface PageFlowGate {
|
|
4920
|
+
readonly answer: FlowGateAnswer;
|
|
4921
|
+
readonly compiled: CompiledFlow | null;
|
|
4922
|
+
}
|
|
4923
|
+
/**
|
|
4924
|
+
* The gate of a record-free flow. The same `resolveFlowGate` the app-action palette and the list
|
|
4925
|
+
* toolbar run, so a page offers a flow exactly where they do.
|
|
4926
|
+
*/
|
|
4927
|
+
declare function usePageFlowGate(target: FlowTarget): PageFlowGate;
|
|
4928
|
+
//#endregion
|
|
4929
|
+
//#region src/flows/page-host.d.ts
|
|
4930
|
+
/** The page a flow's `host: { page }` names, when it names one (P7 3.15). */
|
|
4931
|
+
declare function hostPageRef(host: unknown): EntityRef | undefined;
|
|
4932
|
+
/** A flow's host page: where its buttons link, and whether the user may open it. */
|
|
4933
|
+
interface HostPage {
|
|
4934
|
+
/** The page's own path (the flow's buttons are guarded links to it). */
|
|
4935
|
+
readonly href: string;
|
|
4936
|
+
readonly access: PageAccess;
|
|
4937
|
+
}
|
|
4938
|
+
/**
|
|
4939
|
+
* The host page of a flow (P7 3.15), or `undefined` for a flow that is not hosted on one. A page
|
|
4940
|
+
* no layer declares is `denied` (fail closed): the flow's buttons are absent rather than links to
|
|
4941
|
+
* a not-found page. So is a page its own `visible`, or any group on its chain, hides: the route
|
|
4942
|
+
* renders not-found for it (`PageHost`), so the link would land there.
|
|
4943
|
+
*/
|
|
4944
|
+
declare function hostPageFor(registry: RegistryReader, host: unknown, permissions: Parameters<typeof pageAccessFor>[1], ctx: AppContext): HostPage | undefined;
|
|
4945
|
+
/** {@link hostPageFor} for a component: the registry and the permission map from the context. */
|
|
4946
|
+
declare function useHostPage(host: unknown): HostPage | undefined;
|
|
4947
|
+
/**
|
|
4948
|
+
* A flow control's state conjoined with its host page's access (P7 3.15): a page the user cannot
|
|
4949
|
+
* open leaves no button (`absent`), an undecided one draws nothing yet (`undecided`).
|
|
4950
|
+
*/
|
|
4951
|
+
declare function conjoinHostPage(state: FlowControlState, hostPage: HostPage | undefined): FlowControlState;
|
|
4952
|
+
//#endregion
|
|
4953
|
+
//#region src/navigation/use-route-navigate.d.ts
|
|
4954
|
+
interface RouteNavigateOptions {
|
|
4955
|
+
/** Navigate without adding a history entry. */
|
|
4956
|
+
readonly replace?: boolean;
|
|
4957
|
+
}
|
|
4958
|
+
type RouteNavigate = (to: RouteDescriptor$1, options?: RouteNavigateOptions) => void;
|
|
4959
|
+
/**
|
|
4960
|
+
* The framework's one navigation seam. Resolves a `RouteDescriptor` against the
|
|
4961
|
+
* app registry and asks the navigation guard's gate (P1b+P1c decision 30):
|
|
4962
|
+
* unblocked, or to the exact current URL, it navigates at once; with unsaved
|
|
4963
|
+
* changes it holds the navigation for the guard's prompt. Outside a
|
|
4964
|
+
* `NavigationGuardProvider` it navigates directly. Either way the navigation
|
|
4965
|
+
* is the mounted `RouterAdapter`'s `push` (`replace` when asked), or a document
|
|
4966
|
+
* navigation without one.
|
|
4967
|
+
*/
|
|
4968
|
+
declare function useRouteNavigate(): RouteNavigate;
|
|
4969
|
+
//#endregion
|
|
4970
|
+
//#region src/navigation/navigation-guard.d.ts
|
|
4971
|
+
/**
|
|
4972
|
+
* Marks an anchor a quick opener owns (a relation display, a related-list row). The attribute
|
|
4973
|
+
* alone changes nothing: the guard leaves a click to its opener only when the opener has also
|
|
4974
|
+
* claimed the element (`quickAnchorRef`, internal), so an app's own `<a data-buro-quick>` is
|
|
4975
|
+
* guarded like any link. A claimed anchor whose click the opener does not take (no
|
|
4976
|
+
* `preventDefault`) is held by the guard after all, at the bubble phase.
|
|
4977
|
+
*/
|
|
4978
|
+
declare const QUICK_ANCHOR_ATTRIBUTE = "data-buro-quick";
|
|
4979
|
+
/**
|
|
4980
|
+
* @internal The ref a framework quick opener puts on its anchor (with `QUICK_ANCHOR_ATTRIBUTE`):
|
|
4981
|
+
* its click goes to the opener, which opens an overlay or navigates through the guarded gate.
|
|
4982
|
+
*/
|
|
4983
|
+
declare function quickAnchorRef(element: Element | null): void;
|
|
4984
|
+
interface NavigationGuardText {
|
|
4985
|
+
readonly title: string;
|
|
4986
|
+
readonly body: string;
|
|
4987
|
+
readonly stay: string;
|
|
4988
|
+
readonly leave: string;
|
|
4989
|
+
/** Leave's label when the prompt holds a dismissal (`reason: 'dismiss'`). */
|
|
4990
|
+
readonly discard: string;
|
|
4991
|
+
}
|
|
4992
|
+
/** The guard's strings: `navGuard.*` in the framework bundles, English literals without one. */
|
|
4993
|
+
declare function useNavigationGuardText(): NavigationGuardText;
|
|
4994
|
+
/**
|
|
4995
|
+
* What the guard is holding, for the registered dialog to answer: a navigation (`href` is
|
|
4996
|
+
* the app-space destination the user tried to reach) or the dismissal of an overlay holding
|
|
4997
|
+
* a dirty form (`href` is `null`). Narrow on `reason`.
|
|
4998
|
+
*/
|
|
4999
|
+
type NavigationGuardPrompt = {
|
|
5000
|
+
/**
|
|
5001
|
+
* The labels of the active blockers that carry one (P6 3.12): an inline flow whose node is not
|
|
5002
|
+
* on screen but holds unsaved input. The dialog says so after its text.
|
|
5003
|
+
*/
|
|
5004
|
+
readonly labels: readonly string[];
|
|
5005
|
+
} & ({
|
|
5006
|
+
readonly reason: 'navigation';
|
|
5007
|
+
/** App-space destination the user tried to reach. */
|
|
5008
|
+
readonly href: string;
|
|
5009
|
+
/** Leave without saving: performs the deferred navigation. */
|
|
5010
|
+
leave(): void;
|
|
5011
|
+
/** Stay: drops the pending navigation. */
|
|
5012
|
+
stay(): void;
|
|
5013
|
+
} | {
|
|
5014
|
+
readonly reason: 'dismiss';
|
|
5015
|
+
readonly href: null;
|
|
5016
|
+
/** Discard: releases the overlay's forms and closes it with every overlay above it. */
|
|
5017
|
+
leave(): void;
|
|
5018
|
+
/** Stay: keeps every overlay open and gives focus back. */
|
|
5019
|
+
stay(): void;
|
|
5020
|
+
});
|
|
5021
|
+
/**
|
|
5022
|
+
* @internal Holds every route change while `active` (P4 plan ruling 7): a flow's pending lock
|
|
5023
|
+
* spans the write, so a framework navigation or an in-app anchor click is dropped without a
|
|
5024
|
+
* prompt (a development `console.info` names the hold) and `beforeunload` is armed. Registered
|
|
5025
|
+
* in an effect, so a React StrictMode remount registers it again (Known finding 20).
|
|
5026
|
+
*/
|
|
5027
|
+
declare function useNavigationHold(active: boolean): void;
|
|
5028
|
+
/** What `useNavigationBlocker` takes besides `active`. */
|
|
5029
|
+
interface NavigationBlockerOptions {
|
|
5030
|
+
/**
|
|
5031
|
+
* Names what holds the unsaved input when its node is not on screen: the guard's dialog adds
|
|
5032
|
+
* `navigation.unsavedAction` and the label (P6 3.12).
|
|
5033
|
+
*/
|
|
5034
|
+
readonly label?: string;
|
|
5035
|
+
}
|
|
5036
|
+
/** What `useNavigationBlocker` returns. */
|
|
5037
|
+
interface NavigationBlockerHandle {
|
|
5038
|
+
/** Unregister now, synchronously; the blocker registers again the next time `active` turns true. */
|
|
5039
|
+
release(): void;
|
|
5040
|
+
}
|
|
5041
|
+
/**
|
|
5042
|
+
* Arm the guard while the calling component holds unsaved changes (a dirty
|
|
5043
|
+
* form). A no-op outside a `BuroProvider`. `release()` disarms it at once — a
|
|
5044
|
+
* successful submit calls it before the navigation that follows, which must
|
|
5045
|
+
* not wait for a render to unregister the blocker.
|
|
5046
|
+
*/
|
|
5047
|
+
declare function useNavigationBlocker(active: boolean, opts?: NavigationBlockerOptions): NavigationBlockerHandle;
|
|
5048
|
+
/**
|
|
5049
|
+
* Register the calling component as the guard's leave dialog for as long as
|
|
5050
|
+
* it is mounted, and return the navigation being held — to the CURRENT dialog
|
|
5051
|
+
* only: the most recently registered one still mounted. Every other
|
|
5052
|
+
* registrant gets `null`, so two dialogs (`<AppLayout>`'s and an explicit
|
|
5053
|
+
* `<NavigationGuardDialog>`, say) never stack; unmounting the current one hands
|
|
5054
|
+
* the prompt back to the previous registrant. With no dialog registered the
|
|
5055
|
+
* guard asks through `window.confirm`.
|
|
5056
|
+
*/
|
|
5057
|
+
declare function useRegisterNavigationGuardDialog(): NavigationGuardPrompt | null;
|
|
5058
|
+
//#endregion
|
|
5059
|
+
//#region src/navigation/dismiss-scope.d.ts
|
|
5060
|
+
/**
|
|
5061
|
+
* One overlay's dismiss scope: a presentation instance, a flow's host, the export
|
|
5062
|
+
* dialog, or an app dialog under `useDismissGuard`. Scopes form a tree (P3-30): a dialog
|
|
5063
|
+
* rendered inside an overlay is a child of the enclosing scope, and an overlay presented
|
|
5064
|
+
* from inside another is a child of the scope it was presented from. A scope is dirty while
|
|
5065
|
+
* any navigation blocker in it or in a descendant is active, and locked while any form in it
|
|
5066
|
+
* or in a descendant submits.
|
|
5067
|
+
*/
|
|
5068
|
+
interface DismissScopeValue {
|
|
5069
|
+
readonly id: string;
|
|
5070
|
+
/**
|
|
5071
|
+
* Ask before leaving: a locked scope ignores the request, a clean one calls `onLeave` at
|
|
5072
|
+
* once, a dirty one holds it for the guard's prompt (Leave calls it, Stay drops it).
|
|
5073
|
+
*/
|
|
5074
|
+
request(onLeave: () => void): void;
|
|
5075
|
+
/** True while a form in this scope or a descendant scope submits. */
|
|
5076
|
+
isLocked(): boolean;
|
|
5077
|
+
}
|
|
5078
|
+
/**
|
|
5079
|
+
* Provide `value` as the dismiss scope of everything below: the forms rendered inside register
|
|
5080
|
+
* their unsaved-changes blockers and their submitting state in it.
|
|
5081
|
+
*/
|
|
5082
|
+
declare function DismissGuardScope({ value, children }: {
|
|
5083
|
+
readonly value: DismissScopeValue;
|
|
5084
|
+
readonly children: ReactNode;
|
|
5085
|
+
}): ReactElement;
|
|
5086
|
+
/** What `useDismissGuard` returns. */
|
|
5087
|
+
interface DismissGuard {
|
|
5088
|
+
/** Close through the guard: asks first when a form in the scope (or below it) is dirty. */
|
|
5089
|
+
dismiss(): void;
|
|
5090
|
+
/** Pass to `<DismissGuardScope value={…}>` around the dialog's content. */
|
|
5091
|
+
readonly scope: DismissScopeValue;
|
|
5092
|
+
}
|
|
5093
|
+
/**
|
|
5094
|
+
* Guard an app's own dialog against losing a dirty form (P3-33): wrap its content in
|
|
5095
|
+
* `<DismissGuardScope value={guard.scope}>` and route its close through `guard.dismiss()`.
|
|
5096
|
+
* Outside a `BuroProvider` `dismiss()` calls `onDismiss` at once.
|
|
5097
|
+
*
|
|
5098
|
+
* ```tsx
|
|
5099
|
+
* const guard = useDismissGuard(() => setOpen(false));
|
|
5100
|
+
* <Dialog open={open} onOpenChange={(next) => { if (!next) guard.dismiss(); }}>
|
|
5101
|
+
* <DismissGuardScope value={guard.scope}><MyForm /></DismissGuardScope>
|
|
5102
|
+
* </Dialog>
|
|
5103
|
+
* ```
|
|
5104
|
+
*/
|
|
5105
|
+
declare function useDismissGuard(onDismiss: () => void): DismissGuard;
|
|
5106
|
+
/**
|
|
5107
|
+
* @internal Lock the enclosing dismiss scope while `pending` is true: a submitting form's
|
|
5108
|
+
* overlay ignores Escape, an outside click and ✕ (P3-34). A no-op outside a scope.
|
|
5109
|
+
*/
|
|
5110
|
+
declare function useDismissPending(pending: boolean): void;
|
|
5111
|
+
//#endregion
|
|
5112
|
+
//#region src/flows/open-implementation.d.ts
|
|
5113
|
+
/**
|
|
5114
|
+
* @internal The app's view of the block a flow's `then.open` names (P4 spec 4.13), by its
|
|
5115
|
+
* `<namespace>:<name>` id, from the catalog mounted in `<BuroProvider blockImplementations>`;
|
|
5116
|
+
* `undefined` when the app implements none (the UI kit falls back to its own).
|
|
5117
|
+
*/
|
|
5118
|
+
declare function useFlowOpenImplementation(id: string): BlockImplementation<unknown> | undefined;
|
|
5119
|
+
//#endregion
|
|
5120
|
+
//#region src/flows/resource-flows.d.ts
|
|
5121
|
+
/** The surfaces a resource-level flow can be drawn on, besides the record ones (P7-31). */
|
|
5122
|
+
type ResourceFlowSurface = 'list';
|
|
5123
|
+
/**
|
|
5124
|
+
* The resource-level flows (`actions.resource`) a resource draws on `surface`, in the order its
|
|
5125
|
+
* toolbar shows them: `order` first (ascending; a flow without one keeps its declaration
|
|
5126
|
+
* position among the unordered), then declaration order. A flow whose `surfaces` resolve to
|
|
5127
|
+
* `false` on `surface` is left out; the rest are `'menu'` or a prominent mode.
|
|
5128
|
+
*/
|
|
5129
|
+
declare function resourceFlowsOn(def: Pick<ResourceDef, 'actions'>, surface: ResourceFlowSurface): readonly ActionFlow[];
|
|
5130
|
+
//#endregion
|
|
5131
|
+
//#region src/flows/present-flow.d.ts
|
|
5132
|
+
interface PresentFlowInput extends FlowStart {
|
|
5133
|
+
readonly host: 'dialog' | 'sheet';
|
|
5134
|
+
readonly label: string;
|
|
5135
|
+
readonly title?: string;
|
|
5136
|
+
}
|
|
5137
|
+
/**
|
|
5138
|
+
* @internal Opens a flow with a form or a review in the UI kit's host (P4 spec 4.15; P4-C review
|
|
5139
|
+
* I1): the host owns the run, so it outlives the control that opened it — a dirty form still
|
|
5140
|
+
* asks before it closes, and a pending write is never cut. The opener's dismiss scope is the
|
|
5141
|
+
* host's parent (closing a quick sheet asks about a dirty flow above it) and the opener's
|
|
5142
|
+
* dispatcher scope runs `then`. Resolves when the host closes, with the last outcome (`halted`
|
|
5143
|
+
* when there was none); `null` when nothing could be presented (one development error names a
|
|
5144
|
+
* missing host or screen).
|
|
5145
|
+
*/
|
|
5146
|
+
declare function usePresentFlow(): (input: PresentFlowInput) => Promise<FlowResult> | null;
|
|
5147
|
+
//#endregion
|
|
5148
|
+
//#region src/quick/use-quick.d.ts
|
|
5149
|
+
/** What a quick open did: opened, opened nothing (with a development error), or waited for access. */
|
|
5150
|
+
type QuickOpen = 'opened' | 'absent' | 'undecided';
|
|
5151
|
+
/**
|
|
5152
|
+
* Opening a record in an overlay from code (spec 3.5). Every call runs the same entry gate as the
|
|
5153
|
+
* framework's openers; `'absent'` and `'undecided'` open nothing, and an undecided call is never
|
|
5154
|
+
* queued.
|
|
5155
|
+
*/
|
|
5156
|
+
interface QuickApi {
|
|
5157
|
+
show(resource: ResourceRefInput, id: string | number): QuickOpen;
|
|
5158
|
+
edit(resource: ResourceRefInput, id: string | number): QuickOpen;
|
|
5159
|
+
/**
|
|
5160
|
+
* Opens `quick.create`; resolves with the created row, or `null` when the gate refused it or
|
|
5161
|
+
* the overlay closed without one. `defaults` are the caller's trusted tier; `input` is user
|
|
5162
|
+
* input (a search text the user typed): it fills the fields the create form holds active and
|
|
5163
|
+
* editable for this user, makes the form dirty, and is dropped for any other field.
|
|
5164
|
+
*/
|
|
5165
|
+
create(resource: ResourceRefInput, opts?: {
|
|
5166
|
+
readonly defaults?: Readonly<Record<string, unknown>>;
|
|
5167
|
+
readonly input?: Readonly<Record<string, unknown>>;
|
|
5168
|
+
}): Promise<QuickSettledRow>;
|
|
5169
|
+
}
|
|
5170
|
+
/**
|
|
5171
|
+
* The one way to open a record in an overlay from code. `show` / `edit` with an id that is no
|
|
5172
|
+
* key (`null`, `''`, `NaN`, an object, a boolean) open nothing and log a development error, as
|
|
5173
|
+
* does a refused entry; `'undecided'` (the permission map is loading) opens nothing and is never
|
|
5174
|
+
* queued. A `show` of the record already on top of the topmost quick sheet opens nothing more.
|
|
5175
|
+
*/
|
|
5176
|
+
declare function useQuick(): QuickApi;
|
|
5177
|
+
/**
|
|
5178
|
+
* @internal The framework openers' path to `quick.show` (a relation display, a related-list
|
|
5179
|
+
* row): the gate with the opener's row, then — inside a quick sheet, a push through the sheet's
|
|
5180
|
+
* scope (it asks when the sheet holds a dirty form); inside a quick dialog, the dialog closes
|
|
5181
|
+
* (through its scope) and the target opens as a new overlay beside it; elsewhere a new overlay
|
|
5182
|
+
* whose parent is the enclosing scope.
|
|
5183
|
+
*/
|
|
5184
|
+
declare function useQuickOpener(): (target: string, id: string, opts?: {
|
|
5185
|
+
readonly row?: unknown;
|
|
5186
|
+
}) => QuickOpen;
|
|
5187
|
+
//#endregion
|
|
5188
|
+
//#region src/quick/quick-entry-context.d.ts
|
|
5189
|
+
/** What a component inside a quick overlay knows about it. */
|
|
5190
|
+
interface QuickEntryValue {
|
|
5191
|
+
readonly stack: QuickStack;
|
|
5192
|
+
readonly host: QuickHost;
|
|
5193
|
+
/** The overlay's presentation id in the runtime. */
|
|
5194
|
+
readonly presentationId: string;
|
|
5195
|
+
/** The overlay's dismiss scope: a push or a close inside it asks through it. */
|
|
5196
|
+
readonly scope: DismissScopeValue;
|
|
5197
|
+
}
|
|
5198
|
+
/** @internal Provided by the UI kit's quick screen around the entry it renders. */
|
|
5199
|
+
declare const QuickEntryContext: Context<QuickEntryValue | null>;
|
|
5200
|
+
/** The quick overlay the caller renders in, or `null` outside one. */
|
|
5201
|
+
declare function useQuickEntry(): QuickEntryValue | null;
|
|
5202
|
+
/**
|
|
5203
|
+
* @internal What the UI kit's quick screen provides as `QuickEntryContext`: its stack, the host it
|
|
5204
|
+
* was presented in (read off its descriptor), its presentation id and the presentation's dismiss
|
|
5205
|
+
* scope. Called by the quick screen, which renders inside its presentation instance.
|
|
5206
|
+
*/
|
|
5207
|
+
declare function useQuickEntryValue(stack: QuickStack): QuickEntryValue;
|
|
5208
|
+
//#endregion
|
|
5209
|
+
//#region src/quick/entry-gate.d.ts
|
|
5210
|
+
/** Which entry an opener asks for: a quick entry's mode, or the peek. */
|
|
5211
|
+
type EntryKind = 'show' | 'edit' | 'create' | 'peek';
|
|
5212
|
+
/**
|
|
5213
|
+
* The entry gate's answer (spec 4.4). `open` names the host and the resolved target (a resource
|
|
5214
|
+
* delegating its show through `routesTo.show` opens the delegate's entry). `undecided` while the
|
|
5215
|
+
* user's permission map loads: the opener renders plain text and sends nothing. `absent`, `hidden`
|
|
5216
|
+
* and `disabled` open nothing, and say why.
|
|
5217
|
+
*/
|
|
5218
|
+
type EntryAnswer = {
|
|
5219
|
+
readonly state: 'open';
|
|
5220
|
+
readonly host: UIPresentHost;
|
|
5221
|
+
readonly target: string;
|
|
5222
|
+
} | {
|
|
5223
|
+
readonly state: 'undecided';
|
|
5224
|
+
} | {
|
|
5225
|
+
readonly state: 'absent' | 'hidden' | 'disabled';
|
|
5226
|
+
readonly why: string;
|
|
5227
|
+
};
|
|
5228
|
+
/**
|
|
5229
|
+
* @internal The one entry gate every opener asks before any request (spec 4.4, 4.14):
|
|
5230
|
+
*
|
|
5231
|
+
* 1. static — the target resolves (following `routesTo.show` for `show` and `peek`),
|
|
5232
|
+
* `recordEntries` names the entry, and its host and screen are wired in
|
|
5233
|
+
* `presentationHosts`; otherwise `absent` (one development error per missing member);
|
|
5234
|
+
* 2. decided — `undecided` while the permission map has `status: 'loading'`. No map is
|
|
5235
|
+
* decided, and a map in `error` is decided by the rules (a `can()` against it fails closed);
|
|
5236
|
+
* 3. dynamic — `resolveAvailability` of the entry's operation (`show` for the peek) with the
|
|
5237
|
+
* opener's row when it holds one.
|
|
5238
|
+
*/
|
|
5239
|
+
declare function useEntryGate(): (target: string, entry: EntryKind, row?: unknown) => EntryAnswer;
|
|
5240
|
+
//#endregion
|
|
5241
|
+
//#region src/notifications/notification-sink.d.ts
|
|
5242
|
+
interface NotificationSinkMessage {
|
|
5243
|
+
/** `info` is a plain notice that dismisses itself, never a progress indicator. */
|
|
5244
|
+
readonly type: 'success' | 'error' | 'info';
|
|
5245
|
+
readonly message: string;
|
|
5246
|
+
readonly description?: string;
|
|
5247
|
+
}
|
|
5248
|
+
/** Where the dispatcher's default `notify` delivers — a UI kit's toaster. */
|
|
5249
|
+
interface NotificationSink {
|
|
5250
|
+
open(notification: NotificationSinkMessage): void;
|
|
5251
|
+
}
|
|
5252
|
+
/**
|
|
5253
|
+
* Register `sink` for as long as the calling component is mounted. Outside a
|
|
5254
|
+
* `BuroProvider` it registers nothing and throws nothing, so a toaster mounted
|
|
5255
|
+
* at an app root keeps working standalone.
|
|
5256
|
+
*
|
|
5257
|
+
* `sink` must be stable (memoised, e.g. with `useMemo`): it is an effect
|
|
5258
|
+
* dependency, so an inline object re-registers on every render.
|
|
5259
|
+
*/
|
|
5260
|
+
declare function useRegisterNotificationSink(sink: NotificationSink | null): void;
|
|
5261
|
+
//#endregion
|
|
3993
5262
|
//#region src/merge-components.d.ts
|
|
3994
5263
|
/**
|
|
3995
5264
|
* Shallow merge of components objects. Overrides keys win; both inputs unchanged.
|
|
@@ -4000,7 +5269,7 @@ declare function mergeComponents<TBase extends Record<string, unknown>, TOver ex
|
|
|
4000
5269
|
/** A resource's list/show/edit/create route. */
|
|
4001
5270
|
interface ResourceRouteDescriptor {
|
|
4002
5271
|
resource: string;
|
|
4003
|
-
action: 'list' | 'show' | 'edit' | 'create';
|
|
5272
|
+
action: 'list' | 'show' | 'edit' | 'create' | 'flow';
|
|
4004
5273
|
path: string;
|
|
4005
5274
|
}
|
|
4006
5275
|
/** A custom (non-resource) page's single route. */
|
|
@@ -4041,6 +5310,44 @@ declare const en: {
|
|
|
4041
5310
|
readonly validation: {
|
|
4042
5311
|
readonly requiredHint: "(required)";
|
|
4043
5312
|
readonly required: "This field is required";
|
|
5313
|
+
readonly string: {
|
|
5314
|
+
readonly minLength: "Too short";
|
|
5315
|
+
readonly maxLength: "Too long";
|
|
5316
|
+
readonly pattern: "Invalid format";
|
|
5317
|
+
};
|
|
5318
|
+
readonly constraint: {
|
|
5319
|
+
readonly invalid: "Invalid value";
|
|
5320
|
+
};
|
|
5321
|
+
readonly number: {
|
|
5322
|
+
readonly minimum: "Value is too small";
|
|
5323
|
+
readonly maximum: "Value is too large";
|
|
5324
|
+
readonly exclusiveMinimum: "Value is too small";
|
|
5325
|
+
readonly exclusiveMaximum: "Value is too large";
|
|
5326
|
+
readonly multipleOf: "Value is not an allowed step";
|
|
5327
|
+
};
|
|
5328
|
+
readonly array: {
|
|
5329
|
+
readonly minItems: "Too few items";
|
|
5330
|
+
readonly maxItems: "Too many items";
|
|
5331
|
+
readonly uniqueItems: "Items must be unique";
|
|
5332
|
+
};
|
|
5333
|
+
readonly validator: {
|
|
5334
|
+
readonly invalid: "Invalid value";
|
|
5335
|
+
readonly exception: "Validation failed";
|
|
5336
|
+
};
|
|
5337
|
+
readonly schema: {
|
|
5338
|
+
readonly invalid: "Invalid value";
|
|
5339
|
+
readonly exception: "Validation failed";
|
|
5340
|
+
};
|
|
5341
|
+
readonly resource: {
|
|
5342
|
+
readonly invalid: "Invalid value";
|
|
5343
|
+
};
|
|
5344
|
+
readonly type: {
|
|
5345
|
+
readonly string: "Must be text";
|
|
5346
|
+
readonly number: "Must be a number";
|
|
5347
|
+
readonly boolean: "Must be yes or no";
|
|
5348
|
+
readonly array: "Must be a list";
|
|
5349
|
+
readonly object: "Must be an object";
|
|
5350
|
+
};
|
|
4044
5351
|
};
|
|
4045
5352
|
readonly actions: {
|
|
4046
5353
|
readonly close: "Close";
|
|
@@ -4069,7 +5376,10 @@ declare const en: {
|
|
|
4069
5376
|
};
|
|
4070
5377
|
readonly confirm: {
|
|
4071
5378
|
readonly delete: "Are you sure you want to delete?";
|
|
4072
|
-
readonly
|
|
5379
|
+
readonly deleteMany_one: "Are you sure you want to delete {{count}} record?";
|
|
5380
|
+
readonly deleteMany_few: "Are you sure you want to delete {{count}} records?";
|
|
5381
|
+
readonly deleteMany_many: "Are you sure you want to delete {{count}} records?";
|
|
5382
|
+
readonly deleteMany_other: "Are you sure you want to delete {{count}} records?";
|
|
4073
5383
|
readonly discardChanges: "Discard unsaved changes?";
|
|
4074
5384
|
readonly ok: "OK";
|
|
4075
5385
|
readonly confirm: "Confirm";
|
|
@@ -4079,22 +5389,24 @@ declare const en: {
|
|
|
4079
5389
|
readonly proceed: "Continue anyway";
|
|
4080
5390
|
readonly back: "Go back";
|
|
4081
5391
|
readonly blocked: "Cannot continue";
|
|
4082
|
-
readonly
|
|
5392
|
+
readonly couldNotVerify: "Could not verify \"{{checkId}}\"";
|
|
5393
|
+
readonly notVerified: "Check \"{{checkId}}\" failed to run";
|
|
4083
5394
|
readonly parseError: "Check \"{{checkId}}\" has an invalid condition: {{detail}}";
|
|
4084
5395
|
};
|
|
4085
5396
|
readonly table: {
|
|
4086
|
-
readonly
|
|
5397
|
+
readonly selectedCount_one: "{{count}} selected";
|
|
5398
|
+
readonly selectedCount_few: "{{count}} selected";
|
|
5399
|
+
readonly selectedCount_many: "{{count}} selected";
|
|
5400
|
+
readonly selectedCount_other: "{{count}} selected";
|
|
4087
5401
|
readonly empty: "No records";
|
|
4088
5402
|
readonly loading: "Loading…";
|
|
4089
|
-
readonly
|
|
5403
|
+
readonly rowsSelected_one: "{{count}} selected";
|
|
5404
|
+
readonly rowsSelected_few: "{{count}} selected";
|
|
5405
|
+
readonly rowsSelected_many: "{{count}} selected";
|
|
5406
|
+
readonly rowsSelected_other: "{{count}} selected";
|
|
4090
5407
|
readonly selectAllRows: "Select all rows";
|
|
4091
5408
|
readonly selectRow: "Select row";
|
|
4092
5409
|
};
|
|
4093
|
-
readonly show: {
|
|
4094
|
-
readonly groups: {
|
|
4095
|
-
readonly other: "Other";
|
|
4096
|
-
};
|
|
4097
|
-
};
|
|
4098
5410
|
readonly boolean: {
|
|
4099
5411
|
readonly yes: "Yes";
|
|
4100
5412
|
readonly no: "No";
|
|
@@ -4149,7 +5461,10 @@ declare const en: {
|
|
|
4149
5461
|
readonly clear: "Clear";
|
|
4150
5462
|
readonly reset: "Reset";
|
|
4151
5463
|
readonly title: "Filters";
|
|
4152
|
-
readonly
|
|
5464
|
+
readonly selectedCount_one: "{{count}} selected";
|
|
5465
|
+
readonly selectedCount_few: "{{count}} selected";
|
|
5466
|
+
readonly selectedCount_many: "{{count}} selected";
|
|
5467
|
+
readonly selectedCount_other: "{{count}} selected";
|
|
4153
5468
|
readonly is: "is";
|
|
4154
5469
|
readonly isNot: "is not";
|
|
4155
5470
|
readonly contains: "contains";
|
|
@@ -4169,11 +5484,12 @@ declare const en: {
|
|
|
4169
5484
|
readonly errors: {
|
|
4170
5485
|
readonly required: "Required";
|
|
4171
5486
|
readonly invalid: "Invalid value";
|
|
4172
|
-
readonly tooLong: "No more than {{max}} characters";
|
|
4173
|
-
readonly tooShort: "At least {{min}} characters";
|
|
4174
5487
|
readonly failed: "Validation failed";
|
|
4175
5488
|
readonly validatorFailed: "Could not validate the form. Please try again.";
|
|
4176
5489
|
};
|
|
5490
|
+
readonly access: {
|
|
5491
|
+
readonly restricted: "No access";
|
|
5492
|
+
};
|
|
4177
5493
|
readonly list: {
|
|
4178
5494
|
readonly loadingShort: "Loading…";
|
|
4179
5495
|
readonly notRegistered: "Resource not registered";
|
|
@@ -4183,19 +5499,19 @@ declare const en: {
|
|
|
4183
5499
|
readonly errorDetails: "Details";
|
|
4184
5500
|
readonly emptyTitle: "No {{items}} yet";
|
|
4185
5501
|
readonly emptyBody: "Get started by creating your first {{item}}.";
|
|
5502
|
+
readonly emptyBodyReadOnly: "They will appear here once they are added.";
|
|
4186
5503
|
readonly emptyFilteredTitle: "No matching {{items}}";
|
|
4187
5504
|
readonly emptyFilteredBody: "No {{items}} match the current filter. Try clearing the filter to see everything.";
|
|
4188
5505
|
readonly clearFilter: "Clear filter";
|
|
4189
5506
|
readonly create: "+ Create {{item}}";
|
|
4190
5507
|
readonly templateUnknown: "Unknown";
|
|
4191
5508
|
readonly search: "Search";
|
|
5509
|
+
readonly predicatesDropped: "Some saved filters were not applied";
|
|
5510
|
+
readonly flowsMenu: "More actions";
|
|
4192
5511
|
};
|
|
4193
|
-
readonly
|
|
4194
|
-
readonly
|
|
4195
|
-
|
|
4196
|
-
readonly tabBody: {
|
|
4197
|
-
readonly empty: "Nothing to show here yet.";
|
|
4198
|
-
readonly failed: "This tab failed to load.";
|
|
5512
|
+
readonly timeline: {
|
|
5513
|
+
readonly empty: "No entries";
|
|
5514
|
+
readonly undated: "Undated";
|
|
4199
5515
|
};
|
|
4200
5516
|
readonly breadcrumbs: {
|
|
4201
5517
|
readonly create: "Create";
|
|
@@ -4206,10 +5522,25 @@ declare const en: {
|
|
|
4206
5522
|
readonly resources: "Resources";
|
|
4207
5523
|
readonly main: "Main navigation";
|
|
4208
5524
|
readonly breadcrumb: "Breadcrumb";
|
|
4209
|
-
readonly language: "Language";
|
|
4210
5525
|
readonly toggleSidebar: "Toggle sidebar";
|
|
4211
5526
|
readonly label: "Navigation";
|
|
4212
5527
|
};
|
|
5528
|
+
readonly shell: {
|
|
5529
|
+
readonly refresh: "Refresh";
|
|
5530
|
+
readonly help: "Help";
|
|
5531
|
+
readonly scopeSwitcher: "Switch";
|
|
5532
|
+
readonly scopePlaceholder: "Select…";
|
|
5533
|
+
readonly account: "Account";
|
|
5534
|
+
};
|
|
5535
|
+
readonly theme: {
|
|
5536
|
+
readonly label: "Theme";
|
|
5537
|
+
readonly light: "Light";
|
|
5538
|
+
readonly dark: "Dark";
|
|
5539
|
+
readonly system: "System";
|
|
5540
|
+
};
|
|
5541
|
+
readonly language: {
|
|
5542
|
+
readonly label: "Language";
|
|
5543
|
+
};
|
|
4213
5544
|
readonly pageHeader: {
|
|
4214
5545
|
readonly backTo: "Back to {{label}}";
|
|
4215
5546
|
readonly editTitle: "Edit {{label}}";
|
|
@@ -4221,6 +5552,10 @@ declare const en: {
|
|
|
4221
5552
|
readonly emptyBody: "This page has no registered content.";
|
|
4222
5553
|
readonly notFoundTitle: "Page not found";
|
|
4223
5554
|
readonly notFoundBody: "This route doesn't match any registered page.";
|
|
5555
|
+
readonly recordLoading: "Loading…";
|
|
5556
|
+
readonly recordNotFound: "This record does not exist, or you do not have access to it.";
|
|
5557
|
+
readonly recordSessionExpired: "Your session has expired. Sign in again to continue.";
|
|
5558
|
+
readonly recordError: "The record could not be loaded.";
|
|
4224
5559
|
};
|
|
4225
5560
|
readonly notifications: {
|
|
4226
5561
|
readonly region: "Notifications";
|
|
@@ -4230,6 +5565,13 @@ declare const en: {
|
|
|
4230
5565
|
readonly unsupportedType: "Unsupported type";
|
|
4231
5566
|
readonly unsupportedTypeHint: "The type “{{type}}” is not registered for this resource.";
|
|
4232
5567
|
readonly backToPicker: "Back to picker";
|
|
5568
|
+
/** The built-in type offer of a typed create (P1b+P1c decision 24). */
|
|
5569
|
+
readonly typeOffer: {
|
|
5570
|
+
readonly title: "Choose a type";
|
|
5571
|
+
readonly hint: "The type decides which fields the record has.";
|
|
5572
|
+
readonly empty: "No type can be created here.";
|
|
5573
|
+
readonly change: "Change type";
|
|
5574
|
+
};
|
|
4233
5575
|
};
|
|
4234
5576
|
readonly taskRun: {
|
|
4235
5577
|
readonly idle: "Not started";
|
|
@@ -4253,7 +5595,10 @@ declare const en: {
|
|
|
4253
5595
|
};
|
|
4254
5596
|
readonly toolbar: {
|
|
4255
5597
|
readonly clearAll: "Clear all";
|
|
4256
|
-
readonly
|
|
5598
|
+
readonly clearAllAria_one: "Clear {{count}} active filter";
|
|
5599
|
+
readonly clearAllAria_few: "Clear {{count}} active filters";
|
|
5600
|
+
readonly clearAllAria_many: "Clear {{count}} active filters";
|
|
5601
|
+
readonly clearAllAria_other: "Clear {{count}} active filters";
|
|
4257
5602
|
readonly addFilter: "Add filter";
|
|
4258
5603
|
readonly filterBy: "Filter by";
|
|
4259
5604
|
readonly columns: "Columns";
|
|
@@ -4290,6 +5635,7 @@ declare const en: {
|
|
|
4290
5635
|
readonly liveOff: "Auto-refresh: off";
|
|
4291
5636
|
};
|
|
4292
5637
|
readonly field: {
|
|
5638
|
+
readonly misconfigured: "This field is misconfigured";
|
|
4293
5639
|
readonly removeFile: "Remove file";
|
|
4294
5640
|
readonly pickFile: "Pick or drop a file";
|
|
4295
5641
|
readonly dropHint: "Click to pick a file or drag-and-drop";
|
|
@@ -4301,12 +5647,13 @@ declare const en: {
|
|
|
4301
5647
|
readonly form: {
|
|
4302
5648
|
readonly systemFields: "System fields (read-only)";
|
|
4303
5649
|
readonly validating: "Validating";
|
|
4304
|
-
readonly wizardProgress: "Wizard progress";
|
|
4305
5650
|
};
|
|
4306
5651
|
readonly relation: {
|
|
4307
5652
|
readonly select: "Select {{name}}…";
|
|
4308
5653
|
readonly failed: "Failed to load options.";
|
|
4309
5654
|
readonly noResults: "No results.";
|
|
5655
|
+
/** A lazy `by` relation whose key names no row, found when it is clicked (P3). */
|
|
5656
|
+
readonly unavailable: "Not available";
|
|
4310
5657
|
};
|
|
4311
5658
|
readonly columnMenu: {
|
|
4312
5659
|
readonly sortSection: "Sort";
|
|
@@ -4327,13 +5674,23 @@ declare const en: {
|
|
|
4327
5674
|
readonly body: "You have unsaved changes on this page. If you leave now, they will be lost.";
|
|
4328
5675
|
readonly stay: "Stay";
|
|
4329
5676
|
readonly leave: "Leave without saving";
|
|
5677
|
+
readonly discard: "Discard changes";
|
|
5678
|
+
};
|
|
5679
|
+
readonly navigation: {
|
|
5680
|
+
readonly unsavedAction: "An action on this screen has unsaved input";
|
|
4330
5681
|
};
|
|
4331
5682
|
readonly relationPicker: {
|
|
4332
5683
|
readonly viewAll: "Open list";
|
|
4333
5684
|
readonly clear: "Clear";
|
|
4334
5685
|
readonly advancedSearch: "Advanced search";
|
|
4335
5686
|
readonly title: "Select: {{name}}";
|
|
4336
|
-
readonly
|
|
5687
|
+
readonly view: "View";
|
|
5688
|
+
readonly create: "+ Create";
|
|
5689
|
+
readonly createdNotFitting: "The record was created but does not fit this field";
|
|
5690
|
+
readonly createdNotSelected: "The record was created but could not be selected";
|
|
5691
|
+
readonly chooseFirst: "Choose {{label}} first";
|
|
5692
|
+
readonly cannotSearchBy: "You cannot search by {{label}}";
|
|
5693
|
+
readonly notMatching: "Does not match the current filter";
|
|
4337
5694
|
readonly select: "Select";
|
|
4338
5695
|
readonly prev: "Prev";
|
|
4339
5696
|
readonly next: "Next";
|
|
@@ -4344,10 +5701,20 @@ declare const en: {
|
|
|
4344
5701
|
readonly restorePrompt: "Restore?";
|
|
4345
5702
|
readonly restore: "Restore";
|
|
4346
5703
|
readonly discard: "Discard";
|
|
5704
|
+
readonly recordChanged: "Record changed since your draft";
|
|
4347
5705
|
readonly timeAgoMoment: "a moment ago";
|
|
4348
|
-
readonly
|
|
4349
|
-
readonly
|
|
4350
|
-
readonly
|
|
5706
|
+
readonly timeAgoMinutes_one: "{{count}} minute ago";
|
|
5707
|
+
readonly timeAgoMinutes_few: "{{count}} minutes ago";
|
|
5708
|
+
readonly timeAgoMinutes_many: "{{count}} minutes ago";
|
|
5709
|
+
readonly timeAgoMinutes_other: "{{count}} minutes ago";
|
|
5710
|
+
readonly timeAgoHours_one: "{{count}} hour ago";
|
|
5711
|
+
readonly timeAgoHours_few: "{{count}} hours ago";
|
|
5712
|
+
readonly timeAgoHours_many: "{{count}} hours ago";
|
|
5713
|
+
readonly timeAgoHours_other: "{{count}} hours ago";
|
|
5714
|
+
readonly timeAgoDays_one: "{{count}} day ago";
|
|
5715
|
+
readonly timeAgoDays_few: "{{count}} days ago";
|
|
5716
|
+
readonly timeAgoDays_many: "{{count}} days ago";
|
|
5717
|
+
readonly timeAgoDays_other: "{{count}} days ago";
|
|
4351
5718
|
readonly timeAgoRecently: "recently";
|
|
4352
5719
|
};
|
|
4353
5720
|
readonly commandPalette: {
|
|
@@ -4431,10 +5798,16 @@ declare const en: {
|
|
|
4431
5798
|
};
|
|
4432
5799
|
};
|
|
4433
5800
|
readonly dialog: {
|
|
4434
|
-
readonly
|
|
5801
|
+
readonly titleFilter_one: "Export {{count}} row by current filter";
|
|
5802
|
+
readonly titleFilter_few: "Export {{count}} rows by current filter";
|
|
5803
|
+
readonly titleFilter_many: "Export {{count}} rows by current filter";
|
|
5804
|
+
readonly titleFilter_other: "Export {{count}} rows by current filter";
|
|
4435
5805
|
/** `estimatedCount` is optional on `ExportDialogProps` — shown when a filter-scope export has no known row estimate. */
|
|
4436
5806
|
readonly titleFilterUnknownCount: "Export rows by current filter";
|
|
4437
|
-
readonly
|
|
5807
|
+
readonly titleSelected_one: "Export {{count}} selected row";
|
|
5808
|
+
readonly titleSelected_few: "Export {{count}} selected rows";
|
|
5809
|
+
readonly titleSelected_many: "Export {{count}} selected rows";
|
|
5810
|
+
readonly titleSelected_other: "Export {{count}} selected rows";
|
|
4438
5811
|
/** Defensive fallback: Task 8 gates the trigger on `available` before opening, so this is only reachable from a direct/programmatic mount. */
|
|
4439
5812
|
readonly unavailable: "Export is not available for this resource.";
|
|
4440
5813
|
/** Shown in place of the format selector while a deferred exporter registration (`ExporterLoader`) is still loading. */
|
|
@@ -4470,6 +5843,94 @@ declare const en: {
|
|
|
4470
5843
|
readonly notify: {
|
|
4471
5844
|
readonly deleted: "Record deleted";
|
|
4472
5845
|
};
|
|
5846
|
+
readonly record: {
|
|
5847
|
+
readonly copyId: "Copy ID";
|
|
5848
|
+
};
|
|
5849
|
+
/** A quick overlay's header (P3): Back to the previous entry, close, open the record's page. */
|
|
5850
|
+
readonly quick: {
|
|
5851
|
+
readonly back: "Back to {{title}}";
|
|
5852
|
+
readonly close: "Close";
|
|
5853
|
+
readonly openAsPage: "Open as page";
|
|
5854
|
+
};
|
|
5855
|
+
/** A peek: the hover preview of a related record (P3). */
|
|
5856
|
+
readonly peek: {
|
|
5857
|
+
readonly failed: "Couldn't load";
|
|
5858
|
+
readonly unavailable: "Not available";
|
|
5859
|
+
};
|
|
5860
|
+
/** A block placement's framework chrome (P1b+P1c section 8.1). */
|
|
5861
|
+
readonly block: {
|
|
5862
|
+
readonly failed: "This section could not be loaded.";
|
|
5863
|
+
readonly sessionExpired: "Your session has expired. Sign in again to continue.";
|
|
5864
|
+
readonly notImplemented: "This section is not available.";
|
|
5865
|
+
};
|
|
5866
|
+
readonly facts: {
|
|
5867
|
+
readonly empty: "No data";
|
|
5868
|
+
};
|
|
5869
|
+
readonly screen: {
|
|
5870
|
+
readonly failed: "This section could not be loaded.";
|
|
5871
|
+
/** A tab's, step's or collapsed panel's badge: errors, not fields. */
|
|
5872
|
+
readonly errorCount_one: "{{count}} error";
|
|
5873
|
+
readonly errorCount_few: "{{count}} errors";
|
|
5874
|
+
readonly errorCount_many: "{{count}} errors";
|
|
5875
|
+
readonly errorCount_other: "{{count}} errors";
|
|
5876
|
+
readonly expand: "Expand";
|
|
5877
|
+
readonly collapse: "Collapse";
|
|
5878
|
+
};
|
|
5879
|
+
/** A create wizard (a `steps` node in create). */
|
|
5880
|
+
readonly steps: {
|
|
5881
|
+
readonly progress: "Progress";
|
|
5882
|
+
readonly next: "Next";
|
|
5883
|
+
readonly back: "Back";
|
|
5884
|
+
readonly current: "Step {{index}} of {{count}}";
|
|
5885
|
+
};
|
|
5886
|
+
/** A flow's host and outcomes (P4 spec 4.22). */
|
|
5887
|
+
readonly flow: {
|
|
5888
|
+
readonly submit: "Submit";
|
|
5889
|
+
readonly back: "Back";
|
|
5890
|
+
readonly next: "Next";
|
|
5891
|
+
readonly checkAgain: "Check again";
|
|
5892
|
+
readonly close: "Close";
|
|
5893
|
+
readonly resend: "Resend";
|
|
5894
|
+
readonly sendAsNew: "Send as new";
|
|
5895
|
+
readonly sendAsNewConfirm: "This may apply the change twice. Send it as a new request?";
|
|
5896
|
+
readonly startOver: "I've checked — start over";
|
|
5897
|
+
readonly forget: "I've checked — forget it";
|
|
5898
|
+
readonly couldNotCheck: "Couldn't check";
|
|
5899
|
+
readonly couldNotReread: "Couldn't re-read the record. Nothing was sent.";
|
|
5900
|
+
readonly unavailable: "Not allowed.";
|
|
5901
|
+
readonly busyElsewhere: "This action is running in another tab.";
|
|
5902
|
+
readonly notAvailable: "This action is not available";
|
|
5903
|
+
readonly noLongerApplies: "This action no longer applies";
|
|
5904
|
+
readonly discard: "Discard";
|
|
5905
|
+
readonly done: "Done";
|
|
5906
|
+
readonly reset: "Reset";
|
|
5907
|
+
readonly rejected: {
|
|
5908
|
+
readonly validation: "The server refused the values. Nothing was saved.";
|
|
5909
|
+
readonly conflict: "Someone else changed this record. Nothing was saved.";
|
|
5910
|
+
readonly forbidden: "You are not allowed to do this. Nothing was saved.";
|
|
5911
|
+
readonly notFound: "This record is no longer available.";
|
|
5912
|
+
readonly precondition: "The record changed. Nothing was sent.";
|
|
5913
|
+
readonly gone: "This record is no longer available.";
|
|
5914
|
+
};
|
|
5915
|
+
readonly failed: "The request could not be sent. Nothing was saved.";
|
|
5916
|
+
readonly unknown: "The request timed out. It may have been applied. Nothing was resent.";
|
|
5917
|
+
readonly unknownUnhandled: "Check the record before trying again.";
|
|
5918
|
+
readonly resultUnavailable: "Done; the result is not available here.";
|
|
5919
|
+
readonly bulkSummary_one: "{{count}} record processed";
|
|
5920
|
+
readonly bulkSummary_few: "{{count}} records processed";
|
|
5921
|
+
readonly bulkSummary_many: "{{count}} records processed";
|
|
5922
|
+
readonly bulkSummary_other: "{{count}} records processed";
|
|
5923
|
+
readonly bulkLimit_one: "Select at most {{count}} record.";
|
|
5924
|
+
readonly bulkLimit_few: "Select at most {{count}} records.";
|
|
5925
|
+
readonly bulkLimit_many: "Select at most {{count}} records.";
|
|
5926
|
+
readonly bulkLimit_other: "Select at most {{count}} records.";
|
|
5927
|
+
readonly bulkUnresolved: "Skipped: an earlier request for it may have been applied.";
|
|
5928
|
+
readonly bulkNotAttempted: "Not attempted.";
|
|
5929
|
+
};
|
|
5930
|
+
/** A flow's review step (P4 spec 4.4). */
|
|
5931
|
+
readonly review: {
|
|
5932
|
+
readonly changed: "changed";
|
|
5933
|
+
};
|
|
4473
5934
|
};
|
|
4474
5935
|
//#endregion
|
|
4475
5936
|
//#region src/locales/ru.d.ts
|
|
@@ -4477,6 +5938,44 @@ declare const ru: {
|
|
|
4477
5938
|
readonly validation: {
|
|
4478
5939
|
readonly requiredHint: "(обязательное)";
|
|
4479
5940
|
readonly required: "Обязательное поле";
|
|
5941
|
+
readonly string: {
|
|
5942
|
+
readonly minLength: "Слишком короткое значение";
|
|
5943
|
+
readonly maxLength: "Слишком длинное значение";
|
|
5944
|
+
readonly pattern: "Неверный формат";
|
|
5945
|
+
};
|
|
5946
|
+
readonly constraint: {
|
|
5947
|
+
readonly invalid: "Неверное значение";
|
|
5948
|
+
};
|
|
5949
|
+
readonly number: {
|
|
5950
|
+
readonly minimum: "Слишком маленькое значение";
|
|
5951
|
+
readonly maximum: "Слишком большое значение";
|
|
5952
|
+
readonly exclusiveMinimum: "Слишком маленькое значение";
|
|
5953
|
+
readonly exclusiveMaximum: "Слишком большое значение";
|
|
5954
|
+
readonly multipleOf: "Недопустимый шаг значения";
|
|
5955
|
+
};
|
|
5956
|
+
readonly array: {
|
|
5957
|
+
readonly minItems: "Слишком мало элементов";
|
|
5958
|
+
readonly maxItems: "Слишком много элементов";
|
|
5959
|
+
readonly uniqueItems: "Элементы должны быть уникальными";
|
|
5960
|
+
};
|
|
5961
|
+
readonly validator: {
|
|
5962
|
+
readonly invalid: "Неверное значение";
|
|
5963
|
+
readonly exception: "Проверка не пройдена";
|
|
5964
|
+
};
|
|
5965
|
+
readonly schema: {
|
|
5966
|
+
readonly invalid: "Неверное значение";
|
|
5967
|
+
readonly exception: "Проверка не пройдена";
|
|
5968
|
+
};
|
|
5969
|
+
readonly resource: {
|
|
5970
|
+
readonly invalid: "Неверное значение";
|
|
5971
|
+
};
|
|
5972
|
+
readonly type: {
|
|
5973
|
+
readonly string: "Должно быть текстом";
|
|
5974
|
+
readonly number: "Должно быть числом";
|
|
5975
|
+
readonly boolean: "Должно быть «да» или «нет»";
|
|
5976
|
+
readonly array: "Должно быть списком";
|
|
5977
|
+
readonly object: "Должно быть объектом";
|
|
5978
|
+
};
|
|
4480
5979
|
};
|
|
4481
5980
|
readonly actions: {
|
|
4482
5981
|
readonly close: "Закрыть";
|
|
@@ -4505,7 +6004,10 @@ declare const ru: {
|
|
|
4505
6004
|
};
|
|
4506
6005
|
readonly confirm: {
|
|
4507
6006
|
readonly delete: "Удалить запись?";
|
|
4508
|
-
readonly
|
|
6007
|
+
readonly deleteMany_one: "Удалить {{count}} запись?";
|
|
6008
|
+
readonly deleteMany_few: "Удалить {{count}} записи?";
|
|
6009
|
+
readonly deleteMany_many: "Удалить {{count}} записей?";
|
|
6010
|
+
readonly deleteMany_other: "Удалить {{count}} записи?";
|
|
4509
6011
|
readonly discardChanges: "Отменить изменения?";
|
|
4510
6012
|
readonly ok: "ОК";
|
|
4511
6013
|
readonly confirm: "Подтвердить";
|
|
@@ -4515,22 +6017,24 @@ declare const ru: {
|
|
|
4515
6017
|
readonly proceed: "Всё равно продолжить";
|
|
4516
6018
|
readonly back: "Вернуться";
|
|
4517
6019
|
readonly blocked: "Продолжить нельзя";
|
|
4518
|
-
readonly
|
|
6020
|
+
readonly couldNotVerify: "Не удалось проверить «{{checkId}}»";
|
|
6021
|
+
readonly notVerified: "Проверка «{{checkId}}» не выполнилась";
|
|
4519
6022
|
readonly parseError: "Правило «{{checkId}}» задано неверно: {{detail}}";
|
|
4520
6023
|
};
|
|
4521
6024
|
readonly table: {
|
|
4522
|
-
readonly
|
|
6025
|
+
readonly selectedCount_one: "Выбрано: {{count}}";
|
|
6026
|
+
readonly selectedCount_few: "Выбрано: {{count}}";
|
|
6027
|
+
readonly selectedCount_many: "Выбрано: {{count}}";
|
|
6028
|
+
readonly selectedCount_other: "Выбрано: {{count}}";
|
|
4523
6029
|
readonly empty: "Нет записей";
|
|
4524
6030
|
readonly loading: "Загрузка…";
|
|
4525
|
-
readonly
|
|
6031
|
+
readonly rowsSelected_one: "Выбрано: {{count}}";
|
|
6032
|
+
readonly rowsSelected_few: "Выбрано: {{count}}";
|
|
6033
|
+
readonly rowsSelected_many: "Выбрано: {{count}}";
|
|
6034
|
+
readonly rowsSelected_other: "Выбрано: {{count}}";
|
|
4526
6035
|
readonly selectAllRows: "Выбрать все строки";
|
|
4527
6036
|
readonly selectRow: "Выбрать строку";
|
|
4528
6037
|
};
|
|
4529
|
-
readonly show: {
|
|
4530
|
-
readonly groups: {
|
|
4531
|
-
readonly other: "Прочее";
|
|
4532
|
-
};
|
|
4533
|
-
};
|
|
4534
6038
|
readonly boolean: {
|
|
4535
6039
|
readonly yes: "Да";
|
|
4536
6040
|
readonly no: "Нет";
|
|
@@ -4585,7 +6089,10 @@ declare const ru: {
|
|
|
4585
6089
|
readonly clear: "Сбросить";
|
|
4586
6090
|
readonly reset: "Сбросить";
|
|
4587
6091
|
readonly title: "Фильтры";
|
|
4588
|
-
readonly
|
|
6092
|
+
readonly selectedCount_one: "Выбрано: {{count}}";
|
|
6093
|
+
readonly selectedCount_few: "Выбрано: {{count}}";
|
|
6094
|
+
readonly selectedCount_many: "Выбрано: {{count}}";
|
|
6095
|
+
readonly selectedCount_other: "Выбрано: {{count}}";
|
|
4589
6096
|
readonly is: "равно";
|
|
4590
6097
|
readonly isNot: "не равно";
|
|
4591
6098
|
readonly contains: "содержит";
|
|
@@ -4605,11 +6112,12 @@ declare const ru: {
|
|
|
4605
6112
|
readonly errors: {
|
|
4606
6113
|
readonly required: "Обязательное поле";
|
|
4607
6114
|
readonly invalid: "Неверное значение";
|
|
4608
|
-
readonly tooLong: "Не более {{max}} символов";
|
|
4609
|
-
readonly tooShort: "Не менее {{min}} символов";
|
|
4610
6115
|
readonly failed: "Проверка не пройдена";
|
|
4611
6116
|
readonly validatorFailed: "Не удалось проверить форму. Попробуйте ещё раз.";
|
|
4612
6117
|
};
|
|
6118
|
+
readonly access: {
|
|
6119
|
+
readonly restricted: "Нет доступа";
|
|
6120
|
+
};
|
|
4613
6121
|
readonly list: {
|
|
4614
6122
|
readonly loadingShort: "Загрузка…";
|
|
4615
6123
|
readonly notRegistered: "Ресурс не зарегистрирован";
|
|
@@ -4619,19 +6127,19 @@ declare const ru: {
|
|
|
4619
6127
|
readonly errorDetails: "Подробности";
|
|
4620
6128
|
readonly emptyTitle: "Пока нет записей";
|
|
4621
6129
|
readonly emptyBody: "Создайте первую запись, чтобы начать.";
|
|
6130
|
+
readonly emptyBodyReadOnly: "Записи появятся здесь, когда их добавят.";
|
|
4622
6131
|
readonly emptyFilteredTitle: "Ничего не найдено";
|
|
4623
6132
|
readonly emptyFilteredBody: "Ни одна запись не соответствует текущему фильтру. Сбросьте фильтр, чтобы увидеть все.";
|
|
4624
6133
|
readonly clearFilter: "Сбросить фильтр";
|
|
4625
6134
|
readonly create: "+ Создать {{item}}";
|
|
4626
6135
|
readonly templateUnknown: "Неизвестный";
|
|
4627
6136
|
readonly search: "Поиск";
|
|
6137
|
+
readonly predicatesDropped: "Некоторые сохранённые фильтры не применены";
|
|
6138
|
+
readonly flowsMenu: "Ещё действия";
|
|
4628
6139
|
};
|
|
4629
|
-
readonly
|
|
4630
|
-
readonly
|
|
4631
|
-
|
|
4632
|
-
readonly tabBody: {
|
|
4633
|
-
readonly empty: "Здесь пока ничего нет.";
|
|
4634
|
-
readonly failed: "Не удалось загрузить вкладку.";
|
|
6140
|
+
readonly timeline: {
|
|
6141
|
+
readonly empty: "Нет записей";
|
|
6142
|
+
readonly undated: "Без даты";
|
|
4635
6143
|
};
|
|
4636
6144
|
readonly breadcrumbs: {
|
|
4637
6145
|
readonly create: "Создание";
|
|
@@ -4642,10 +6150,25 @@ declare const ru: {
|
|
|
4642
6150
|
readonly resources: "Ресурсы";
|
|
4643
6151
|
readonly main: "Основная навигация";
|
|
4644
6152
|
readonly breadcrumb: "Хлебные крошки";
|
|
4645
|
-
readonly language: "Язык";
|
|
4646
6153
|
readonly toggleSidebar: "Свернуть меню";
|
|
4647
6154
|
readonly label: "Навигация";
|
|
4648
6155
|
};
|
|
6156
|
+
readonly shell: {
|
|
6157
|
+
readonly refresh: "Обновить";
|
|
6158
|
+
readonly help: "Справка";
|
|
6159
|
+
readonly scopeSwitcher: "Переключить";
|
|
6160
|
+
readonly scopePlaceholder: "Выберите…";
|
|
6161
|
+
readonly account: "Учётная запись";
|
|
6162
|
+
};
|
|
6163
|
+
readonly theme: {
|
|
6164
|
+
readonly label: "Тема";
|
|
6165
|
+
readonly light: "Светлая";
|
|
6166
|
+
readonly dark: "Тёмная";
|
|
6167
|
+
readonly system: "Системная";
|
|
6168
|
+
};
|
|
6169
|
+
readonly language: {
|
|
6170
|
+
readonly label: "Язык";
|
|
6171
|
+
};
|
|
4649
6172
|
readonly pageHeader: {
|
|
4650
6173
|
readonly backTo: "Назад к списку";
|
|
4651
6174
|
readonly editTitle: "Изменить {{label}}";
|
|
@@ -4657,6 +6180,10 @@ declare const ru: {
|
|
|
4657
6180
|
readonly emptyBody: "Для этой страницы не зарегистрировано содержимое.";
|
|
4658
6181
|
readonly notFoundTitle: "Страница не найдена";
|
|
4659
6182
|
readonly notFoundBody: "Этот адрес не соответствует ни одной зарегистрированной странице.";
|
|
6183
|
+
readonly recordLoading: "Загрузка…";
|
|
6184
|
+
readonly recordNotFound: "Запись не найдена или у вас нет к ней доступа.";
|
|
6185
|
+
readonly recordSessionExpired: "Сеанс истёк. Войдите снова, чтобы продолжить.";
|
|
6186
|
+
readonly recordError: "Не удалось загрузить запись.";
|
|
4660
6187
|
};
|
|
4661
6188
|
readonly notifications: {
|
|
4662
6189
|
readonly region: "Уведомления";
|
|
@@ -4666,6 +6193,12 @@ declare const ru: {
|
|
|
4666
6193
|
readonly unsupportedType: "Неподдерживаемый тип";
|
|
4667
6194
|
readonly unsupportedTypeHint: "Тип «{{type}}» не зарегистрирован для этого ресурса.";
|
|
4668
6195
|
readonly backToPicker: "Назад к выбору типа";
|
|
6196
|
+
readonly typeOffer: {
|
|
6197
|
+
readonly title: "Выберите тип";
|
|
6198
|
+
readonly hint: "От типа зависит, какие поля есть у записи.";
|
|
6199
|
+
readonly empty: "Здесь нельзя создать запись ни одного типа.";
|
|
6200
|
+
readonly change: "Сменить тип";
|
|
6201
|
+
};
|
|
4669
6202
|
};
|
|
4670
6203
|
readonly taskRun: {
|
|
4671
6204
|
readonly idle: "Не запущено";
|
|
@@ -4689,7 +6222,10 @@ declare const ru: {
|
|
|
4689
6222
|
};
|
|
4690
6223
|
readonly toolbar: {
|
|
4691
6224
|
readonly clearAll: "Очистить всё";
|
|
4692
|
-
readonly
|
|
6225
|
+
readonly clearAllAria_one: "Очистить фильтры: {{count}}";
|
|
6226
|
+
readonly clearAllAria_few: "Очистить фильтры: {{count}}";
|
|
6227
|
+
readonly clearAllAria_many: "Очистить фильтры: {{count}}";
|
|
6228
|
+
readonly clearAllAria_other: "Очистить фильтры: {{count}}";
|
|
4693
6229
|
readonly addFilter: "Добавить фильтр";
|
|
4694
6230
|
readonly filterBy: "Фильтровать по";
|
|
4695
6231
|
readonly columns: "Колонки";
|
|
@@ -4726,6 +6262,7 @@ declare const ru: {
|
|
|
4726
6262
|
readonly liveOff: "Авто-обновление: выкл";
|
|
4727
6263
|
};
|
|
4728
6264
|
readonly field: {
|
|
6265
|
+
readonly misconfigured: "Это поле настроено неверно";
|
|
4729
6266
|
readonly removeFile: "Удалить файл";
|
|
4730
6267
|
readonly pickFile: "Выберите файл или перетащите его сюда";
|
|
4731
6268
|
readonly dropHint: "Нажмите, чтобы выбрать файл, или перетащите его сюда";
|
|
@@ -4737,12 +6274,13 @@ declare const ru: {
|
|
|
4737
6274
|
readonly form: {
|
|
4738
6275
|
readonly systemFields: "Системные поля (только чтение)";
|
|
4739
6276
|
readonly validating: "Проверка";
|
|
4740
|
-
readonly wizardProgress: "Ход заполнения";
|
|
4741
6277
|
};
|
|
4742
6278
|
readonly relation: {
|
|
4743
6279
|
readonly select: "Выберите…";
|
|
4744
6280
|
readonly failed: "Не удалось загрузить варианты.";
|
|
4745
6281
|
readonly noResults: "Ничего не найдено.";
|
|
6282
|
+
/** A lazy `by` relation whose key names no row, found when it is clicked (P3). */
|
|
6283
|
+
readonly unavailable: "Недоступно";
|
|
4746
6284
|
};
|
|
4747
6285
|
readonly columnMenu: {
|
|
4748
6286
|
readonly sortSection: "Сортировка";
|
|
@@ -4763,13 +6301,23 @@ declare const ru: {
|
|
|
4763
6301
|
readonly body: "На этой странице есть несохранённые изменения. Если уйти сейчас, они будут потеряны.";
|
|
4764
6302
|
readonly stay: "Остаться";
|
|
4765
6303
|
readonly leave: "Уйти без сохранения";
|
|
6304
|
+
readonly discard: "Отменить изменения";
|
|
6305
|
+
};
|
|
6306
|
+
readonly navigation: {
|
|
6307
|
+
readonly unsavedAction: "В действии на этом экране есть несохранённые данные";
|
|
4766
6308
|
};
|
|
4767
6309
|
readonly relationPicker: {
|
|
4768
6310
|
readonly viewAll: "Открыть список";
|
|
4769
6311
|
readonly clear: "Очистить";
|
|
4770
6312
|
readonly advancedSearch: "Расширенный поиск";
|
|
4771
6313
|
readonly title: "Выбор: {{name}}";
|
|
4772
|
-
readonly
|
|
6314
|
+
readonly view: "Открыть";
|
|
6315
|
+
readonly create: "+ Создать";
|
|
6316
|
+
readonly createdNotFitting: "Запись создана, но не подходит для этого поля";
|
|
6317
|
+
readonly createdNotSelected: "Запись создана, но её не удалось выбрать";
|
|
6318
|
+
readonly chooseFirst: "Сначала выберите {{label}}";
|
|
6319
|
+
readonly cannotSearchBy: "Нельзя искать по {{label}}";
|
|
6320
|
+
readonly notMatching: "Не соответствует текущему фильтру";
|
|
4773
6321
|
readonly select: "Выбрать";
|
|
4774
6322
|
readonly prev: "Назад";
|
|
4775
6323
|
readonly next: "Вперёд";
|
|
@@ -4780,10 +6328,20 @@ declare const ru: {
|
|
|
4780
6328
|
readonly restorePrompt: "Восстановить?";
|
|
4781
6329
|
readonly restore: "Восстановить";
|
|
4782
6330
|
readonly discard: "Отклонить";
|
|
6331
|
+
readonly recordChanged: "Запись изменилась после сохранения черновика";
|
|
4783
6332
|
readonly timeAgoMoment: "только что";
|
|
4784
|
-
readonly
|
|
4785
|
-
readonly
|
|
4786
|
-
readonly
|
|
6333
|
+
readonly timeAgoMinutes_one: "{{count}} минуту назад";
|
|
6334
|
+
readonly timeAgoMinutes_few: "{{count}} минуты назад";
|
|
6335
|
+
readonly timeAgoMinutes_many: "{{count}} минут назад";
|
|
6336
|
+
readonly timeAgoMinutes_other: "{{count}} минуты назад";
|
|
6337
|
+
readonly timeAgoHours_one: "{{count}} час назад";
|
|
6338
|
+
readonly timeAgoHours_few: "{{count}} часа назад";
|
|
6339
|
+
readonly timeAgoHours_many: "{{count}} часов назад";
|
|
6340
|
+
readonly timeAgoHours_other: "{{count}} часа назад";
|
|
6341
|
+
readonly timeAgoDays_one: "{{count}} день назад";
|
|
6342
|
+
readonly timeAgoDays_few: "{{count}} дня назад";
|
|
6343
|
+
readonly timeAgoDays_many: "{{count}} дней назад";
|
|
6344
|
+
readonly timeAgoDays_other: "{{count}} дня назад";
|
|
4787
6345
|
readonly timeAgoRecently: "недавно";
|
|
4788
6346
|
};
|
|
4789
6347
|
readonly commandPalette: {
|
|
@@ -4867,13 +6425,19 @@ declare const ru: {
|
|
|
4867
6425
|
};
|
|
4868
6426
|
};
|
|
4869
6427
|
readonly dialog: {
|
|
4870
|
-
readonly
|
|
4871
|
-
|
|
6428
|
+
readonly titleFilter_one: "Экспорт {{count}} строки по текущему фильтру";
|
|
6429
|
+
readonly titleFilter_few: "Экспорт {{count}} строк по текущему фильтру";
|
|
6430
|
+
readonly titleFilter_many: "Экспорт {{count}} строк по текущему фильтру";
|
|
6431
|
+
readonly titleFilter_other: "Экспорт {{count}} строки по текущему фильтру";
|
|
6432
|
+
/** `estimatedCount` is optional on `ExportDialogProps` — shown when a filter-scope export has no known row estimate. */
|
|
4872
6433
|
readonly titleFilterUnknownCount: "Экспорт строк по текущему фильтру";
|
|
4873
|
-
readonly
|
|
4874
|
-
|
|
6434
|
+
readonly titleSelected_one: "Экспорт {{count}} выбранной строки";
|
|
6435
|
+
readonly titleSelected_few: "Экспорт {{count}} выбранных строк";
|
|
6436
|
+
readonly titleSelected_many: "Экспорт {{count}} выбранных строк";
|
|
6437
|
+
readonly titleSelected_other: "Экспорт {{count}} выбранной строки";
|
|
6438
|
+
/** Defensive fallback: Task 8 gates the trigger on `available` before opening, so this is only reachable from a direct/programmatic mount. */
|
|
4875
6439
|
readonly unavailable: "Экспорт недоступен для этого ресурса.";
|
|
4876
|
-
/**
|
|
6440
|
+
/** Shown in place of the format selector while a deferred exporter registration (`ExporterLoader`) is still loading. */
|
|
4877
6441
|
readonly loading: "Подготовка экспорта…";
|
|
4878
6442
|
readonly format: "Формат";
|
|
4879
6443
|
readonly columns: "Колонки";
|
|
@@ -4892,11 +6456,11 @@ declare const ru: {
|
|
|
4892
6456
|
readonly continue: "Продолжить в фоне";
|
|
4893
6457
|
};
|
|
4894
6458
|
readonly continuesInBackground: "Экспорт продолжается в фоне.";
|
|
4895
|
-
/**
|
|
6459
|
+
/** Toolbar/bulk-bar Export entry points (Task 8). Shared by both — the same action, two scopes. */
|
|
4896
6460
|
readonly button: {
|
|
4897
6461
|
readonly label: "Экспорт";
|
|
4898
6462
|
};
|
|
4899
|
-
/**
|
|
6463
|
+
/** `useExportRunWatcher()` background-completion toasts (Task 8). */
|
|
4900
6464
|
readonly toast: {
|
|
4901
6465
|
readonly succeeded: "Экспорт готов";
|
|
4902
6466
|
readonly download: "Скачать";
|
|
@@ -4906,241 +6470,213 @@ declare const ru: {
|
|
|
4906
6470
|
readonly notify: {
|
|
4907
6471
|
readonly deleted: "Запись удалена";
|
|
4908
6472
|
};
|
|
6473
|
+
readonly record: {
|
|
6474
|
+
readonly copyId: "Скопировать ID";
|
|
6475
|
+
};
|
|
6476
|
+
/** A quick overlay's header (P3): Back to the previous entry, close, open the record's page. */
|
|
6477
|
+
readonly quick: {
|
|
6478
|
+
readonly back: "Назад к «{{title}}»";
|
|
6479
|
+
readonly close: "Закрыть";
|
|
6480
|
+
readonly openAsPage: "Открыть страницей";
|
|
6481
|
+
};
|
|
6482
|
+
readonly peek: {
|
|
6483
|
+
readonly failed: "Не удалось загрузить";
|
|
6484
|
+
readonly unavailable: "Недоступно";
|
|
6485
|
+
};
|
|
6486
|
+
/** A block placement's framework chrome (P1b+P1c section 8.1). */
|
|
6487
|
+
readonly block: {
|
|
6488
|
+
readonly failed: "Не удалось загрузить раздел.";
|
|
6489
|
+
readonly sessionExpired: "Сессия истекла. Войдите снова, чтобы продолжить.";
|
|
6490
|
+
readonly notImplemented: "Этот раздел недоступен.";
|
|
6491
|
+
};
|
|
6492
|
+
readonly facts: {
|
|
6493
|
+
readonly empty: "Нет данных";
|
|
6494
|
+
};
|
|
6495
|
+
readonly screen: {
|
|
6496
|
+
readonly failed: "Не удалось загрузить раздел.";
|
|
6497
|
+
/** A tab's, step's or collapsed panel's badge: errors, not fields. */
|
|
6498
|
+
readonly errorCount_one: "{{count}} ошибка";
|
|
6499
|
+
readonly errorCount_few: "{{count}} ошибки";
|
|
6500
|
+
readonly errorCount_many: "{{count}} ошибок";
|
|
6501
|
+
readonly errorCount_other: "{{count}} ошибки";
|
|
6502
|
+
readonly expand: "Развернуть";
|
|
6503
|
+
readonly collapse: "Свернуть";
|
|
6504
|
+
};
|
|
6505
|
+
/** A create wizard (a `steps` node in create). */
|
|
6506
|
+
readonly steps: {
|
|
6507
|
+
readonly progress: "Ход заполнения";
|
|
6508
|
+
readonly next: "Далее";
|
|
6509
|
+
readonly back: "Назад";
|
|
6510
|
+
readonly current: "Шаг {{index}} из {{count}}";
|
|
6511
|
+
};
|
|
6512
|
+
/** A flow's host and outcomes (P4 spec 4.22). */
|
|
6513
|
+
readonly flow: {
|
|
6514
|
+
readonly submit: "Отправить";
|
|
6515
|
+
readonly back: "Назад";
|
|
6516
|
+
readonly next: "Далее";
|
|
6517
|
+
readonly checkAgain: "Проверить снова";
|
|
6518
|
+
readonly close: "Закрыть";
|
|
6519
|
+
readonly resend: "Отправить повторно";
|
|
6520
|
+
readonly sendAsNew: "Отправить как новый";
|
|
6521
|
+
readonly sendAsNewConfirm: "Изменение может примениться дважды. Отправить как новый запрос?";
|
|
6522
|
+
readonly startOver: "Я проверил — начать заново";
|
|
6523
|
+
readonly forget: "Я проверил — забыть";
|
|
6524
|
+
readonly couldNotCheck: "Не удалось проверить";
|
|
6525
|
+
readonly couldNotReread: "Не удалось перечитать запись. Ничего не отправлено.";
|
|
6526
|
+
readonly unavailable: "Недоступно.";
|
|
6527
|
+
readonly busyElsewhere: "Это действие выполняется в другой вкладке.";
|
|
6528
|
+
readonly notAvailable: "Это действие недоступно";
|
|
6529
|
+
readonly noLongerApplies: "Это действие больше не применимо";
|
|
6530
|
+
readonly discard: "Отменить";
|
|
6531
|
+
readonly done: "Готово";
|
|
6532
|
+
readonly reset: "Сбросить";
|
|
6533
|
+
readonly rejected: {
|
|
6534
|
+
readonly validation: "Сервер отклонил значения. Ничего не сохранено.";
|
|
6535
|
+
readonly conflict: "Запись изменил кто-то другой. Ничего не сохранено.";
|
|
6536
|
+
readonly forbidden: "У вас нет прав на это действие. Ничего не сохранено.";
|
|
6537
|
+
readonly notFound: "Эта запись больше недоступна.";
|
|
6538
|
+
readonly precondition: "Запись изменилась. Ничего не отправлено.";
|
|
6539
|
+
readonly gone: "Эта запись больше недоступна.";
|
|
6540
|
+
};
|
|
6541
|
+
readonly failed: "Не удалось отправить запрос. Ничего не сохранено.";
|
|
6542
|
+
readonly unknown: "Время ожидания истекло. Изменение могло примениться. Повторно ничего не отправлено.";
|
|
6543
|
+
readonly unknownUnhandled: "Проверьте запись, прежде чем пробовать снова.";
|
|
6544
|
+
readonly resultUnavailable: "Готово; результат здесь недоступен.";
|
|
6545
|
+
readonly bulkSummary_one: "Обработана {{count}} запись";
|
|
6546
|
+
readonly bulkSummary_few: "Обработано {{count}} записи";
|
|
6547
|
+
readonly bulkSummary_many: "Обработано {{count}} записей";
|
|
6548
|
+
readonly bulkSummary_other: "Обработано {{count}} записи";
|
|
6549
|
+
readonly bulkLimit_one: "Выберите не больше {{count}} записи.";
|
|
6550
|
+
readonly bulkLimit_few: "Выберите не больше {{count}} записей.";
|
|
6551
|
+
readonly bulkLimit_many: "Выберите не больше {{count}} записей.";
|
|
6552
|
+
readonly bulkLimit_other: "Выберите не больше {{count}} записей.";
|
|
6553
|
+
readonly bulkUnresolved: "Пропущено: прежний запрос мог уже примениться.";
|
|
6554
|
+
readonly bulkNotAttempted: "Не выполнялось.";
|
|
6555
|
+
};
|
|
6556
|
+
/** A flow's review step (P4 spec 4.4). */
|
|
6557
|
+
readonly review: {
|
|
6558
|
+
readonly changed: "изменено";
|
|
6559
|
+
};
|
|
4909
6560
|
};
|
|
4910
6561
|
//#endregion
|
|
4911
|
-
//#region src/forms/
|
|
4912
|
-
/** The live values map a declarative form reads from and writes to. */
|
|
4913
|
-
type FormValues = Record<string, unknown>;
|
|
4914
|
-
/**
|
|
4915
|
-
* A friendly validator return, resolved through `normalizeFieldIssues` at
|
|
4916
|
-
* the boundary. Reused for both per-field validators (`ResourceFieldDefinition.
|
|
4917
|
-
* validators`, from `@burojs/core`) and the form-level `validate` below.
|
|
4918
|
-
*/
|
|
4919
|
-
type FormLevelValidationResult = FieldIssue | readonly FieldIssue[] | null | undefined;
|
|
6562
|
+
//#region src/forms/controller/screen-state.d.ts
|
|
4920
6563
|
/**
|
|
4921
|
-
*
|
|
4922
|
-
*
|
|
4923
|
-
*
|
|
4924
|
-
* the
|
|
4925
|
-
*
|
|
4926
|
-
* controller with no provider wrapper.
|
|
6564
|
+
* Which panels of a screen are open: the `open` input of `planScreen` (P1b+P1c
|
|
6565
|
+
* decision 13), plus `expanded`: the `collapse: 'closed'` panels a user opened.
|
|
6566
|
+
* A host holds no screen, so it cannot list the panels a screen starts
|
|
6567
|
+
* collapsed; the controller adds every `collapse: 'closed'` panel that is not
|
|
6568
|
+
* in `expanded` to `collapsed` before it plans.
|
|
4927
6569
|
*/
|
|
4928
|
-
type
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
readonly
|
|
4933
|
-
|
|
6570
|
+
type ScreenOpenState = NonNullable<PlanScreenInput['open']> & {
|
|
6571
|
+
readonly expanded?: readonly string[];
|
|
6572
|
+
};
|
|
6573
|
+
interface ScreenStateValue {
|
|
6574
|
+
readonly open: ScreenOpenState;
|
|
6575
|
+
openPanel(containerId: string, panelKey: string): void;
|
|
6576
|
+
setCollapsed(containerId: string, collapsed: boolean): void;
|
|
6577
|
+
/** The inline flows this screen instance holds (P6 3.12); released when the screen unmounts. */
|
|
6578
|
+
readonly inline: InlineFlowHolder;
|
|
6579
|
+
}
|
|
6580
|
+
interface ScreenStateProviderProps {
|
|
6581
|
+
/** The uncontrolled start value. */
|
|
6582
|
+
readonly initialOpen?: ScreenOpenState;
|
|
4934
6583
|
/**
|
|
4935
|
-
*
|
|
4936
|
-
*
|
|
4937
|
-
*
|
|
4938
|
-
* `t(message.key, { params })` call can fill in a `{{placeholder}}` in a
|
|
4939
|
-
* registered bundle entry, mirroring `resource-form.tsx`'s
|
|
4940
|
-
* `resolveIssueMessage` and `<CheckConfirmDialog>`'s own `issueText`.
|
|
6584
|
+
* Controlled: when given, the provider holds no state of its own and plans
|
|
6585
|
+
* this value, so a host can drive it after mount (URL tab state reaching
|
|
6586
|
+
* the plan).
|
|
4941
6587
|
*/
|
|
4942
|
-
readonly
|
|
6588
|
+
readonly open?: ScreenOpenState;
|
|
6589
|
+
/** Called by `openPanel` and `setCollapsed`, controlled or not. */
|
|
6590
|
+
readonly onOpenChange?: (next: ScreenOpenState) => void;
|
|
6591
|
+
readonly children: ReactNode;
|
|
4943
6592
|
}
|
|
4944
6593
|
/**
|
|
4945
|
-
*
|
|
4946
|
-
*
|
|
4947
|
-
*
|
|
6594
|
+
* Holds what is open on a screen (tabs, steps, collapsed panels) for the form
|
|
6595
|
+
* controller and the renderer below it. Controlled through `open` /
|
|
6596
|
+
* `onOpenChange`, or uncontrolled from `initialOpen`.
|
|
6597
|
+
*/
|
|
6598
|
+
declare function ScreenStateProvider({ initialOpen, open, onOpenChange, children }: ScreenStateProviderProps): ReactElement;
|
|
6599
|
+
/** The screen state, or `null` outside a provider: the controller then plans without `open`. */
|
|
6600
|
+
declare function useScreenState(): ScreenStateValue | null;
|
|
6601
|
+
//#endregion
|
|
6602
|
+
//#region src/forms/controller/use-form-controller.d.ts
|
|
6603
|
+
/**
|
|
6604
|
+
* The form controller (P1b+P1c section 10.3): one planned screen, its values
|
|
6605
|
+
* with their seed provenance, validation, checks and the payload allow-list.
|
|
6606
|
+
* A record form passes `resource` and `mode`, and its screen is read from the
|
|
6607
|
+
* compiled snapshot, never from a handle; a resource-less form passes
|
|
6608
|
+
* `fields` (and a `body`), and its screen is compiled by `compileFormScreen`.
|
|
4948
6609
|
*/
|
|
4949
|
-
|
|
4950
|
-
|
|
6610
|
+
declare function useFormController<F extends ResourceFieldMap>(options: UseFormControllerFormOptions<F>): FormController;
|
|
6611
|
+
declare function useFormController(options: UseFormControllerRecordOptions): FormController;
|
|
6612
|
+
//#endregion
|
|
6613
|
+
//#region src/forms/validation-message.d.ts
|
|
6614
|
+
/** What {@link resolveValidationMessage} reads besides the issue. */
|
|
6615
|
+
interface ValidationMessageContext {
|
|
6616
|
+
/** A translator that returns the key itself on a miss (`useTranslate`, `useT`). */
|
|
6617
|
+
readonly t: (key: string, options?: {
|
|
6618
|
+
params?: Record<string, unknown>;
|
|
6619
|
+
}) => string;
|
|
6620
|
+
/** `resources.<r>.fields.<f>` (a flow form's: `resources.<r>.actions.<name>.fields.<f>`); absent for a form-level issue. */
|
|
6621
|
+
readonly fieldKey?: string;
|
|
4951
6622
|
}
|
|
4952
6623
|
/**
|
|
4953
|
-
* The
|
|
4954
|
-
*
|
|
4955
|
-
*
|
|
4956
|
-
*
|
|
4957
|
-
*
|
|
6624
|
+
* The one text of a validation issue, resolved at render so a locale switch
|
|
6625
|
+
* reaches it. A lookup hits when `t` returns something other than the key:
|
|
6626
|
+
*
|
|
6627
|
+
* 1. `${fieldKey}.validation.${code}` — the author's per-field override;
|
|
6628
|
+
* 2. `message.key`, when it is not `validation.${code}` (a server or semantic key);
|
|
6629
|
+
* 3. `message.default` — the schema's, validator's or server's own text;
|
|
6630
|
+
* 4. `validation.${code}` — the framework's text for a built-in code;
|
|
6631
|
+
* 5. `errors.failed`.
|
|
4958
6632
|
*
|
|
4959
|
-
*
|
|
4960
|
-
*
|
|
4961
|
-
* `visible` convention, reused as-is); `required`/`disabled` are each
|
|
4962
|
-
* either a static boolean or a predicate `(ctx, values) => boolean`
|
|
4963
|
-
* evaluated the same way — see `packages/react/src/forms/conditional.ts`.
|
|
6633
|
+
* Built-in constraint issues carry no `default`, so step 4 answers them in
|
|
6634
|
+
* every locale; an issue with its own `default` keeps it unless step 1 hits.
|
|
4964
6635
|
*/
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
readonly onChange: (value: unknown) => void;
|
|
4969
|
-
readonly onBlur: () => void;
|
|
4970
|
-
readonly error?: ResolvedIssue;
|
|
4971
|
-
readonly warnings: readonly ResolvedIssue[];
|
|
4972
|
-
readonly required: boolean;
|
|
4973
|
-
readonly disabled: boolean;
|
|
4974
|
-
readonly hidden: boolean;
|
|
4975
|
-
readonly resource: EntityRef;
|
|
4976
|
-
readonly field: ResourceFieldDefinition;
|
|
4977
|
-
/**
|
|
4978
|
-
* A relation field's scope, RESOLVED against the current `values` snapshot
|
|
4979
|
-
* (design doc §5). `undefined` when the field declared no `filter` opt (or
|
|
4980
|
-
* a function-form `filter` threw / returned a non-array — same
|
|
4981
|
-
* "broken predicate behaves as if never declared" convention
|
|
4982
|
-
* `resolvePredicate` uses for `required`/`disabled`, see
|
|
4983
|
-
* `./conditional.js`). `@burojs/ui-shadcn`'s `<Field>` merges this into
|
|
4984
|
-
* the field's `meta.filters` — the channel `RelationPickerInput` already
|
|
4985
|
-
* reads (`relation-picker.tsx:478-487,526`) — so a plain `{...binding}`
|
|
4986
|
-
* spread onto `<Field>` (what `<DeclarativeForm>` already does) needs no
|
|
4987
|
-
* extra wiring per field.
|
|
4988
|
-
*
|
|
4989
|
-
* Typed as `FixedFilterInput` (not the bare AST) so it widens together
|
|
4990
|
-
* with `RelationPickerProps.fixedFilters` and
|
|
4991
|
-
* `RelationPickerDialogProps.fixedFilters` downstream — a bare expression
|
|
4992
|
-
* is still a valid `FixedFilterInput`, so `resolveFieldFilter`'s bare-array
|
|
4993
|
-
* return (below) keeps satisfying this without a cast.
|
|
4994
|
-
*/
|
|
4995
|
-
readonly fixedFilters?: readonly FixedFilterInput[];
|
|
4996
|
-
}
|
|
6636
|
+
declare function resolveValidationMessage(issue: Pick<ValidationIssue, 'code' | 'message' | 'params'>, context: ValidationMessageContext): string;
|
|
6637
|
+
//#endregion
|
|
6638
|
+
//#region src/hooks/use-current-user-id.d.ts
|
|
4997
6639
|
/**
|
|
4998
|
-
*
|
|
4999
|
-
*
|
|
5000
|
-
*
|
|
5001
|
-
*
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
* `./conditional.js`.
|
|
5005
|
-
*/
|
|
5006
|
-
type RelationFilterOpt = readonly FilterExpression<ErasedResourceHandle>[] | ((values: FormValues) => readonly FilterExpression<ErasedResourceHandle>[]);
|
|
5007
|
-
interface UseDeclarativeFormOptions {
|
|
5008
|
-
/** The existing field-def map — the same shape `defineResource`'s `f` builder produces. */
|
|
5009
|
-
readonly fields: ResourceFieldMap;
|
|
5010
|
-
/** Controlled values. Presence (not truthiness) of this key selects controlled mode. */
|
|
5011
|
-
readonly value?: FormValues;
|
|
5012
|
-
/** Uncontrolled seed. Ignored once `value` is provided. */
|
|
5013
|
-
readonly defaultValue?: FormValues;
|
|
5014
|
-
readonly onChange?: (values: FormValues) => void;
|
|
5015
|
-
/** Drives label/hint/placeholder i18n, doc address, and the `<Field>` EntityRef. */
|
|
5016
|
-
readonly i18nPrefix?: string;
|
|
5017
|
-
/** Optional whole-form Standard Schema. */
|
|
5018
|
-
readonly schema?: StandardSchemaV1;
|
|
5019
|
-
/** Cross-field validation; may return warnings as well as errors. */
|
|
5020
|
-
readonly validate?: FormValidate;
|
|
5021
|
-
/**
|
|
5022
|
-
* Optional per-field capability seam. Declared for forward compatibility
|
|
5023
|
-
* with the design doc's §4 shape; still unread — an OPEN QUESTION (design
|
|
5024
|
-
* doc §13) whether it should be shaped now to also serve a later
|
|
5025
|
-
* `<ResourceForm>` migration, or stay minimal. NOT how `field(name)
|
|
5026
|
-
* .disabled` is resolved — that is the new `disabled` predicate opt
|
|
5027
|
-
* (Task 4, `./conditional.js`), a separate channel from this capability
|
|
5028
|
-
* seam.
|
|
5029
|
-
*/
|
|
5030
|
-
readonly editable?: (field: string, ctx: ValidationContext) => boolean;
|
|
5031
|
-
readonly onSubmit?: (values: FormValues) => unknown | Promise<unknown>;
|
|
5032
|
-
/**
|
|
5033
|
-
* Conditional checks for this form. Declarative forms are resource-less, so
|
|
5034
|
-
* checks are supplied here rather than resolved from a registry. Warnings
|
|
5035
|
-
* never gate `canSubmit`; a `severity: 'error'` check does.
|
|
5036
|
-
*/
|
|
5037
|
-
readonly checks?: readonly Check[];
|
|
5038
|
-
/**
|
|
5039
|
-
* Explicit `on: ['create' | 'edit' | ...]` surface for the check pass.
|
|
5040
|
-
* When omitted, `handleSubmit`/`revalidate` INFER it from whether a
|
|
5041
|
-
* baseline was supplied (`value`/`defaultValue` present → `'edit'`, absent
|
|
5042
|
-
* → `'create'`) — but that heuristic misfires for the ordinary "seed a
|
|
5043
|
-
* new record's defaults" create-form shape
|
|
5044
|
-
* (`<DeclarativeForm defaultValue={{ status: 'draft' }} />`), which DOES
|
|
5045
|
-
* supply `defaultValue` yet is still a create. Set this explicitly
|
|
5046
|
-
* whenever the form's create/edit-ness can't be read off "was a baseline
|
|
5047
|
-
* given" — the inference stays the default because the brief mandates it
|
|
5048
|
-
* as the fallback, not because it's always right.
|
|
5049
|
-
*/
|
|
5050
|
-
readonly surface?: CheckSurface;
|
|
5051
|
-
/**
|
|
5052
|
-
* Called by `handleSubmit` when a submit-time check pass produced
|
|
5053
|
-
* `confirmable` issues but no `blockers` — ordinary validation AND checks
|
|
5054
|
-
* both passed, and there is something worth a second look before saving.
|
|
5055
|
-
* The host (`<DeclarativeForm>`) supplies this to drive its own confirm
|
|
5056
|
-
* gate (built around `<CheckConfirmDialog>`), seeded with the exact
|
|
5057
|
-
* `CheckOutcome` this controller already computed. There is deliberately
|
|
5058
|
-
* no `useCheckGate(resource)`-style re-derivation here: that hook resolves
|
|
5059
|
-
* its check list from `app.checkSource.checks(resource)`, which has
|
|
5060
|
-
* nothing to key off for a resource-less form whose checks arrive as a
|
|
5061
|
-
* plain option. Resolving `'cancel'` aborts the submit (`onSubmit` is
|
|
5062
|
-
* never called); resolving `'proceed'` — or omitting this option
|
|
5063
|
-
* entirely — behaves exactly like an ordinary non-blocking warning, and
|
|
5064
|
-
* the submit proceeds.
|
|
5065
|
-
*/
|
|
5066
|
-
readonly onConfirmChecks?: (outcome: CheckOutcome) => Promise<'proceed' | 'cancel'>;
|
|
5067
|
-
}
|
|
5068
|
-
interface DeclarativeFormApi {
|
|
5069
|
-
/** Spread into `<Field/>`, or read raw for a hand-rolled input. */
|
|
5070
|
-
field(name: string): FieldBinding;
|
|
5071
|
-
/** Visible fields only, in `options.fields` declaration order — a hidden field is excluded (Task 4). */
|
|
5072
|
-
readonly fields: readonly FieldBinding[];
|
|
5073
|
-
readonly values: FormValues;
|
|
5074
|
-
/** severity 'error' issues, form-level plus per-field, from the last validation pass. */
|
|
5075
|
-
readonly errors: readonly ResolvedIssue[];
|
|
5076
|
-
/** severity 'warning' | 'info' issues — never block `canSubmit`. */
|
|
5077
|
-
readonly warnings: readonly ResolvedIssue[];
|
|
5078
|
-
/** `errors.length === 0 && !isSubmitting`. */
|
|
5079
|
-
readonly canSubmit: boolean;
|
|
5080
|
-
/** Current `values` vs. the baseline captured once at mount. */
|
|
5081
|
-
readonly isDirty: boolean;
|
|
5082
|
-
readonly isSubmitting: boolean;
|
|
5083
|
-
/** The last check pass, for a host that mounts its own confirm gate. */
|
|
5084
|
-
readonly checkOutcome: CheckOutcome | null;
|
|
5085
|
-
handleSubmit(cb?: (values: FormValues) => unknown | Promise<unknown>): (e?: SubmitEventLike) => Promise<void>;
|
|
5086
|
-
setValue(name: string, value: unknown): void;
|
|
5087
|
-
reset(next?: FormValues): void;
|
|
5088
|
-
/**
|
|
5089
|
-
* Re-run every field's + the form's validation against the current
|
|
5090
|
-
* `values` and update `errors`/`warnings`. A live seam for a renderer or
|
|
5091
|
-
* adopter to call on value change (e.g. debounced) — this controller does
|
|
5092
|
-
* NOT call it itself; deciding when to revalidate outside of blur/submit
|
|
5093
|
-
* is the caller's job.
|
|
5094
|
-
*/
|
|
5095
|
-
revalidate(): Promise<void>;
|
|
5096
|
-
}
|
|
6640
|
+
* The signed-in user's id from the `user` context slot: a non-empty string,
|
|
6641
|
+
* or a finite number as a string; `null` without a slot, while the slot is
|
|
6642
|
+
* pending and for an empty id. The one user-id read of the framework (drafts,
|
|
6643
|
+
* sign-out, recent records).
|
|
6644
|
+
*/
|
|
6645
|
+
declare function useCurrentUserId(): string | null;
|
|
5097
6646
|
//#endregion
|
|
5098
|
-
//#region src/
|
|
6647
|
+
//#region src/hooks/url-state/use-search-params-writer.d.ts
|
|
5099
6648
|
/**
|
|
5100
|
-
*
|
|
5101
|
-
*
|
|
5102
|
-
*
|
|
5103
|
-
*
|
|
5104
|
-
* `
|
|
5105
|
-
*
|
|
5106
|
-
* Reads `useOptionalVisibilityCtx()` (`../hooks/use-permissions.js`) as the
|
|
5107
|
-
* `ctx` argument every `visible`/`required`/`disabled` predicate receives —
|
|
5108
|
-
* NOT `useVisibilityCtx`, which throws outside a `BuroProvider`. This
|
|
5109
|
-
* controller must stay instantiable via a bare
|
|
5110
|
-
* `renderHook(() => useDeclarativeForm(...))`, no wrapper (Task 3's own
|
|
5111
|
-
* suite does this, and a form with no conditional fields has no reason to
|
|
5112
|
-
* require the whole app's provider tree just to mount) — the optional
|
|
5113
|
-
* variant defaults `ctx` to `{}` outside a provider instead.
|
|
6649
|
+
* Writes in-page URL state (a record tab, list state): `update` edits a copy
|
|
6650
|
+
* of the current search params, and the result is written on the same
|
|
6651
|
+
* pathname, by default with `replace`. Never asks the navigation guard and
|
|
6652
|
+
* never changes the pathname; a navigation to another page goes through
|
|
6653
|
+
* `useRouteNavigate`. Without a router adapter it does nothing.
|
|
5114
6654
|
*/
|
|
5115
|
-
declare function
|
|
6655
|
+
declare function useSearchParamsWriter(): (update: (params: URLSearchParams) => void, options?: {
|
|
6656
|
+
readonly history?: 'push' | 'replace';
|
|
6657
|
+
}) => void;
|
|
5116
6658
|
//#endregion
|
|
5117
|
-
//#region src/
|
|
5118
|
-
/**
|
|
5119
|
-
interface
|
|
5120
|
-
/**
|
|
5121
|
-
readonly
|
|
5122
|
-
readonly
|
|
5123
|
-
readonly
|
|
6659
|
+
//#region src/record/record-frame-context.d.ts
|
|
6660
|
+
/** What a record frame gives the pieces rendered inside `<RecordScreen>`. */
|
|
6661
|
+
interface RecordFrameValue {
|
|
6662
|
+
/** The resource's canonical name. */
|
|
6663
|
+
readonly resource: string;
|
|
6664
|
+
readonly recordId: string | undefined;
|
|
6665
|
+
readonly mode: ScreenMode;
|
|
6666
|
+
/** The record being shown or edited, once it is read; `undefined` in create. */
|
|
6667
|
+
readonly record: Readonly<Record<string, unknown>> | undefined;
|
|
6668
|
+
/** The form controller planning the frame's screen. */
|
|
6669
|
+
readonly controller: FormController;
|
|
5124
6670
|
}
|
|
6671
|
+
/** The record frame `<RecordScreen>` provides; `null` outside one. */
|
|
6672
|
+
declare const RecordFrameContext: import("react").Context<RecordFrameValue | null>;
|
|
5125
6673
|
/**
|
|
5126
|
-
*
|
|
5127
|
-
*
|
|
5128
|
-
*
|
|
5129
|
-
* `hidden` is `!evaluateVisible(...)` — core's real evaluator
|
|
5130
|
-
* (`@burojs/core`'s `permissions.ts:121-136`), reused as-is rather than
|
|
5131
|
-
* reimplemented: undefined → visible (adopters opt INTO gating); a throw →
|
|
5132
|
-
* NOT visible, unconditionally (fail-closed). This is THE existing `visible`
|
|
5133
|
-
* convention every other renderer (`<ResourceList>`, `<ResourceShow>`,
|
|
5134
|
-
* `<ResourceForm>`) already consults — reusing it, rather than routing
|
|
5135
|
-
* `visible` through the more generic `resolvePredicate` below, is what
|
|
5136
|
-
* keeps this controller's conditional-visibility semantics identical to
|
|
5137
|
-
* theirs.
|
|
5138
|
-
*
|
|
5139
|
-
* `required`/`disabled` default to `false` when undeclared or on a throw
|
|
5140
|
-
* (`resolvePredicate`) — "no predicate declared → behave exactly as before
|
|
5141
|
-
* this feature existed".
|
|
6674
|
+
* The record frame around the caller. A frame piece rendered outside
|
|
6675
|
+
* `<RecordScreen>` is a development error (P1b+P1c decision 6), so this throws there.
|
|
5142
6676
|
*/
|
|
5143
|
-
declare function
|
|
6677
|
+
declare function useRecordFrame(): RecordFrameValue;
|
|
6678
|
+
/** The record frame around the caller, or `null` outside `<RecordScreen>`. */
|
|
6679
|
+
declare function useOptionalRecordFrame(): RecordFrameValue | null;
|
|
5144
6680
|
//#endregion
|
|
5145
6681
|
//#region src/export/runs-store.d.ts
|
|
5146
6682
|
interface ExportRunEntry {
|
|
@@ -5286,5 +6822,5 @@ declare function useResourceExport(resource: string, opts?: UseResourceExportOpt
|
|
|
5286
6822
|
declare const PACKAGE_NAME: "@burojs/react";
|
|
5287
6823
|
declare const PACKAGE_VERSION: "0.0.0";
|
|
5288
6824
|
//#endregion
|
|
5289
|
-
export { type AppActionEntry, type ApplyViewToUrlStateOptions, type ApplyViewUrlStateSetters, type AuthController, type
|
|
6825
|
+
export { type AppActionEntry, type AppAudit, type ApplyViewToUrlStateOptions, type ApplyViewUrlStateSetters, type AuthController, BLOCK_COMPONENT, type BlockDataEntryName, type BlockImplementation, type BlockImplementationCatalog, type BlockScreenProps, type BlockViewPropValues, type BlockViewProps, type BuroDehydratedData, BuroPresentationOutlet, BuroProvider, type BuroProviderProps, BuroRoutes, BuroRuntimeProvider, type BuroRuntimeProviderProps, type CandidatesAccess, type CapabilityResolver, type CheckGateRequest, type CheckGateState, type CodecOptions, type CollectionDisplayProps, type CollectionInputProps, ComponentsContext, type CountExecution, type CreateAuthControllerOptions, type CreateDataRuntimeOptions, type CreateDataRuntimeTransitionParticipantOptions, type CustomPageRouteDescriptor, DEFAULT_HISTORY_MODE, DEFAULT_LANGUAGE_STORAGE_KEY, type DataRuntimeContextValue, type DataRuntimeLease, type DataRuntimeTransitionParticipant, type DataSessionController, type DataSessionState, type DataSessionTransitionParticipant, type DefinedField, type DismissGuard, DismissGuardScope, type DismissScopeValue, DispatcherProvider, type DispatcherProviderProps, type DocPanelApi, type DocPanelTarget, type DocScopeView, type DocTopicView, DocsProvider, type DocumentedScope, EMPTY_FIELD_IMPLEMENTATIONS, type EntryAnswer, type EntryKind, type ExportRunEntry, ExportRunsStore, FLOW_COMPONENT, type FieldAccessibilityIds, type FieldBinding, type FieldI18n, type FieldImplementation, type FieldImplementationCatalog, type FieldImplementationComponent, type FieldImplementationDiagnostic, type FieldImplementationLayout, type FieldImplementationMap, FieldImplementationProvider, type FieldImplementationSource, type FieldMetaState, type FieldPresentation, type FieldRenderContext, type FieldRenderSurface, type FieldTestIds, type FieldType, type FieldUiHints, type FileItem, type FileItemStatus, type FilterFieldSpec, type FilterFieldsResult, type FilterKind, FlowRowBatchContext, type FlowRowBatchValue, type FlowRowControl, type FlowRowState, type FlowScreenProps, type FlowStart, type FormController, type FormControllerFailure, type FormDraftState, type FormSteps, type FormSubmitResult, type FormValues, FrameCheckContext, type FrameCheckValue, type FrameImplementation, type FrameImplementationCatalog, type FrameNodeAttributes, type FramePiece, type FrameStep, type FrameTab, type FrameTranslate, type FrameViewProps, type HistoryMode, type HostPage, I18nContext, type InfiniteListData, type InitialManifest, type InlineFlowHolder, type InlineLease, LOCAL_USER_SCOPE_ID, type ListFrameViewProps, type ListState, type LocalStorageUiSettingsAdapterOptions, type ManifestHydration, type ManifestHydrationScope, type NativeInfiniteListResult, type NativeMutationOptions, type NativeQueryOptions, type NativeQueryResult, type NavigationBlockerHandle, type NavigationGuardPrompt, type NavigationGuardText, type NotificationSink, type NotificationSinkMessage, PACKAGE_NAME, PACKAGE_VERSION, PEEK_COMPONENT, type PageAccess, type PageFlowGate, type PageFrameViewProps, type PageScreen, type PanelFrameViewProps, type PeekFrameViewProps, type PeekScreenProps, type PlacementRuntime, type PlacementView, type PresentBlockInput, type PresentFlowInput, type PresentationsMode, type ProjectedRecord, QUICK_ANCHOR_ATTRIBUTE, QUICK_COMPONENT, type QuickApi, type QuickEntry, QuickEntryContext, type QuickEntryValue, type QuickOpen, type QuickScreenProps, type QuickSettledRow, type QuickStack, RELATION_BATCH_MAX_PAGE, RENDER_TIME_DATA, RESERVED_LIST_SUFFIXES, RESOLVE_COOLDOWN_MS, RESOURCE_URL_STATE_LIMITS, RecordCodecError, type RecordCodecOutcome, RecordFrameContext, type RecordFrameSlots, type RecordFrameValue, type RecordFrameViewProps, type RelatedRecord, type RelationFilterOpt, type ResolvedFieldImplementation, type ResolvedIssue, type ResolvedItemAction, ResourceContext, type ResourceFlowSurface, type ResourceListController, ResourceListProvider, type ResourceListProviderProps, type ResourceRecordCodec, type ResourceRouteDescriptor, type ResourceUrlState, type RouteDescriptor, type RouteNavigate, type RouteNavigateOptions, RouteSourceContext, type RouterAdapter, RouterAdapterProvider, type RouterAdapterProviderProps, type RowRecord, type SavedViewEntry, type ScalarDisplayProps, type ScalarInputProps, type ScreenOpenState, ScreenStateProvider, type ScreenStateProviderProps, type ScreenStateValue, type SetterOptions, type StepsFrameViewProps, type TabsFrameViewProps, type TaskRunController, type TaskRunReporter, type TestIdBuilder, TestIdContext, UIActivationSurfaceProvider, type UIInstance, UIInstanceProvider, type UIPresent, type UIPresentInput, type UIPresentationHost, type UIPresentationHostProps, type UIPresentationHosts, type UIPresentationLifecycle, type UIPresentationOptionsSchema, UIPresentationRuntimeProvider, type UIPresentationScreens, UIPresentations, type UIPresentationsProps, UiSettingsProvider, type UiSettingsProviderProps, type UrlCache, type UseCapabilityArgs, type UseCheckGateResult, type UseChecksOptions, type UseChecksResult, type UseCommandPaletteOptions, type UseCommandPaletteResult, type UseCountOptions, type UseCreateOneOptions, type UseCustomMutationOptions, type UseCustomQueryOptions, type UseDeleteManyOptions, type UseDeleteOneOptions, type UseEnumValuesResult, type UseFieldImplementationArgs, type UseFileFieldArgs, type UseFileFieldResult, type UseFileUrlsOpts, type UseFileUrlsResult, type UseFilterFieldsOptions, type UseFormControllerFormOptions, type UseFormControllerRecordOptions, type UseInfiniteListOptions, type UseListOptions, type UseManyOptions, type UseOneOptions, type UseRefreshResult, type UseRelatedRecordOptions, type UseRelatedRecordResult, type UseResourceExportOptions, type UseResourceExportResult, type UseResourceListOptions, type UseSavedViewsResult, type UseTaskRunOptions, type UseUiSettingsCollectionResult, type UseUiSettingsResult, type UseUiSettingsSingletonResult, type UseUpdateManyOptions, type UseUpdateOneOptions, type ValidationMessageContext, applyViewToUrlState, buildDI, buroMutationOptions, composeBlockImplementations, composeFieldImplementations, composeFrameImplementations, conjoinHostPage, createAuthController, createDataRuntime, createDataRuntimeTransitionParticipant, createDataSession, createLocalStorageUiSettingsAdapter, createManifestHydrationScope, createResourceRecordCodec, createRuntimeActionDataAccess, createUrlCache, defineFieldWithImplementation, dehydrateBuroData, deserializeResourceState, disposeBuroRequest, en, fieldImplementation, filterFields, formatBytes, generateRouteDescriptors, getResourceParams, hostPageFor, hostPageRef, hydrateBuroData, hydrateManifest, implementBlock, implementFrame, isCustomPageRoute, matchesAccept, mergeComponents, modeForSurface, normalizeServerRecordIssues, pageAccessFor, policyRecordOf, policyRowsOf, quickAnchorRef, resolveCountExecution, resolveFieldImplementation, resolveRoute, resolveValidationMessage, resourceFlowsOn, retryRecordRead, ru, serializeBuroHydration, serializeResourceState, sharedUrlCache, useApp, useAppActions, useApplicationSnapshot, useAudit, useAvailability, useAvailabilityGate, useAvailabilityResolver, useCandidatesAccess, useCapability, useCapabilityResolver, useChangeLocale, useCheckGate, useChecks, useCommandPalette, useComponent, useCount, useCreateOne, useCtx, useCurrentResource, useCurrentUIActivation, useCurrentUserId, useCustomMutation, useCustomQuery, useDataRuntime, useDebouncedValue, useDefaultComponent, useDeleteMany, useDeleteOne, useDismissExportRun, useDismissGuard, useDismissPending, useDispatcher, useDispatcherEffects, useDoc, useDocPanel, useDocScopes, useDocTopic, useDocTopics, useDocTrailScopes, useDocsConfig, useDocumentedScopes, useEntryGate, useEnumValues, useExportRuns, useFieldAccess, useFieldImplementation, useFieldImplementationCatalog, useFieldMeta, useFieldMetaSources, useFileField, useFileStorage, useFileUrls, useFilterFields, useFlowFormCatalog, useFlowOpenImplementation, useFlowRowBatch, useFlowRowResolver, useFormController, useFrameImplementations, useFramePiece, useFrameT, useHasDocTopics, useHostPage, useI18nCaps, useIdentity, useInfiniteList, useIsAuthenticated, useItemActions, useLanguageStorageKey, useLayerRuntime, useLayerStatus, useList, useListAccess, useLocalStorage, useLocale, useLogin, useLogout, useMany, useNavigationBlocker, useNavigationGuardText, useNavigationHold, useOne, useOptionalAuthController, useOptionalDataRuntime, useOptionalFileStorage, useOptionalLocale, useOptionalRecordFrame, useOptionalRouterAdapter, useOptionalT, useOptionalUIActivationSurface, useOptionalUIInstance, useOptionalUIPresentation, useOptionalVisibilityCtx, usePageAccess, usePageFlowGate, usePageScreen, usePermissions, usePlacement, usePresentBlock, usePresentFlow, useProjectedRecord, useProjectedTitle, useProjection, usePublishDocVariant, useQuick, useQuickEntry, useQuickEntryValue, useQuickOpener, useRecordFrame, useRecordTitle, useRefresh, useRegisterNavigationGuardDialog, useRegisterNotificationSink, useRelatedRecord, useResource, useResourceExport, useResourceI18n, useResourceList, useResourceListContext, useResourceUrlState, useRouteListImplementation, useRouteNavigate, useRouterAdapter, useSavedViews, useScopeCtx, useScreenState, useSearchParamsWriter, useSetSlice, useT, useTaskRun, useTestIds, useTrailHasDocs, useTranslate, useUIInstance, useUIPresent, useUIPresentationRuntime, useUiSettings, useUpdateMany, useUpdateOne, useViewRow, useVisibilityCtx, validateBuroHydration };
|
|
5290
6826
|
//# sourceMappingURL=index.d.cts.map
|