@craftainer/crud-views 0.0.0-stage → 0.1.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/LICENSE +674 -0
- package/README.md +63 -2
- package/dist/index.d.mts +1176 -0
- package/dist/index.mjs +5459 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +87 -4
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,1176 @@
|
|
|
1
|
+
import { ComponentType, ReactElement, ReactNode } from "react";
|
|
2
|
+
import { Theme } from "@mui/material/styles";
|
|
3
|
+
import { InfiniteData, QueryClient, UseInfiniteQueryResult, UseMutationResult, UseQueryResult } from "@tanstack/react-query";
|
|
4
|
+
import { BulkResult, Capabilities, CrudClient, Filters, JsonObject, Resource, ResourceClient } from "@craftainer/crud-sdk";
|
|
5
|
+
import { CrudQuery, InfiniteListInit, TanstackApi, UpdateVariables } from "@craftainer/crud-sdk/tanstack";
|
|
6
|
+
import { DataGridProps } from "@mui/x-data-grid";
|
|
7
|
+
//#region src/core/types.d.ts
|
|
8
|
+
/** What a manifest field renders as. `array` and `json` are fallbacks for schema members the manifest `fields` list does not cover. */
|
|
9
|
+
type FieldKind = "string" | "number" | "integer" | "boolean" | "date" | "datetime" | "enum" | "array" | "json";
|
|
10
|
+
/** The manifest's `filter_ops` vocabulary (`eq` is the bare `field=` form). */
|
|
11
|
+
type FilterOp = "eq" | "min" | "max" | "in" | "contains" | "icontains" | "regex";
|
|
12
|
+
/** A JSON value as it travels on the wire. */
|
|
13
|
+
type FieldValue = string | number | boolean | null | undefined | readonly FieldValue[] | {
|
|
14
|
+
readonly [key: string]: FieldValue;
|
|
15
|
+
};
|
|
16
|
+
/** Validation hints lifted from the read/create/update JSON Schemas. */
|
|
17
|
+
interface FieldConstraints {
|
|
18
|
+
readonly minLength: number | undefined;
|
|
19
|
+
readonly maxLength: number | undefined;
|
|
20
|
+
readonly minimum: number | undefined;
|
|
21
|
+
readonly maximum: number | undefined;
|
|
22
|
+
readonly pattern: string | undefined;
|
|
23
|
+
}
|
|
24
|
+
/** One field of a resource, merged from the manifest `fields` and `schemas`. */
|
|
25
|
+
interface FieldDescriptor {
|
|
26
|
+
readonly name: string;
|
|
27
|
+
/** Human label derived from `name` (`power_level` -> `Power level`). */
|
|
28
|
+
readonly label: string;
|
|
29
|
+
readonly kind: FieldKind;
|
|
30
|
+
/** The JSON Schema `format` (`email`, `uri`, `uuid`, ...), or `null`. */
|
|
31
|
+
readonly format: string | null;
|
|
32
|
+
/** The value may be `null` (the schema allows it). */
|
|
33
|
+
readonly nullable: boolean;
|
|
34
|
+
/** Neither `create` nor `update` accepts it: show it, never edit it. */
|
|
35
|
+
readonly readOnly: boolean;
|
|
36
|
+
/** `create` requires it. */
|
|
37
|
+
readonly required: boolean;
|
|
38
|
+
/** `enum` choices (from the manifest field, else the schema). */
|
|
39
|
+
readonly choices: readonly string[] | null;
|
|
40
|
+
/** For `array`, the kind of the items. */
|
|
41
|
+
readonly itemKind: FieldKind | null;
|
|
42
|
+
readonly constraints: FieldConstraints;
|
|
43
|
+
/** The manifest lists it as a field: it can be filtered/sorted per `filterOps`/`sortable`. */
|
|
44
|
+
readonly inManifest: boolean;
|
|
45
|
+
readonly sortable: boolean;
|
|
46
|
+
readonly filterOps: readonly FilterOp[];
|
|
47
|
+
readonly numeric: boolean;
|
|
48
|
+
readonly categorical: boolean;
|
|
49
|
+
}
|
|
50
|
+
/** One operand of a filter. `datetime` filters carry `Date`s, `date` filters `YYYY-MM-DD` strings (the SDK's query builder wants exactly that). */
|
|
51
|
+
type FilterScalar = string | number | boolean | Date;
|
|
52
|
+
/** The filter state of one field: operator -> operand (`in` takes an array). Absent or empty means no filter. */
|
|
53
|
+
type FieldFilter = Readonly<Partial<Record<FilterOp, FilterScalar | readonly FilterScalar[]>>>;
|
|
54
|
+
/** Filter state of a whole resource: field name -> its filter. */
|
|
55
|
+
type FieldFilters = Readonly<Record<string, FieldFilter | undefined>>;
|
|
56
|
+
/** Props every renderer gets. */
|
|
57
|
+
interface RendererBase {
|
|
58
|
+
readonly field: FieldDescriptor;
|
|
59
|
+
/** The resource name, for renderers that special-case a field. */
|
|
60
|
+
readonly resource: string;
|
|
61
|
+
readonly size?: "small" | "medium" | undefined;
|
|
62
|
+
}
|
|
63
|
+
/** Shows a value. `value` is the wire value (`undefined` when the record has no such member). */
|
|
64
|
+
interface DisplayRendererProps extends RendererBase {
|
|
65
|
+
readonly value: FieldValue;
|
|
66
|
+
readonly record?: Readonly<Record<string, FieldValue>> | undefined;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Edits a value. Wire values in and out: strings for `string`/`enum`/`date`
|
|
70
|
+
* (`YYYY-MM-DD`)/`datetime` (ISO-8601 UTC), numbers for `number`/`integer`,
|
|
71
|
+
* booleans, arrays and JSON for `array`/`json`. A cleared input emits `null`
|
|
72
|
+
* when the field is nullable, else `undefined` (leave the member out).
|
|
73
|
+
*/
|
|
74
|
+
interface InputRendererProps extends RendererBase {
|
|
75
|
+
readonly value: FieldValue;
|
|
76
|
+
readonly onChange: (value: FieldValue) => void;
|
|
77
|
+
readonly onBlur?: (() => void) | undefined;
|
|
78
|
+
/** Validation message to show (the form owns validation). */
|
|
79
|
+
readonly error?: string | undefined;
|
|
80
|
+
readonly helperText?: string | undefined;
|
|
81
|
+
readonly disabled?: boolean | undefined;
|
|
82
|
+
readonly autoFocus?: boolean | undefined;
|
|
83
|
+
readonly id?: string | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* Reports whether the input's own draft is invalid, with the reason: it is
|
|
86
|
+
* called with a message when the draft cannot be turned into a valid value
|
|
87
|
+
* (non-numeric, malformed JSON, out of range) and with `null` when it is
|
|
88
|
+
* valid again (or the input unmounts). A form blocks submit while any field
|
|
89
|
+
* reports a reason. Additive to the frozen I4 (ADR 0002 addendum).
|
|
90
|
+
*/
|
|
91
|
+
readonly onInvalid?: ((reason: string | null) => void) | undefined;
|
|
92
|
+
}
|
|
93
|
+
/** Edits the filter of one field. Emits `undefined` when cleared. */
|
|
94
|
+
interface FilterRendererProps extends RendererBase {
|
|
95
|
+
readonly value: FieldFilter | undefined;
|
|
96
|
+
readonly onChange: (value: FieldFilter | undefined) => void;
|
|
97
|
+
}
|
|
98
|
+
type DisplayRenderer = ComponentType<DisplayRendererProps>;
|
|
99
|
+
type InputRenderer = ComponentType<InputRendererProps>;
|
|
100
|
+
type FilterRenderer = ComponentType<FilterRendererProps>;
|
|
101
|
+
type RendererRole = "display" | "input" | "filter";
|
|
102
|
+
/** The three renderers for one selector; each is optional. */
|
|
103
|
+
interface FieldRenderers {
|
|
104
|
+
readonly display?: DisplayRenderer;
|
|
105
|
+
readonly input?: InputRenderer;
|
|
106
|
+
readonly filter?: FilterRenderer;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Selector -> renderers. A selector is `"<resource>.<field>"` (one field),
|
|
110
|
+
* `"<kind>:<format>"` (`string:email`) or `"<kind>"` (`date`).
|
|
111
|
+
*/
|
|
112
|
+
type RendererOverrides = Readonly<Record<string, FieldRenderers>>;
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region src/core/provider.d.ts
|
|
115
|
+
interface CrudProviderProps {
|
|
116
|
+
readonly client: CrudClient;
|
|
117
|
+
readonly queryClient: QueryClient;
|
|
118
|
+
/** Wraps the tree in this MUI theme. Omit to inherit the ambient theme. */
|
|
119
|
+
readonly theme?: Theme | undefined;
|
|
120
|
+
/** Renderer overrides for this tree (selector -> renderers). */
|
|
121
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
122
|
+
readonly scope?: string | undefined;
|
|
123
|
+
readonly locale?: string | undefined;
|
|
124
|
+
readonly timeZone?: string | undefined;
|
|
125
|
+
readonly children?: ReactNode;
|
|
126
|
+
}
|
|
127
|
+
/** Provides the SDK client, the TanStack `QueryClient`, an optional MUI theme and renderer overrides. */
|
|
128
|
+
export declare function CrudProvider({ client, queryClient, theme, renderers, scope, locale, timeZone, children }: CrudProviderProps): ReactElement;
|
|
129
|
+
//#endregion
|
|
130
|
+
//#region src/core/context.d.ts
|
|
131
|
+
/** What `useCrud` returns. */
|
|
132
|
+
interface CrudContextValue {
|
|
133
|
+
readonly client: CrudClient;
|
|
134
|
+
readonly queryClient: QueryClient;
|
|
135
|
+
/** Separates cached manifests of different callers (e.g. the user id). */
|
|
136
|
+
readonly scope: string;
|
|
137
|
+
/** BCP 47 tag for number and date formatting; `undefined` = the browser's. */
|
|
138
|
+
readonly locale: string | undefined;
|
|
139
|
+
/** IANA zone for `datetime` display; `undefined` = the browser's. */
|
|
140
|
+
readonly timeZone: string | undefined;
|
|
141
|
+
readonly renderers: RendererOverrides | undefined;
|
|
142
|
+
}
|
|
143
|
+
/** The provider's value; throws outside a `CrudProvider`. */
|
|
144
|
+
export declare function useCrud(): CrudContextValue;
|
|
145
|
+
//#endregion
|
|
146
|
+
//#region src/core/useResource.d.ts
|
|
147
|
+
/** TanStack hooks bound to one resource. Stable between renders while the resource is. */
|
|
148
|
+
interface ResourceHooks<Read extends object = JsonObject, Create extends object = JsonObject, Update extends object = JsonObject> {
|
|
149
|
+
useList(query?: CrudQuery): UseQueryResult<Read[]>;
|
|
150
|
+
useInfiniteList(query?: CrudQuery, init?: InfiniteListInit): UseInfiniteQueryResult<InfiniteData<Read[], number>>;
|
|
151
|
+
useRecord(id: number): UseQueryResult<Read>;
|
|
152
|
+
useStats(query?: CrudQuery): UseQueryResult<JsonObject>;
|
|
153
|
+
usePredict(query?: CrudQuery): UseQueryResult<JsonObject>;
|
|
154
|
+
useRevisions(id: number): UseQueryResult<JsonObject[]>;
|
|
155
|
+
/** Invalidates lists, stats and predictions on success. */
|
|
156
|
+
useCreate(): UseMutationResult<Read, Error, Create>;
|
|
157
|
+
/** Variables carry `ifMatch` for `If-Match`; a stale one fails with `PreconditionFailed`. */
|
|
158
|
+
useUpdate(): UseMutationResult<Read, Error, UpdateVariables<Update>>;
|
|
159
|
+
useDelete(): UseMutationResult<unknown, Error, number>;
|
|
160
|
+
}
|
|
161
|
+
/** The loaded state of `useResource`. */
|
|
162
|
+
interface ReadyResource<Read extends object = JsonObject, Create extends object = JsonObject, Update extends object = JsonObject> {
|
|
163
|
+
readonly status: "ready";
|
|
164
|
+
readonly error: null;
|
|
165
|
+
/** The manifest entry (schemas, fields, pagination, paths, ...). */
|
|
166
|
+
readonly resource: Resource;
|
|
167
|
+
/** Shortcut for `resource.capabilities`: gate every optional view on it. */
|
|
168
|
+
readonly capabilities: Capabilities;
|
|
169
|
+
readonly fields: readonly FieldDescriptor[];
|
|
170
|
+
field(name: string): FieldDescriptor | undefined;
|
|
171
|
+
/** The SDK handle, for calls the hooks do not cover (clone, publish, restore, bulk). */
|
|
172
|
+
readonly handle: ResourceClient<Read, Create, Update>;
|
|
173
|
+
readonly api: TanstackApi<Read, Create, Update>;
|
|
174
|
+
readonly hooks: ResourceHooks<Read, Create, Update>;
|
|
175
|
+
}
|
|
176
|
+
interface PendingResource {
|
|
177
|
+
readonly status: "pending";
|
|
178
|
+
readonly error: null;
|
|
179
|
+
}
|
|
180
|
+
interface FailedResource {
|
|
181
|
+
readonly status: "error";
|
|
182
|
+
readonly error: Error;
|
|
183
|
+
}
|
|
184
|
+
type UseResourceResult<Read extends object = JsonObject, Create extends object = JsonObject, Update extends object = JsonObject> = PendingResource | FailedResource | ReadyResource<Read, Create, Update>;
|
|
185
|
+
/**
|
|
186
|
+
* Loads the manifest (once per caller scope) and returns the resource `name`
|
|
187
|
+
* (the highest `api_version` unless given) with its capabilities, described
|
|
188
|
+
* fields, SDK handle and TanStack hooks. Query keys use `name`, or
|
|
189
|
+
* `name@apiVersion` when `apiVersion` is given, so two versions never share a cache entry.
|
|
190
|
+
*/
|
|
191
|
+
export declare function useResource<Read extends object = JsonObject, Create extends object = JsonObject, Update extends object = JsonObject>(name: string, apiVersion?: string): UseResourceResult<Read, Create, Update>;
|
|
192
|
+
//#endregion
|
|
193
|
+
//#region src/core/ResourceGate.d.ts
|
|
194
|
+
interface ResourceGateProps {
|
|
195
|
+
readonly name: string;
|
|
196
|
+
readonly apiVersion?: string | undefined;
|
|
197
|
+
/** Shown while the manifest loads. Default: a spinner. */
|
|
198
|
+
readonly pending?: ReactNode;
|
|
199
|
+
/** Shown on failure (unknown resource, network). Default: an error alert. */
|
|
200
|
+
readonly fallback?: ((error: Error) => ReactNode) | undefined;
|
|
201
|
+
readonly children: (ready: ReadyResource) => ReactNode;
|
|
202
|
+
}
|
|
203
|
+
/** Renders `children` once the resource is loaded; the common loading and error states otherwise. */
|
|
204
|
+
export declare function ResourceGate({ name, apiVersion, pending, fallback, children }: ResourceGateProps): ReactElement;
|
|
205
|
+
//#endregion
|
|
206
|
+
//#region src/core/fields.d.ts
|
|
207
|
+
/** `power_level` -> `Power level`. */
|
|
208
|
+
export declare function humanize(name: string): string;
|
|
209
|
+
/**
|
|
210
|
+
* Every field of `resource`, in read-schema order, then manifest fields the
|
|
211
|
+
* read schema does not list. The `id` field is included (read only).
|
|
212
|
+
*/
|
|
213
|
+
export declare function describeFields(resource: Resource): readonly FieldDescriptor[];
|
|
214
|
+
//#endregion
|
|
215
|
+
//#region src/core/registry.d.ts
|
|
216
|
+
/** The renderer type of each role. */
|
|
217
|
+
interface RendererByRole {
|
|
218
|
+
readonly display: DisplayRenderer;
|
|
219
|
+
readonly input: InputRenderer;
|
|
220
|
+
readonly filter: FilterRenderer;
|
|
221
|
+
}
|
|
222
|
+
/** The selectors that match `field` of `resource`, most specific first. */
|
|
223
|
+
export declare function selectorsFor(field: FieldDescriptor, resource: string): readonly string[];
|
|
224
|
+
/** One renderer role resolved from `layers` (nearest first); `undefined` when no layer has one. */
|
|
225
|
+
export declare function resolveRenderer<R extends RendererRole>(role: R, field: FieldDescriptor, resource: string, layers: readonly (RendererOverrides | undefined)[]): RendererByRole[R] | undefined;
|
|
226
|
+
/**
|
|
227
|
+
* Registers renderers process-wide (the layer between `CrudProvider`'s
|
|
228
|
+
* `renderers` and the built-ins). A later registration wins per role. Returns
|
|
229
|
+
* the function that removes exactly this registration, in any order.
|
|
230
|
+
* Prefer the provider's `renderers` prop in apps: this is shared state.
|
|
231
|
+
*/
|
|
232
|
+
export declare function registerFieldRenderer(selector: string, renderers: FieldRenderers): () => void;
|
|
233
|
+
/** The process-wide registrations merged (a new object after every change). */
|
|
234
|
+
export declare function getRegisteredRenderers(): RendererOverrides;
|
|
235
|
+
//#endregion
|
|
236
|
+
//#region src/core/renderers/builtins.d.ts
|
|
237
|
+
/** The built-in layer: one entry per `FieldKind`. */
|
|
238
|
+
export declare const builtinRenderers: RendererOverrides;
|
|
239
|
+
//#endregion
|
|
240
|
+
//#region src/core/fieldComponents.d.ts
|
|
241
|
+
/** Props of the three field components: the renderer props plus a per-component override layer. */
|
|
242
|
+
type WithOverrides<P> = P & {
|
|
243
|
+
/** Highest-precedence layer, for this one component. */
|
|
244
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
245
|
+
};
|
|
246
|
+
/** Shows `value` with the resolved display renderer. */
|
|
247
|
+
export declare function FieldDisplay({ renderers, ...props }: WithOverrides<DisplayRendererProps>): ReactElement;
|
|
248
|
+
/** Edits a value with the resolved input renderer. */
|
|
249
|
+
export declare function FieldInput({ renderers, ...props }: WithOverrides<InputRendererProps>): ReactElement;
|
|
250
|
+
/** Edits the filter of a field with the resolved filter renderer. */
|
|
251
|
+
export declare function FieldFilterInput({ renderers, ...props }: WithOverrides<FilterRendererProps>): ReactElement;
|
|
252
|
+
//#endregion
|
|
253
|
+
//#region src/core/values.d.ts
|
|
254
|
+
/** What a cleared input emits: `null` for a nullable field, else `undefined`. */
|
|
255
|
+
export declare const emptyValue: (field: FieldDescriptor) => FieldValue;
|
|
256
|
+
//#endregion
|
|
257
|
+
//#region src/core/filterState.d.ts
|
|
258
|
+
/** Sets `op` on `current`; an empty operand removes it, and no operators left is `undefined`. */
|
|
259
|
+
export declare function withOp(current: FieldFilter | undefined, op: FilterOp, operand: FilterScalar | readonly FilterScalar[] | undefined): FieldFilter | undefined;
|
|
260
|
+
/** Whether the manifest lets a client filter on this field at all. */
|
|
261
|
+
export declare const isFilterable: (field: FieldDescriptor) => boolean;
|
|
262
|
+
//#endregion
|
|
263
|
+
//#region src/core/filters.d.ts
|
|
264
|
+
/**
|
|
265
|
+
* Turns per-field filter state into the SDK's flat `Filters`: `eq` is the bare
|
|
266
|
+
* field name, every other operator is `field__op`.
|
|
267
|
+
*/
|
|
268
|
+
export declare function toQueryFilters(filters: FieldFilters): Filters;
|
|
269
|
+
//#endregion
|
|
270
|
+
//#region src/core/shells.d.ts
|
|
271
|
+
/** Props every shell shares. */
|
|
272
|
+
interface ShellProps {
|
|
273
|
+
readonly title: ReactNode;
|
|
274
|
+
/** Buttons for the footer (dialog, drawer) or the header (page). */
|
|
275
|
+
readonly actions?: ReactNode;
|
|
276
|
+
readonly children?: ReactNode;
|
|
277
|
+
}
|
|
278
|
+
interface PageShellProps extends ShellProps {
|
|
279
|
+
readonly subtitle?: ReactNode;
|
|
280
|
+
/** Links shown above the title, e.g. `[<Link>Heroes</Link>]`. */
|
|
281
|
+
readonly breadcrumbs?: readonly ReactNode[] | undefined;
|
|
282
|
+
readonly maxWidth?: "sm" | "md" | "lg" | "xl" | false;
|
|
283
|
+
}
|
|
284
|
+
/** A full page: heading row (title, subtitle, actions) above the content. */
|
|
285
|
+
export declare function PageShell({ title, subtitle, actions, breadcrumbs, maxWidth, children }: PageShellProps): ReactElement;
|
|
286
|
+
interface OverlayShellProps extends ShellProps {
|
|
287
|
+
readonly open: boolean;
|
|
288
|
+
readonly onClose: () => void;
|
|
289
|
+
/** Label of the close button that is always present. Default "Close". */
|
|
290
|
+
readonly closeLabel?: string;
|
|
291
|
+
}
|
|
292
|
+
interface DialogShellProps extends OverlayShellProps {
|
|
293
|
+
readonly maxWidth?: "xs" | "sm" | "md" | "lg";
|
|
294
|
+
}
|
|
295
|
+
/** A modal dialog with a title, scrolling content and a footer of actions. */
|
|
296
|
+
export declare function DialogShell({ open, onClose, title, actions, closeLabel, maxWidth, children }: DialogShellProps): ReactElement;
|
|
297
|
+
interface DrawerShellProps extends OverlayShellProps {
|
|
298
|
+
readonly anchor?: "left" | "right";
|
|
299
|
+
/** Width in theme spacing units on screens from `sm` up (full width below). Default 60. */
|
|
300
|
+
readonly width?: number;
|
|
301
|
+
}
|
|
302
|
+
/** A side drawer with a title, scrolling content and a footer of actions. */
|
|
303
|
+
export declare function DrawerShell({ open, onClose, title, actions, closeLabel, anchor, width, children }: DrawerShellProps): ReactElement;
|
|
304
|
+
//#endregion
|
|
305
|
+
//#region src/bulk/selection.d.ts
|
|
306
|
+
/** Which records are selected: explicit ids, or every record matching the current filters. */
|
|
307
|
+
interface BulkSelection {
|
|
308
|
+
/** Ids ticked by hand (empty while `allMatching`). */
|
|
309
|
+
readonly selected: readonly number[];
|
|
310
|
+
/** All records matching the list's filters are selected, on every page. */
|
|
311
|
+
readonly allMatching: boolean;
|
|
312
|
+
isSelected(id: number): boolean;
|
|
313
|
+
/**
|
|
314
|
+
* Ticks or unticks one record. Passing the visible page's ids lets an
|
|
315
|
+
* untick while `allMatching` keep the other visible records selected.
|
|
316
|
+
*/
|
|
317
|
+
toggle(id: number, visible?: readonly number[]): void;
|
|
318
|
+
/** Ticks or unticks every id of the visible page. */
|
|
319
|
+
setPage(ids: readonly number[], on: boolean): void;
|
|
320
|
+
selectAllMatching(): void;
|
|
321
|
+
clear(): void;
|
|
322
|
+
}
|
|
323
|
+
/** Selection state for a list. Ticking a row after "select all matching" returns to explicit ids. */
|
|
324
|
+
export declare function useBulkSelection(): BulkSelection;
|
|
325
|
+
//#endregion
|
|
326
|
+
//#region src/bulk/BulkToolbar.d.ts
|
|
327
|
+
type BulkAction = "delete" | "export" | "publish";
|
|
328
|
+
interface BulkDone {
|
|
329
|
+
readonly action: BulkAction;
|
|
330
|
+
/** Records the call touched. */
|
|
331
|
+
readonly count: number;
|
|
332
|
+
}
|
|
333
|
+
interface BulkToolbarProps {
|
|
334
|
+
readonly ready: ReadyResource;
|
|
335
|
+
readonly selection: BulkSelection;
|
|
336
|
+
/** The list's current filters. "Select all matching" needs at least one. */
|
|
337
|
+
readonly filters?: FieldFilters | undefined;
|
|
338
|
+
/** Actions to offer; each also needs the matching capability. Default: all. */
|
|
339
|
+
readonly actions?: readonly BulkAction[] | undefined;
|
|
340
|
+
/** Receives the CSV of "Export"; default: a file download. */
|
|
341
|
+
readonly onExport?: ((csv: string, filename: string) => void) | undefined;
|
|
342
|
+
readonly onDone?: ((done: BulkDone) => void) | undefined;
|
|
343
|
+
}
|
|
344
|
+
/** The toolbar over a list's selection: count, bulk delete, export and bulk publish. Hidden while nothing is selected. */
|
|
345
|
+
export declare function BulkToolbar({ ready, selection, filters, actions, onExport, onDone }: BulkToolbarProps): ReactElement | null;
|
|
346
|
+
//#endregion
|
|
347
|
+
//#region src/bulk/BulkRecords.d.ts
|
|
348
|
+
interface BulkPanelProps extends Pick<BulkToolbarProps, "actions" | "onExport" | "onDone"> {
|
|
349
|
+
readonly ready: ReadyResource;
|
|
350
|
+
readonly filters?: FieldFilters | undefined;
|
|
351
|
+
/** Columns to show; default: the first four non-system fields. */
|
|
352
|
+
readonly columns?: readonly string[] | undefined;
|
|
353
|
+
/** Page size; default 25. */
|
|
354
|
+
readonly limit?: number | undefined;
|
|
355
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
356
|
+
}
|
|
357
|
+
/** A selectable table over one page of an already loaded resource, with the bulk toolbar above it. */
|
|
358
|
+
export declare function BulkPanel({ ready, filters, columns, limit, renderers, ...toolbar }: BulkPanelProps): ReactElement;
|
|
359
|
+
interface BulkRecordsProps extends Omit<BulkPanelProps, "ready"> {
|
|
360
|
+
readonly resource: string;
|
|
361
|
+
readonly apiVersion?: string | undefined;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Records with checkboxes and the bulk toolbar: selection count, bulk delete,
|
|
365
|
+
* export, bulk publish and filter-based select-all (no count preview). Bulk
|
|
366
|
+
* calls respect `bulk.max_matched`.
|
|
367
|
+
*/
|
|
368
|
+
export declare function BulkRecords({ resource, apiVersion, ...rest }: BulkRecordsProps): ReactElement;
|
|
369
|
+
//#endregion
|
|
370
|
+
//#region src/bulk/errors.d.ts
|
|
371
|
+
/** More records than the server will touch in one call (`bulk.max_matched`). */
|
|
372
|
+
export declare class BulkLimitError extends Error {
|
|
373
|
+
constructor(max: number);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* A message for a failed bulk call. The server answers `400` when a filter
|
|
377
|
+
* matches more than `bulk.max_matched` records (or the request is bad for
|
|
378
|
+
* another reason, which its own message then says).
|
|
379
|
+
*/
|
|
380
|
+
export declare function describeBulkError(error: Error, max: number): string;
|
|
381
|
+
//#endregion
|
|
382
|
+
//#region src/bulk/export.d.ts
|
|
383
|
+
/** RFC 4180 CSV: a header of field names, then one line per record. Objects and arrays become JSON. */
|
|
384
|
+
export declare function toCsv(fields: readonly FieldDescriptor[], rows: readonly JsonObject[]): string;
|
|
385
|
+
/** Offers `text` to the browser as a file download. */
|
|
386
|
+
export declare function downloadText(filename: string, text: string, type?: string): void;
|
|
387
|
+
//#endregion
|
|
388
|
+
//#region src/delete/DeleteAction.d.ts
|
|
389
|
+
/**
|
|
390
|
+
* - `immediate`: delete on click.
|
|
391
|
+
* - `confirm`: ask first, showing the record.
|
|
392
|
+
* - `undo`: hold the deletion back for `undoMs`; Undo cancels it.
|
|
393
|
+
* - `soft`: delete (the server archives the record) and offer Undo, which
|
|
394
|
+
* restores it; renders lifecycle's `ArchiveButton`, needs the `archive_restore`
|
|
395
|
+
* capability, else renders nothing.
|
|
396
|
+
*/
|
|
397
|
+
type DeleteVariant = "immediate" | "confirm" | "undo" | "soft";
|
|
398
|
+
interface DeleteActionProps {
|
|
399
|
+
readonly name: string;
|
|
400
|
+
readonly apiVersion?: string | undefined;
|
|
401
|
+
readonly id: number;
|
|
402
|
+
/** Default `"confirm"`. */
|
|
403
|
+
readonly variant?: DeleteVariant;
|
|
404
|
+
/** Button text. Default "Delete". */
|
|
405
|
+
readonly label?: string | undefined;
|
|
406
|
+
/** What one record is called in messages. Default "record". */
|
|
407
|
+
readonly recordLabel?: string | undefined;
|
|
408
|
+
/** Called once the record is deleted on the server. */
|
|
409
|
+
readonly onDeleted?: ((id: number) => void) | undefined;
|
|
410
|
+
/** Called when Undo cancelled a pending deletion or restored the record. */
|
|
411
|
+
readonly onUndone?: ((id: number) => void) | undefined;
|
|
412
|
+
/** `undo`: how long the deletion waits, in milliseconds. Default 6000. */
|
|
413
|
+
readonly undoMs?: number | undefined;
|
|
414
|
+
/** `confirm`: the fields shown. Default the first three besides `id`. */
|
|
415
|
+
readonly summaryFields?: readonly string[] | undefined;
|
|
416
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
417
|
+
}
|
|
418
|
+
/** A delete button for one record; see `DeleteActionProps`. */
|
|
419
|
+
export declare function DeleteAction(props: DeleteActionProps): ReactElement;
|
|
420
|
+
//#endregion
|
|
421
|
+
//#region src/detail/RecordDetail.d.ts
|
|
422
|
+
type DetailVariant = "page" | "form" | "metadata" | "tabs" | "dialog" | "drawer";
|
|
423
|
+
/** What `renderForm` receives: enough to mount VW2's edit form for this record. */
|
|
424
|
+
interface DetailFormContext {
|
|
425
|
+
readonly ready: ReadyResource;
|
|
426
|
+
readonly id: number;
|
|
427
|
+
readonly record: JsonObject;
|
|
428
|
+
/** Call after a save so the detail refetches. */
|
|
429
|
+
readonly onDone: () => void;
|
|
430
|
+
}
|
|
431
|
+
interface DetailPanelProps {
|
|
432
|
+
readonly ready: ReadyResource;
|
|
433
|
+
readonly id: number;
|
|
434
|
+
readonly variant?: DetailVariant | undefined;
|
|
435
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
436
|
+
/** Replaces the page title; default `<Resource title> #<id>`. */
|
|
437
|
+
readonly title?: ReactNode;
|
|
438
|
+
/**
|
|
439
|
+
* The `form` variant renders this in place of the field list, so the edit
|
|
440
|
+
* form (VW2's `RecordForm`, or your own) lives in the detail page without
|
|
441
|
+
* this package importing it.
|
|
442
|
+
*/
|
|
443
|
+
readonly renderForm?: ((context: DetailFormContext) => ReactNode) | undefined;
|
|
444
|
+
/** `dialog` and `drawer`: whether it is shown (default true). */
|
|
445
|
+
readonly open?: boolean | undefined;
|
|
446
|
+
/** `dialog` and `drawer`: called when the overlay asks to close. */
|
|
447
|
+
readonly onClose?: (() => void) | undefined;
|
|
448
|
+
/** Called after a publish, discard, archive or restore. */
|
|
449
|
+
readonly onChanged?: (() => void) | undefined;
|
|
450
|
+
}
|
|
451
|
+
interface BodyProps {
|
|
452
|
+
readonly ready: ReadyResource;
|
|
453
|
+
readonly record: JsonObject;
|
|
454
|
+
readonly renderers: RendererOverrides | undefined;
|
|
455
|
+
}
|
|
456
|
+
/** The server-maintained fields: ids, owner, lifecycle and audit timestamps. */
|
|
457
|
+
export declare function DetailMetadata({ ready, record, renderers }: BodyProps): ReactElement;
|
|
458
|
+
/** One record of an already loaded resource, in the chosen `variant` (default `page`). */
|
|
459
|
+
export declare function DetailPanel({ variant, open, ...rest }: DetailPanelProps): ReactElement;
|
|
460
|
+
interface RecordDetailProps extends Omit<DetailPanelProps, "ready"> {
|
|
461
|
+
readonly resource: string;
|
|
462
|
+
readonly apiVersion?: string | undefined;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* The detail of one record: `page` (read-only fields), `form` (an edit form
|
|
466
|
+
* from `renderForm`), `metadata` (fields beside a metadata panel), `tabs`,
|
|
467
|
+
* `dialog` or `drawer`. Status, publish, discard, archive and restore actions
|
|
468
|
+
* show only when the manifest's `capabilities` allow them.
|
|
469
|
+
*/
|
|
470
|
+
export declare function RecordDetail({ resource, apiVersion, ...rest }: RecordDetailProps): ReactElement;
|
|
471
|
+
//#endregion
|
|
472
|
+
//#region src/detail/FieldList.d.ts
|
|
473
|
+
interface FieldListProps {
|
|
474
|
+
readonly resource: string;
|
|
475
|
+
readonly fields: readonly FieldDescriptor[];
|
|
476
|
+
readonly record: JsonObject;
|
|
477
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
478
|
+
}
|
|
479
|
+
/** A label and value for each field, as a description list. */
|
|
480
|
+
export declare function FieldList({ resource, fields, record, renderers }: FieldListProps): ReactElement;
|
|
481
|
+
//#endregion
|
|
482
|
+
//#region src/filter/FacetSidebar.d.ts
|
|
483
|
+
interface FacetSidebarProps {
|
|
484
|
+
readonly ready: ReadyResource;
|
|
485
|
+
readonly filters: FieldFilters;
|
|
486
|
+
readonly onChange: (filters: FieldFilters) => void;
|
|
487
|
+
/** Field names to show. Default: every categorical field with known values. */
|
|
488
|
+
readonly fields?: readonly string[] | undefined;
|
|
489
|
+
}
|
|
490
|
+
/** Checkboxes for the categorical fields: pick values, the list narrows to them. */
|
|
491
|
+
export declare function FacetSidebar({ ready, filters, onChange, fields }: FacetSidebarProps): ReactElement | null;
|
|
492
|
+
//#endregion
|
|
493
|
+
//#region src/filter/FilterBar.d.ts
|
|
494
|
+
interface FilterBarProps {
|
|
495
|
+
readonly ready: ReadyResource;
|
|
496
|
+
readonly filters: FieldFilters;
|
|
497
|
+
readonly onChange: (filters: FieldFilters) => void;
|
|
498
|
+
/** Field names to show, in order. Default: every filterable field except the id. */
|
|
499
|
+
readonly fields?: readonly string[] | undefined;
|
|
500
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
501
|
+
}
|
|
502
|
+
/** One filter control per field, side by side: the filters are all visible at once. */
|
|
503
|
+
export declare function FilterBar({ ready, filters, onChange, fields, renderers }: FilterBarProps): ReactElement;
|
|
504
|
+
//#endregion
|
|
505
|
+
//#region src/filter/FilterBuilder.d.ts
|
|
506
|
+
interface FilterBuilderProps {
|
|
507
|
+
readonly ready: ReadyResource;
|
|
508
|
+
readonly filters: FieldFilters;
|
|
509
|
+
readonly onChange: (filters: FieldFilters) => void;
|
|
510
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* A list of conditions, each "field, operator, operand". Operands use the
|
|
514
|
+
* field's filter renderer where it edits that operator, a text box otherwise.
|
|
515
|
+
* Several conditions on one field combine as the API does: all must hold.
|
|
516
|
+
*/
|
|
517
|
+
export declare function FilterBuilder({ ready, filters, onChange, renderers }: FilterBuilderProps): ReactElement;
|
|
518
|
+
//#endregion
|
|
519
|
+
//#region src/filter/FilterControl.d.ts
|
|
520
|
+
interface FilterControlProps {
|
|
521
|
+
readonly field: FieldDescriptor;
|
|
522
|
+
readonly resource: string;
|
|
523
|
+
readonly value: FieldFilter | undefined;
|
|
524
|
+
readonly onChange: (value: FieldFilter | undefined) => void;
|
|
525
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
526
|
+
}
|
|
527
|
+
/** The filter renderer of one field. A datetime filter says its operands are UTC. */
|
|
528
|
+
export declare function FilterControl({ field, resource, value, onChange, renderers }: FilterControlProps): ReactElement;
|
|
529
|
+
//#endregion
|
|
530
|
+
//#region src/filter/QuickSearch.d.ts
|
|
531
|
+
interface QuickSearchProps {
|
|
532
|
+
/** The string fields to search (`icontains`); see `QueryStateApi.searchFields`. */
|
|
533
|
+
readonly fields: readonly FieldDescriptor[];
|
|
534
|
+
readonly value: string;
|
|
535
|
+
/** The searched field; with several, a selector appears (the API cannot OR fields). */
|
|
536
|
+
readonly field: string | undefined;
|
|
537
|
+
readonly onChange: (value: string) => void;
|
|
538
|
+
readonly onFieldChange: (field: string) => void;
|
|
539
|
+
/** Wait this long after the last keystroke before calling `onChange`. Default 300. */
|
|
540
|
+
readonly debounceMs?: number | undefined;
|
|
541
|
+
}
|
|
542
|
+
/** A search box: case-insensitive "contains" on one string field. Renders nothing without one. */
|
|
543
|
+
export declare function QuickSearch({ fields, value, field, onChange, onFieldChange, debounceMs }: QuickSearchProps): ReactElement | null;
|
|
544
|
+
//#endregion
|
|
545
|
+
//#region src/filter/queryState.d.ts
|
|
546
|
+
/** One sort key: a sortable field and its direction. */
|
|
547
|
+
interface SortKey {
|
|
548
|
+
readonly field: string;
|
|
549
|
+
readonly desc: boolean;
|
|
550
|
+
}
|
|
551
|
+
/** Everything a list view reads: filters, quick search, sort, paging and the visibility toggles. */
|
|
552
|
+
interface QueryState {
|
|
553
|
+
readonly filters: FieldFilters;
|
|
554
|
+
/** Quick-search text (`icontains` on `qField`); empty means off. */
|
|
555
|
+
readonly q: string;
|
|
556
|
+
readonly qField: string | undefined;
|
|
557
|
+
readonly sort: readonly SortKey[];
|
|
558
|
+
/** 1-based. */
|
|
559
|
+
readonly page: number;
|
|
560
|
+
readonly pageSize: number;
|
|
561
|
+
readonly includeArchived: boolean;
|
|
562
|
+
readonly includeUnpublished: boolean;
|
|
563
|
+
}
|
|
564
|
+
/** Values the state falls back to while the URL says nothing. */
|
|
565
|
+
interface QueryDefaults {
|
|
566
|
+
/** Default filter values; the user clears them and the URL remembers that. */
|
|
567
|
+
readonly filters?: FieldFilters | undefined;
|
|
568
|
+
readonly sort?: readonly SortKey[] | undefined;
|
|
569
|
+
readonly pageSize?: number | undefined;
|
|
570
|
+
}
|
|
571
|
+
/** What the codecs need to know about the resource. */
|
|
572
|
+
interface QueryContext {
|
|
573
|
+
readonly fields: readonly FieldDescriptor[];
|
|
574
|
+
readonly defaults: QueryDefaults;
|
|
575
|
+
/** Prefix of every URL parameter, so several lists can share one page. */
|
|
576
|
+
readonly prefix: string;
|
|
577
|
+
/** Default quick-search field, from the `searchField` option or the first searchable one. */
|
|
578
|
+
readonly searchField: string | undefined;
|
|
579
|
+
/** The largest page size the server accepts, less one (the view asks for one extra row to learn whether a next page exists). */
|
|
580
|
+
readonly maxPageSize: number;
|
|
581
|
+
}
|
|
582
|
+
export declare const DEFAULT_PAGE_SIZE = 25;
|
|
583
|
+
/** Fields the quick search can target: strings with `icontains`. */
|
|
584
|
+
export declare const searchableFields: (fields: readonly FieldDescriptor[]) => FieldDescriptor[];
|
|
585
|
+
/** The sort a header click or dropdown can use. */
|
|
586
|
+
export declare const sortableFields: (fields: readonly FieldDescriptor[]) => FieldDescriptor[];
|
|
587
|
+
/** The state with nothing in the URL. */
|
|
588
|
+
export declare function initialState(ctx: QueryContext): QueryState;
|
|
589
|
+
/** Reads typed text as the operand of `op` on `field` (`in` takes a comma-separated list); `undefined` when it does not parse. */
|
|
590
|
+
export declare function parseOperand(field: FieldDescriptor, op: FilterOp, text: string): FilterScalar | readonly FilterScalar[] | undefined;
|
|
591
|
+
/** The text form of an operand: the inverse of `parseOperand`. */
|
|
592
|
+
export declare function formatOperand(operand: FilterScalar | readonly FilterScalar[]): string;
|
|
593
|
+
/**
|
|
594
|
+
* The query string for `state`, merged into `base` (other parameters of the
|
|
595
|
+
* page survive). Values equal to the defaults are left out; a filter set that
|
|
596
|
+
* differs from the defaults is written with an `f` marker, so clearing a
|
|
597
|
+
* default filter sticks.
|
|
598
|
+
*/
|
|
599
|
+
export declare function encodeState(state: QueryState, ctx: QueryContext, base?: string): string;
|
|
600
|
+
/** The state a query string describes; anything invalid for the resource is ignored. */
|
|
601
|
+
export declare function decodeState(search: string, ctx: QueryContext): QueryState;
|
|
602
|
+
/** The filters including the quick search, as per-field state. */
|
|
603
|
+
export declare function effectiveFilters(state: QueryState): FieldFilters;
|
|
604
|
+
/**
|
|
605
|
+
* The SDK query for `state`. `paged` adds `skip` and `limit` (one extra row,
|
|
606
|
+
* to learn whether a next page exists); an infinite list pages itself.
|
|
607
|
+
*/
|
|
608
|
+
export declare function toCrudQuery(state: QueryState, paged: boolean): CrudQuery;
|
|
609
|
+
/** Whether any filter or quick search narrows the list. */
|
|
610
|
+
export declare const isFiltered: (state: QueryState) => boolean;
|
|
611
|
+
//#endregion
|
|
612
|
+
//#region src/filter/urlAdapter.d.ts
|
|
613
|
+
/** Reads and writes the query string (no leading `?`) the list state is kept in. */
|
|
614
|
+
interface UrlAdapter {
|
|
615
|
+
/** The current query string. */
|
|
616
|
+
read(): string;
|
|
617
|
+
/** Replaces the query string; `push` adds a history entry, `replace` does not. */
|
|
618
|
+
write(search: string, mode: "push" | "replace"): void;
|
|
619
|
+
/** Calls `listener` whenever the query string changes, from anywhere; returns the unsubscribe. */
|
|
620
|
+
subscribe(listener: () => void): () => void;
|
|
621
|
+
}
|
|
622
|
+
/** An in-memory adapter: tests, stories, and embedded lists that must not touch the address bar. */
|
|
623
|
+
export declare function memoryUrlAdapter(initial?: string): UrlAdapter;
|
|
624
|
+
/** The default adapter: `window.location` and `history` (back and forward work). */
|
|
625
|
+
export declare function windowUrlAdapter(): UrlAdapter;
|
|
626
|
+
/** The process-wide window adapter, so every list on a page shares one listener set. */
|
|
627
|
+
export declare function defaultUrlAdapter(): UrlAdapter;
|
|
628
|
+
//#endregion
|
|
629
|
+
//#region src/filter/useQueryState.d.ts
|
|
630
|
+
interface QueryStateOptions {
|
|
631
|
+
/** Where the state lives. Default: the window's query string. */
|
|
632
|
+
readonly adapter?: UrlAdapter | undefined;
|
|
633
|
+
/** Prefix of this list's URL parameters; give each list on a page its own. */
|
|
634
|
+
readonly prefix?: string | undefined;
|
|
635
|
+
readonly defaults?: QueryDefaults | undefined;
|
|
636
|
+
/** The field the quick search targets first. Default: the first string field with `icontains`. */
|
|
637
|
+
readonly searchField?: string | undefined;
|
|
638
|
+
}
|
|
639
|
+
/** The URL-synced state of one list plus the setters and the SDK queries derived from it. */
|
|
640
|
+
interface QueryStateApi {
|
|
641
|
+
readonly state: QueryState;
|
|
642
|
+
readonly fields: readonly FieldDescriptor[];
|
|
643
|
+
/** Fields the quick search can target. */
|
|
644
|
+
readonly searchFields: readonly FieldDescriptor[];
|
|
645
|
+
/** The query of a paged view: `skip` and `limit` (page size + 1, to detect a next page). */
|
|
646
|
+
readonly pagedQuery: CrudQuery;
|
|
647
|
+
/** The query of an infinite view: filters and sort only. */
|
|
648
|
+
readonly feedQuery: CrudQuery;
|
|
649
|
+
/** Any change but the page itself returns to page 1. */
|
|
650
|
+
setFilters(filters: FieldFilters): void;
|
|
651
|
+
setQuickSearch(q: string): void;
|
|
652
|
+
setQuickSearchField(field: string): void;
|
|
653
|
+
setSort(sort: readonly SortKey[]): void;
|
|
654
|
+
setPage(page: number): void;
|
|
655
|
+
setPageSize(pageSize: number): void;
|
|
656
|
+
setIncludeArchived(on: boolean): void;
|
|
657
|
+
setIncludeUnpublished(on: boolean): void;
|
|
658
|
+
/** Back to the defaults. */
|
|
659
|
+
reset(): void;
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Filter, sort and paging state for `ready`, kept in the URL through the
|
|
663
|
+
* adapter. Operands are validated against the manifest, so a stale or
|
|
664
|
+
* hand-edited link degrades to the defaults instead of failing the request.
|
|
665
|
+
*/
|
|
666
|
+
export declare function useQueryState(ready: ReadyResource, options?: QueryStateOptions): QueryStateApi;
|
|
667
|
+
//#endregion
|
|
668
|
+
//#region src/form/sections.d.ts
|
|
669
|
+
/** A titled group of fields, by field name. */
|
|
670
|
+
interface FormSection {
|
|
671
|
+
readonly title: string;
|
|
672
|
+
readonly fields: readonly string[];
|
|
673
|
+
}
|
|
674
|
+
type FormLayoutKind = "flat" | "sections" | "tabs" | "stepper";
|
|
675
|
+
/**
|
|
676
|
+
* The sections of a form. Given `sections`, fields they do not name go to a
|
|
677
|
+
* trailing "Other" section; without them, required fields come first under
|
|
678
|
+
* "Required", the rest under "Optional". Empty sections are dropped.
|
|
679
|
+
*/
|
|
680
|
+
export declare function groupFields(fields: readonly FieldDescriptor[], sections: readonly FormSection[] | undefined): readonly FormSection[];
|
|
681
|
+
//#endregion
|
|
682
|
+
//#region src/form/ResourceForm.d.ts
|
|
683
|
+
type Row$2 = Readonly<Record<string, FieldValue>>;
|
|
684
|
+
interface ResourceFormProps {
|
|
685
|
+
/** The manifest resource name. */
|
|
686
|
+
readonly name: string;
|
|
687
|
+
readonly apiVersion?: string | undefined;
|
|
688
|
+
/** Edit this record; without it the form creates one. */
|
|
689
|
+
readonly id?: number | undefined;
|
|
690
|
+
/** Where the form renders. Default `"page"`. */
|
|
691
|
+
readonly presentation?: "page" | "dialog" | "drawer";
|
|
692
|
+
/** Dialog and drawer: whether it shows (a closed one renders nothing). */
|
|
693
|
+
readonly open?: boolean | undefined;
|
|
694
|
+
readonly onClose?: (() => void) | undefined;
|
|
695
|
+
/** How fields are arranged. Default `"flat"`. */
|
|
696
|
+
readonly layout?: FormLayoutKind;
|
|
697
|
+
/** Titled groups of field names for `sections`, `tabs` and `stepper`; default Required and Optional. */
|
|
698
|
+
readonly sections?: readonly FormSection[] | undefined;
|
|
699
|
+
/** Only these fields (in the resource's order). Default every writable field. */
|
|
700
|
+
readonly fields?: readonly string[] | undefined;
|
|
701
|
+
/** Create: starting values. */
|
|
702
|
+
readonly initial?: Row$2 | undefined;
|
|
703
|
+
/** Edit: save by itself after a pause in typing, while the form is valid. */
|
|
704
|
+
readonly autoSave?: boolean | undefined;
|
|
705
|
+
/** Pause before an auto-save, in milliseconds. Default 1000. */
|
|
706
|
+
readonly autoSaveDelayMs?: number | undefined;
|
|
707
|
+
/**
|
|
708
|
+
* The record's current ETag, sent as `If-Match` on every save (edit only,
|
|
709
|
+
* when the resource has `conditional_requests`). Called before each save,
|
|
710
|
+
* because a save changes the ETag. Without it no header is sent by the form
|
|
711
|
+
* (the SDK cache's `autoIfMatch` can still add one).
|
|
712
|
+
*/
|
|
713
|
+
readonly etag?: ((id: number) => string | undefined | Promise<string | undefined>) | undefined;
|
|
714
|
+
readonly onSaved?: ((record: JsonObject) => void) | undefined;
|
|
715
|
+
/** Heading override. Default "New <recordLabel>" or "Edit <recordLabel> <id>". */
|
|
716
|
+
readonly title?: ReactNode;
|
|
717
|
+
/** What one record is called in titles. Default "record". */
|
|
718
|
+
readonly recordLabel?: string | undefined;
|
|
719
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
720
|
+
}
|
|
721
|
+
/** A create or edit form for a resource; see `ResourceFormProps`. */
|
|
722
|
+
export declare function ResourceForm(props: ResourceFormProps): ReactElement | null;
|
|
723
|
+
//#endregion
|
|
724
|
+
//#region src/form/problem.d.ts
|
|
725
|
+
/** What a failed save shows. */
|
|
726
|
+
interface SaveFailure {
|
|
727
|
+
/** 412: the record changed since it was loaded. */
|
|
728
|
+
readonly conflict: boolean;
|
|
729
|
+
/** Messages by field name, from 422 `errors`. */
|
|
730
|
+
readonly fieldErrors: Readonly<Record<string, string>>;
|
|
731
|
+
/** Text for an alert: everything not tied to a visible field. */
|
|
732
|
+
readonly message: string | null;
|
|
733
|
+
}
|
|
734
|
+
/** Splits a mutation error into field messages, a conflict flag and an alert message. */
|
|
735
|
+
export declare function describeFailure(error: unknown, fieldNames: readonly string[]): SaveFailure;
|
|
736
|
+
//#endregion
|
|
737
|
+
//#region src/form/validate.d.ts
|
|
738
|
+
/**
|
|
739
|
+
* The message for the first schema constraint `value` breaks, or `null`.
|
|
740
|
+
* A missing value breaks only `required`; booleans are never missing.
|
|
741
|
+
*/
|
|
742
|
+
export declare function validateValue(field: FieldDescriptor, value: FieldValue): string | null;
|
|
743
|
+
/** Errors by field name for every field whose value breaks a constraint. */
|
|
744
|
+
export declare function validateAll(fields: readonly FieldDescriptor[], values: Readonly<Record<string, FieldValue>>): Record<string, string>;
|
|
745
|
+
//#endregion
|
|
746
|
+
//#region src/lifecycle/DraftControls.d.ts
|
|
747
|
+
interface StatusBadgeProps {
|
|
748
|
+
readonly ready: ReadyResource;
|
|
749
|
+
readonly record: JsonObject;
|
|
750
|
+
}
|
|
751
|
+
/** A chip with the record's state. Hidden unless the resource has drafts or an archive. */
|
|
752
|
+
export declare function StatusBadge({ ready, record }: StatusBadgeProps): ReactElement | null;
|
|
753
|
+
interface RecordActionProps {
|
|
754
|
+
readonly ready: ReadyResource;
|
|
755
|
+
readonly id: number;
|
|
756
|
+
/** Called after the server accepted the change. */
|
|
757
|
+
readonly onDone?: (() => void) | undefined;
|
|
758
|
+
}
|
|
759
|
+
/** Publishes a draft. Hidden unless `capabilities.draft_publish`. */
|
|
760
|
+
export declare function PublishButton({ ready, id, onDone }: RecordActionProps): ReactElement | null;
|
|
761
|
+
/** Discards a draft after a confirmation (a draft has no published state to fall back to, so it is deleted). */
|
|
762
|
+
export declare function DiscardDraftButton({ ready, id, onDone }: RecordActionProps): ReactElement | null;
|
|
763
|
+
interface DraftControlsProps {
|
|
764
|
+
readonly ready: ReadyResource;
|
|
765
|
+
readonly record: JsonObject;
|
|
766
|
+
readonly id: number;
|
|
767
|
+
/** Called after a publish or a discard. */
|
|
768
|
+
readonly onChanged?: (() => void) | undefined;
|
|
769
|
+
}
|
|
770
|
+
/** Status badge plus, for a draft, Publish and Discard draft. Hidden without `draft_publish`. */
|
|
771
|
+
export declare function DraftControls({ ready, record, id, onChanged }: DraftControlsProps): ReactElement | null;
|
|
772
|
+
//#endregion
|
|
773
|
+
//#region src/lifecycle/ArchiveControls.d.ts
|
|
774
|
+
interface ArchivedToggleProps {
|
|
775
|
+
readonly ready: ReadyResource;
|
|
776
|
+
/** Maps to the list query's `includeArchived`. */
|
|
777
|
+
readonly checked: boolean;
|
|
778
|
+
readonly onChange: (checked: boolean) => void;
|
|
779
|
+
}
|
|
780
|
+
/** "Show archived" switch. Hidden unless `capabilities.archive_restore`. */
|
|
781
|
+
export declare function ArchivedToggle({ ready, checked, onChange }: ArchivedToggleProps): ReactElement | null;
|
|
782
|
+
/**
|
|
783
|
+
* Archives a record (the server's delete is a soft delete when it has an
|
|
784
|
+
* archive) and offers Undo, which restores it. Hidden without `archive_restore`.
|
|
785
|
+
*/
|
|
786
|
+
export declare function ArchiveButton({ ready, id, onDone, onArchived, onUndone, label, ariaLabel, archived }: RecordActionProps & {
|
|
787
|
+
/** Button text. Default "Archive". */
|
|
788
|
+
readonly label?: string | undefined;
|
|
789
|
+
/** Accessible name when the text alone is ambiguous, e.g. "Delete hero 1". */
|
|
790
|
+
readonly ariaLabel?: string | undefined;
|
|
791
|
+
/** Called once the record is archived (`onDone` also runs, as after an undo). */
|
|
792
|
+
readonly onArchived?: (() => void) | undefined;
|
|
793
|
+
/** Called once Undo restored the record. */
|
|
794
|
+
readonly onUndone?: (() => void) | undefined;
|
|
795
|
+
/** The record is archived already: the button hides, an Undo toast can still show. */
|
|
796
|
+
readonly archived?: boolean;
|
|
797
|
+
}): ReactElement | null;
|
|
798
|
+
/** Restores an archived record. Hidden without `archive_restore`. */
|
|
799
|
+
export declare function RestoreButton({ ready, id, onDone }: RecordActionProps): ReactElement | null;
|
|
800
|
+
//#endregion
|
|
801
|
+
//#region src/lifecycle/ConfirmDialog.d.ts
|
|
802
|
+
interface ConfirmDialogProps {
|
|
803
|
+
readonly open: boolean;
|
|
804
|
+
readonly title: string;
|
|
805
|
+
readonly children: ReactNode;
|
|
806
|
+
readonly confirmLabel: string;
|
|
807
|
+
readonly busy?: boolean;
|
|
808
|
+
readonly onConfirm: () => void;
|
|
809
|
+
readonly onClose: () => void;
|
|
810
|
+
}
|
|
811
|
+
/** A small confirmation built on `DialogShell`: Cancel and one destructive action. */
|
|
812
|
+
export declare function ConfirmDialog({ open, title, children, confirmLabel, busy, onConfirm, onClose }: ConfirmDialogProps): ReactElement;
|
|
813
|
+
//#endregion
|
|
814
|
+
//#region src/lifecycle/mutations.d.ts
|
|
815
|
+
/**
|
|
816
|
+
* Refreshes every cached query of one resource (all API versions), for the
|
|
817
|
+
* calls the core's hooks do not cover: publish, restore and bulk.
|
|
818
|
+
*/
|
|
819
|
+
export declare function useInvalidateResource(name: string): () => Promise<void>;
|
|
820
|
+
/** `POST publish?id=`: turns a draft into a published record. */
|
|
821
|
+
export declare function usePublish(ready: ReadyResource): UseMutationResult<JsonObject, Error, number>;
|
|
822
|
+
/** `POST restore?id=`: brings an archived record back. */
|
|
823
|
+
export declare function useRestore(ready: ReadyResource): UseMutationResult<BulkResult, Error, number>;
|
|
824
|
+
//#endregion
|
|
825
|
+
//#region src/lifecycle/status.d.ts
|
|
826
|
+
type RecordStatus = "published" | "draft" | "archived";
|
|
827
|
+
/** Fields the server maintains (lifecycle and audit); the detail view shows them in its metadata panel. */
|
|
828
|
+
export declare const SYSTEM_FIELDS: readonly string[];
|
|
829
|
+
/** `archived` wins over `draft`; a record with neither marker is `published`. */
|
|
830
|
+
export declare function recordStatus(record: JsonObject): RecordStatus;
|
|
831
|
+
type StatusFilterValue = "published" | "draft" | "all";
|
|
832
|
+
/** What a list query needs for a status choice: spread into `useList`'s query. */
|
|
833
|
+
interface StatusQuery {
|
|
834
|
+
readonly includeUnpublished: boolean;
|
|
835
|
+
readonly filters: Readonly<Record<string, unknown>>;
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* The list query for a status choice. The server hides drafts unless
|
|
839
|
+
* `include_unpublished` is set; `draft` also filters on `is_draft`.
|
|
840
|
+
*/
|
|
841
|
+
export declare function statusQuery(value: StatusFilterValue): StatusQuery;
|
|
842
|
+
//#endregion
|
|
843
|
+
//#region src/lifecycle/StatusFilter.d.ts
|
|
844
|
+
interface StatusFilterProps {
|
|
845
|
+
readonly ready: ReadyResource;
|
|
846
|
+
readonly value: StatusFilterValue;
|
|
847
|
+
readonly onChange: (value: StatusFilterValue) => void;
|
|
848
|
+
}
|
|
849
|
+
/** Published / Draft / All. Hidden unless `capabilities.draft_publish`. */
|
|
850
|
+
export declare function StatusFilter({ ready, value, onChange }: StatusFilterProps): ReactElement | null;
|
|
851
|
+
//#endregion
|
|
852
|
+
//#region src/lifecycle/TrashList.d.ts
|
|
853
|
+
interface TrashPanelProps {
|
|
854
|
+
readonly ready: ReadyResource;
|
|
855
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
856
|
+
/** Columns to show; default: the first three non-system fields. */
|
|
857
|
+
readonly columns?: readonly string[] | undefined;
|
|
858
|
+
/** Called after a record was restored. */
|
|
859
|
+
readonly onRestored?: ((id: number) => void) | undefined;
|
|
860
|
+
}
|
|
861
|
+
/** The archived records of an already loaded resource, each with Restore. Hidden without `archive_restore`. */
|
|
862
|
+
export declare function TrashPanel(props: TrashPanelProps): ReactElement | null;
|
|
863
|
+
interface TrashListProps extends Omit<TrashPanelProps, "ready"> {
|
|
864
|
+
readonly resource: string;
|
|
865
|
+
readonly apiVersion?: string | undefined;
|
|
866
|
+
}
|
|
867
|
+
/** The trash: archived records with Restore. Renders nothing for a resource without an archive. */
|
|
868
|
+
export declare function TrashList({ resource, apiVersion, ...rest }: TrashListProps): ReactElement;
|
|
869
|
+
//#endregion
|
|
870
|
+
//#region src/list/columns.d.ts
|
|
871
|
+
/** A column: a field name, or a name with a header and a size. */
|
|
872
|
+
type ColumnSpec = string | {
|
|
873
|
+
readonly field: string;
|
|
874
|
+
/** Header text. Default: the field's label. */
|
|
875
|
+
readonly header?: string | undefined;
|
|
876
|
+
/** Width in pixels (a number) for the table. */
|
|
877
|
+
readonly width?: number | undefined;
|
|
878
|
+
};
|
|
879
|
+
/** A resolved column. */
|
|
880
|
+
interface Column {
|
|
881
|
+
readonly field: FieldDescriptor;
|
|
882
|
+
readonly header: string;
|
|
883
|
+
readonly width: number | undefined;
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* The columns to show. Default: every described field except JSON ones.
|
|
887
|
+
* Names the resource does not have are skipped.
|
|
888
|
+
*/
|
|
889
|
+
export declare function resolveColumns(ready: ReadyResource, columns?: readonly ColumnSpec[]): Column[];
|
|
890
|
+
//#endregion
|
|
891
|
+
//#region src/list/RecordCard.d.ts
|
|
892
|
+
type Row = Readonly<Record<string, FieldValue>>;
|
|
893
|
+
interface RecordCardProps {
|
|
894
|
+
readonly ready: ReadyResource;
|
|
895
|
+
readonly row: Row;
|
|
896
|
+
readonly columns?: readonly ColumnSpec[] | undefined;
|
|
897
|
+
/** The field shown as the card's heading. Default: the first column. */
|
|
898
|
+
readonly titleField?: string | undefined;
|
|
899
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
900
|
+
readonly onClick?: ((row: Row) => void) | undefined;
|
|
901
|
+
}
|
|
902
|
+
/** One record as a card: a heading and a label/value pair per other column. */
|
|
903
|
+
export declare function RecordCard({ ready, row, columns, titleField, renderers, onClick }: RecordCardProps): ReactElement;
|
|
904
|
+
//#endregion
|
|
905
|
+
//#region src/list/CardGridList.d.ts
|
|
906
|
+
interface CardGridListProps {
|
|
907
|
+
readonly ready: ReadyResource;
|
|
908
|
+
readonly state: QueryStateApi;
|
|
909
|
+
readonly columns?: readonly ColumnSpec[] | undefined;
|
|
910
|
+
readonly titleField?: string | undefined;
|
|
911
|
+
readonly onRowClick?: ((row: Row) => void) | undefined;
|
|
912
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
913
|
+
}
|
|
914
|
+
/** A page of cards in a responsive grid, with Previous and Next (the server reports no total). */
|
|
915
|
+
export declare function CardGridList({ ready, state, columns, titleField, onRowClick, renderers }: CardGridListProps): ReactElement;
|
|
916
|
+
//#endregion
|
|
917
|
+
//#region src/list/CardList.d.ts
|
|
918
|
+
interface CardListProps {
|
|
919
|
+
readonly ready: ReadyResource;
|
|
920
|
+
readonly rows: readonly Row[];
|
|
921
|
+
readonly columns?: readonly ColumnSpec[] | undefined;
|
|
922
|
+
readonly titleField?: string | undefined;
|
|
923
|
+
/** `list`: one card per row; `grid`: as many as fit. */
|
|
924
|
+
readonly layout: "list" | "grid";
|
|
925
|
+
readonly onRowClick?: ((row: Row) => void) | undefined;
|
|
926
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
927
|
+
}
|
|
928
|
+
/** The cards of the card views (and their empty state). */
|
|
929
|
+
export declare function CardList({ ready, rows, columns, titleField, layout, onRowClick, renderers }: CardListProps): ReactElement;
|
|
930
|
+
//#endregion
|
|
931
|
+
//#region src/list/ColumnsMenu.d.ts
|
|
932
|
+
interface ColumnsMenuProps {
|
|
933
|
+
readonly columns: readonly Column[];
|
|
934
|
+
/** Field names currently hidden. */
|
|
935
|
+
readonly hidden: ReadonlySet<string>;
|
|
936
|
+
readonly onChange: (hidden: ReadonlySet<string>) => void;
|
|
937
|
+
}
|
|
938
|
+
/** A button that opens a checklist of the columns, to show or hide each. */
|
|
939
|
+
export declare function ColumnsMenu({ columns, hidden, onChange }: ColumnsMenuProps): ReactElement;
|
|
940
|
+
//#endregion
|
|
941
|
+
//#region src/list/DataTableList.d.ts
|
|
942
|
+
type Row$1 = Readonly<Record<string, FieldValue>>;
|
|
943
|
+
/** DataGrid props a caller may pass through (not the ones this view controls). */
|
|
944
|
+
type GridOptions = Partial<Omit<DataGridProps, "onRowClick" | "rows" | "columns">>;
|
|
945
|
+
interface DataTableListProps {
|
|
946
|
+
readonly ready: ReadyResource;
|
|
947
|
+
/** Filter, sort and paging state; see `useQueryState`. */
|
|
948
|
+
readonly state: QueryStateApi;
|
|
949
|
+
/** Columns in order. Default: every field but JSON ones. */
|
|
950
|
+
readonly columns?: readonly ColumnSpec[] | undefined;
|
|
951
|
+
/** Show only columns the server can sort by. */
|
|
952
|
+
readonly sortableOnly?: boolean | undefined;
|
|
953
|
+
/** Let the user hide columns (a "Columns" button). Default true. */
|
|
954
|
+
readonly configurableColumns?: boolean | undefined;
|
|
955
|
+
/** Edit cells in place (double-click or Enter; Enter saves, Escape cancels). Read-only fields stay read-only. */
|
|
956
|
+
readonly editable?: boolean | undefined;
|
|
957
|
+
/**
|
|
958
|
+
* The ETag of a row, sent as `If-Match` on an inline edit (a stale one fails
|
|
959
|
+
* with 412 and the view reloads the row). The list endpoint returns no ETags,
|
|
960
|
+
* so the app supplies them (for example from its SDK cache); without this
|
|
961
|
+
* prop the edit is unconditional.
|
|
962
|
+
*/
|
|
963
|
+
readonly ifMatch?: ((row: Row$1) => string | undefined) | undefined;
|
|
964
|
+
readonly pageSizeOptions?: readonly number[] | undefined;
|
|
965
|
+
readonly onRowClick?: ((row: Row$1) => void) | undefined;
|
|
966
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
967
|
+
/** Passed to the DataGrid last (a way to reach options this view does not expose). */
|
|
968
|
+
readonly gridProps?: GridOptions | undefined;
|
|
969
|
+
}
|
|
970
|
+
/** A paged data table (MUI X DataGrid): server-side sort and paging, optional inline editing. */
|
|
971
|
+
export declare function DataTableList({ ready, state, columns, sortableOnly, configurableColumns, editable, ifMatch, pageSizeOptions, onRowClick, renderers, gridProps }: DataTableListProps): ReactElement;
|
|
972
|
+
//#endregion
|
|
973
|
+
//#region src/list/LoadMoreList.d.ts
|
|
974
|
+
interface LoadMoreListProps {
|
|
975
|
+
readonly ready: ReadyResource;
|
|
976
|
+
readonly state: QueryStateApi;
|
|
977
|
+
readonly columns?: readonly ColumnSpec[] | undefined;
|
|
978
|
+
readonly titleField?: string | undefined;
|
|
979
|
+
/** `list`: one card per row; `grid`: cards side by side. Default `list`. */
|
|
980
|
+
readonly layout?: "list" | "grid" | undefined;
|
|
981
|
+
readonly onRowClick?: ((row: Row) => void) | undefined;
|
|
982
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
983
|
+
}
|
|
984
|
+
/** A growing list: the first page, then "Load more" appends the next (`useInfiniteList`). The page number is not used. */
|
|
985
|
+
export declare function LoadMoreList({ ready, state, columns, titleField, layout, onRowClick, renderers }: LoadMoreListProps): ReactElement;
|
|
986
|
+
//#endregion
|
|
987
|
+
//#region src/list/ResourceList.d.ts
|
|
988
|
+
/** `table`: paged data table; `loadMore`: growing list; `cards`: paged card grid. */
|
|
989
|
+
type ListVariant = "table" | "loadMore" | "cards";
|
|
990
|
+
/** `quick`: search box; `bar`: a control per field; `builder`: field/operator/operand rows; `facets`: checkboxes for categorical fields. */
|
|
991
|
+
type FilterVariant = "quick" | "bar" | "builder" | "facets";
|
|
992
|
+
interface ResourceListProps {
|
|
993
|
+
readonly resource: string;
|
|
994
|
+
readonly apiVersion?: string | undefined;
|
|
995
|
+
readonly variant?: ListVariant | undefined;
|
|
996
|
+
/** Which filter UIs to show, in addition to default filter values. Default `["quick"]`. */
|
|
997
|
+
readonly filters?: readonly FilterVariant[] | undefined;
|
|
998
|
+
/** Fields of the filter bar, in order. Default: all filterable fields. */
|
|
999
|
+
readonly barFields?: readonly string[] | undefined;
|
|
1000
|
+
/** Fields of the facet sidebar. Default: all categorical fields. */
|
|
1001
|
+
readonly facetFields?: readonly string[] | undefined;
|
|
1002
|
+
readonly columns?: readonly ColumnSpec[] | undefined;
|
|
1003
|
+
readonly titleField?: string | undefined;
|
|
1004
|
+
/** Table only: edit cells in place. */
|
|
1005
|
+
readonly editable?: boolean | undefined;
|
|
1006
|
+
readonly ifMatch?: ((row: Row) => string | undefined) | undefined;
|
|
1007
|
+
readonly sortableOnly?: boolean | undefined;
|
|
1008
|
+
/** Show the sort dropdown. Default: for the card variants, which have no header to click. */
|
|
1009
|
+
readonly sortDropdown?: boolean | undefined;
|
|
1010
|
+
/** Where the state lives. Default: the window's query string. */
|
|
1011
|
+
readonly urlAdapter?: UrlAdapter | undefined;
|
|
1012
|
+
/** Prefix of this list's URL parameters. */
|
|
1013
|
+
readonly prefix?: string | undefined;
|
|
1014
|
+
readonly defaults?: QueryDefaults | undefined;
|
|
1015
|
+
readonly searchField?: string | undefined;
|
|
1016
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
1017
|
+
readonly onRowClick?: ((row: Row) => void) | undefined;
|
|
1018
|
+
readonly gridProps?: GridOptions | undefined;
|
|
1019
|
+
}
|
|
1020
|
+
/** A resource's list, ready to use: filters, sort and paging in the URL, one of three layouts. */
|
|
1021
|
+
export declare function ResourceList({ resource, apiVersion, ...props }: ResourceListProps): ReactElement;
|
|
1022
|
+
//#endregion
|
|
1023
|
+
//#region src/list/SortDropdown.d.ts
|
|
1024
|
+
interface SortDropdownProps {
|
|
1025
|
+
readonly ready: ReadyResource;
|
|
1026
|
+
readonly sort: readonly SortKey[];
|
|
1027
|
+
readonly onChange: (sort: readonly SortKey[]) => void;
|
|
1028
|
+
}
|
|
1029
|
+
/** Sort by one field, for layouts with no header row to click. Lists only fields the manifest marks sortable. */
|
|
1030
|
+
export declare function SortDropdown({ ready, sort, onChange }: SortDropdownProps): ReactElement | null;
|
|
1031
|
+
//#endregion
|
|
1032
|
+
//#region src/revisions/revision.d.ts
|
|
1033
|
+
/** One entry of a record's history (`GET revisions?id=`, newest first). */
|
|
1034
|
+
interface Revision {
|
|
1035
|
+
readonly id: number;
|
|
1036
|
+
readonly action: string;
|
|
1037
|
+
readonly actor: string;
|
|
1038
|
+
/** ISO-8601 UTC. */
|
|
1039
|
+
readonly createdAt: string;
|
|
1040
|
+
/** The record as it was after the action. */
|
|
1041
|
+
readonly snapshot: JsonObject;
|
|
1042
|
+
}
|
|
1043
|
+
/** Reads the server's revision rows. A row without a snapshot gets an empty one. */
|
|
1044
|
+
export declare function toRevisions(rows: readonly JsonObject[]): Revision[];
|
|
1045
|
+
/** Names of the `fields` whose value differs between two snapshots. */
|
|
1046
|
+
export declare function changedFields(fields: readonly FieldDescriptor[], before: JsonObject, after: JsonObject): string[];
|
|
1047
|
+
/**
|
|
1048
|
+
* The `PATCH` body that puts a record back to `snapshot`: the writable fields
|
|
1049
|
+
* the snapshot has. A `null` for a field that does not take `null` is left out,
|
|
1050
|
+
* as a cleared optional field is everywhere else.
|
|
1051
|
+
*/
|
|
1052
|
+
export declare function restorePatch(fields: readonly FieldDescriptor[], snapshot: JsonObject): JsonObject;
|
|
1053
|
+
//#endregion
|
|
1054
|
+
//#region src/revisions/Revisions.d.ts
|
|
1055
|
+
type RevisionsVariant = "list" | "audit" | "diff" | "preview";
|
|
1056
|
+
interface RevisionsPanelProps {
|
|
1057
|
+
readonly ready: ReadyResource;
|
|
1058
|
+
readonly id: number;
|
|
1059
|
+
readonly variant?: RevisionsVariant | undefined;
|
|
1060
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
1061
|
+
/** Called after a revision was restored (list variant). */
|
|
1062
|
+
readonly onRestored?: ((revision: Revision) => void) | undefined;
|
|
1063
|
+
}
|
|
1064
|
+
/** The history of one record of an already loaded resource. Hidden without `capabilities.revisions`. */
|
|
1065
|
+
export declare function RevisionsPanel(props: RevisionsPanelProps): ReactElement | null;
|
|
1066
|
+
interface RecordRevisionsProps extends Omit<RevisionsPanelProps, "ready"> {
|
|
1067
|
+
readonly resource: string;
|
|
1068
|
+
readonly apiVersion?: string | undefined;
|
|
1069
|
+
}
|
|
1070
|
+
/**
|
|
1071
|
+
* A record's revisions in one of four shapes: `list` (with Restore), `audit`
|
|
1072
|
+
* (table), `diff` (two revisions compared) or `preview` (one snapshot).
|
|
1073
|
+
*/
|
|
1074
|
+
export declare function RecordRevisions({ resource, apiVersion, ...rest }: RecordRevisionsProps): ReactElement;
|
|
1075
|
+
//#endregion
|
|
1076
|
+
//#region src/stats/model.d.ts
|
|
1077
|
+
/** The time buckets the server aggregates by. */
|
|
1078
|
+
type Bucket = "day" | "week" | "month";
|
|
1079
|
+
//#endregion
|
|
1080
|
+
//#region src/stats/shared.d.ts
|
|
1081
|
+
/** Props every stats and prediction variant takes. */
|
|
1082
|
+
interface ViewProps {
|
|
1083
|
+
/** The manifest resource name (`"heroes"`). */
|
|
1084
|
+
readonly resource: string;
|
|
1085
|
+
readonly apiVersion?: string | undefined;
|
|
1086
|
+
/** Field-renderer overrides, passed to every `FieldDisplay` the view renders. */
|
|
1087
|
+
readonly renderers?: RendererOverrides | undefined;
|
|
1088
|
+
}
|
|
1089
|
+
//#endregion
|
|
1090
|
+
//#region src/stats/StatsKpiCards.d.ts
|
|
1091
|
+
/** Variant 1: one card for the record count and one per numeric field (average, with its range). Hidden without the `stats` capability. */
|
|
1092
|
+
export declare function StatsKpiCards({ resource, apiVersion, renderers }: ViewProps): ReactElement;
|
|
1093
|
+
//#endregion
|
|
1094
|
+
//#region src/stats/StatsTimeSeries.d.ts
|
|
1095
|
+
interface StatsTimeSeriesProps extends ViewProps {
|
|
1096
|
+
/** The initial bucket size. Default `"day"`. */
|
|
1097
|
+
readonly bucket?: Bucket | undefined;
|
|
1098
|
+
}
|
|
1099
|
+
/**
|
|
1100
|
+
* Variant 2: records created per UTC bucket as a line chart, with a
|
|
1101
|
+
* day/week/month toggle. Buckets with no records are absent from the server's
|
|
1102
|
+
* series and stay absent on the time axis. Hidden without the `stats`
|
|
1103
|
+
* capability.
|
|
1104
|
+
*/
|
|
1105
|
+
export declare function StatsTimeSeries({ resource, apiVersion, bucket: initial }: StatsTimeSeriesProps): ReactElement;
|
|
1106
|
+
//#endregion
|
|
1107
|
+
//#region src/stats/StatsCategoryChart.d.ts
|
|
1108
|
+
type CategoryChartKind = "bar" | "pie";
|
|
1109
|
+
interface StatsCategoryChartProps extends ViewProps {
|
|
1110
|
+
/** The initial chart. Default `"bar"`. */
|
|
1111
|
+
readonly kind?: CategoryChartKind | undefined;
|
|
1112
|
+
/** The categorical field shown first. Default: the first the server reports. */
|
|
1113
|
+
readonly field?: string | undefined;
|
|
1114
|
+
}
|
|
1115
|
+
/**
|
|
1116
|
+
* Variant 3: the value distribution of a boolean or enum field as a bar or pie
|
|
1117
|
+
* chart, with a field picker and a chart-type toggle. Hidden without the
|
|
1118
|
+
* `stats` capability.
|
|
1119
|
+
*/
|
|
1120
|
+
export declare function StatsCategoryChart({ resource, apiVersion, kind, field }: StatsCategoryChartProps): ReactElement;
|
|
1121
|
+
//#endregion
|
|
1122
|
+
//#region src/stats/StatsTablePanel.d.ts
|
|
1123
|
+
/**
|
|
1124
|
+
* Variant 4: two tables, the numeric aggregates of every numeric field and
|
|
1125
|
+
* the value counts of every categorical field. Values go through the field
|
|
1126
|
+
* renderers. Hidden without the `stats` capability.
|
|
1127
|
+
*/
|
|
1128
|
+
export declare function StatsTablePanel({ resource, apiVersion, renderers }: ViewProps): ReactElement;
|
|
1129
|
+
//#endregion
|
|
1130
|
+
//#region src/stats/StatsDashboard.d.ts
|
|
1131
|
+
/** All four statistics variants on one page. Hidden without the `stats` capability. */
|
|
1132
|
+
export declare function StatsDashboard(props: ViewProps): ReactElement;
|
|
1133
|
+
//#endregion
|
|
1134
|
+
//#region src/stats/predictShared.d.ts
|
|
1135
|
+
/** What `/predict` is asked: a numeric field (default the record count), how many buckets ahead, and the bucket size. */
|
|
1136
|
+
interface PredictionQuery {
|
|
1137
|
+
/** A numeric field to forecast the per-bucket sum of; omit to forecast the record count. */
|
|
1138
|
+
readonly field?: string | undefined;
|
|
1139
|
+
/** Buckets to project, 1 to 52. Default 4. */
|
|
1140
|
+
readonly periods?: number | undefined;
|
|
1141
|
+
/** Default `"day"`. */
|
|
1142
|
+
readonly bucket?: Bucket | undefined;
|
|
1143
|
+
}
|
|
1144
|
+
type PredictionProps = ViewProps & PredictionQuery;
|
|
1145
|
+
//#endregion
|
|
1146
|
+
//#region src/stats/PredictionChart.d.ts
|
|
1147
|
+
/**
|
|
1148
|
+
* Predictions variant 1: a line chart of the known series and the forecast
|
|
1149
|
+
* after it. The history is the server's count series, so it is drawn only
|
|
1150
|
+
* when the forecast is of the record count (no `field`) and `stats` is
|
|
1151
|
+
* available; a field forecast shows its last known value and the projection.
|
|
1152
|
+
* Hidden without the `predict` capability.
|
|
1153
|
+
*/
|
|
1154
|
+
export declare function PredictionChart(props: PredictionProps): ReactElement;
|
|
1155
|
+
//#endregion
|
|
1156
|
+
//#region src/stats/PredictionTable.d.ts
|
|
1157
|
+
/**
|
|
1158
|
+
* Predictions variant 2: the last known value and every forecast bucket as a
|
|
1159
|
+
* table, values shown by the field's renderer. Hidden without the `predict`
|
|
1160
|
+
* capability.
|
|
1161
|
+
*/
|
|
1162
|
+
export declare function PredictionTable(props: PredictionProps): ReactElement;
|
|
1163
|
+
//#endregion
|
|
1164
|
+
//#region src/stats/PredictionKpi.d.ts
|
|
1165
|
+
/**
|
|
1166
|
+
* Predictions variant 3: a card with the first forecast bucket's value and how
|
|
1167
|
+
* it moves from the last known one. Hidden without the `predict` capability.
|
|
1168
|
+
*/
|
|
1169
|
+
export declare function PredictionKpi(props: PredictionProps): ReactElement;
|
|
1170
|
+
//#endregion
|
|
1171
|
+
//#region src/stats/PredictionsDashboard.d.ts
|
|
1172
|
+
/** All three prediction variants with the controls that drive them (field, buckets ahead, bucket size). Hidden without the `predict` capability. */
|
|
1173
|
+
export declare function PredictionsDashboard(props: ViewProps): ReactElement;
|
|
1174
|
+
//#endregion
|
|
1175
|
+
export type { ArchivedToggleProps, Bucket, BulkAction, BulkDone, BulkPanelProps, BulkRecordsProps, BulkSelection, BulkToolbarProps, CardGridListProps, CardListProps, CategoryChartKind, Column, ColumnSpec, ColumnsMenuProps, ConfirmDialogProps, CrudContextValue, CrudProviderProps, DataTableListProps, DeleteActionProps, DeleteVariant, DetailFormContext, DetailPanelProps, DetailVariant, DialogShellProps, DisplayRenderer, DisplayRendererProps, DraftControlsProps, DrawerShellProps, FacetSidebarProps, FailedResource, FieldConstraints, FieldDescriptor, FieldFilter, FieldFilters, FieldKind, FieldListProps, FieldRenderers, FieldValue, FilterBarProps, FilterBuilderProps, FilterControlProps, FilterOp, FilterRenderer, FilterRendererProps, FilterScalar, FilterVariant, FormLayoutKind, FormSection, GridOptions, InputRenderer, InputRendererProps, ListVariant, LoadMoreListProps, OverlayShellProps, PageShellProps, PendingResource, PredictionProps, PredictionQuery, QueryContext, QueryDefaults, QueryState, QueryStateApi, QueryStateOptions, QuickSearchProps, ReadyResource, RecordActionProps, RecordCardProps, RecordDetailProps, RecordRevisionsProps, RecordStatus, RendererByRole, RendererOverrides, RendererRole, ResourceFormProps, ResourceGateProps, ResourceHooks, ResourceListProps, Revision, RevisionsPanelProps, RevisionsVariant, Row, SaveFailure, ShellProps, SortDropdownProps, SortKey, StatsCategoryChartProps, StatsTimeSeriesProps, ViewProps as StatsViewProps, StatusBadgeProps, StatusFilterProps, StatusFilterValue, StatusQuery, TrashListProps, TrashPanelProps, UrlAdapter, UseResourceResult };
|
|
1176
|
+
//# sourceMappingURL=index.d.mts.map
|