@ditojs/admin 2.86.0 → 2.88.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/package.json +6 -6
- package/types/index.d.ts +2535 -431
- package/types/tests/admin.test-d.ts +27 -0
- package/types/tests/component-buttons.test-d.ts +44 -0
- package/types/tests/component-list.test-d.ts +159 -0
- package/types/tests/component-misc.test-d.ts +137 -0
- package/types/tests/component-object.test-d.ts +69 -0
- package/types/tests/component-section.test-d.ts +174 -0
- package/types/tests/component-select.test-d.ts +107 -0
- package/types/tests/components.test-d.ts +81 -0
- package/types/tests/context.test-d.ts +31 -0
- package/types/tests/fixtures.ts +24 -0
- package/types/tests/form.test-d.ts +109 -0
- package/types/tests/instance.test-d.ts +20 -0
- package/types/tests/schema-features.test-d.ts +402 -0
- package/types/tests/variance.test-d.ts +125 -0
- package/types/tests/view.test-d.ts +146 -0
package/types/index.d.ts
CHANGED
|
@@ -17,97 +17,206 @@ declare global {
|
|
|
17
17
|
|
|
18
18
|
export default DitoAdmin
|
|
19
19
|
export interface DitoGlobal {
|
|
20
|
+
/** Global API configuration shared across the admin. */
|
|
20
21
|
api?: ApiConfig
|
|
22
|
+
/** Base URL path for the admin application. */
|
|
21
23
|
base?: string
|
|
24
|
+
/** Arbitrary settings accessible via `dito.settings`. */
|
|
22
25
|
settings?: Record<string, any>
|
|
23
26
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* A function that performs an HTTP request and returns the parsed
|
|
30
|
+
* response. Used by the admin to communicate with the Dito.js
|
|
31
|
+
* server API.
|
|
32
|
+
*
|
|
33
|
+
* @template T The expected type of the response data.
|
|
34
|
+
*/
|
|
35
|
+
export type RequestMethod = <T>(options: {
|
|
36
|
+
/** The URL to send the request to. */
|
|
32
37
|
url: string
|
|
33
38
|
/**
|
|
39
|
+
* The HTTP method to use.
|
|
40
|
+
*
|
|
34
41
|
* @default 'get'
|
|
35
42
|
*/
|
|
36
|
-
method
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
43
|
+
method?: HTTPMethod
|
|
44
|
+
/** Request body payload. */
|
|
45
|
+
data?: unknown
|
|
46
|
+
/** URL query parameters. */
|
|
47
|
+
query?:
|
|
48
|
+
| Record<string, string | number | (string | number)[]>
|
|
49
|
+
| [string, string | number][]
|
|
50
|
+
| null
|
|
51
|
+
/** Additional HTTP headers to include. */
|
|
52
|
+
headers?: Record<string, string> | null
|
|
53
|
+
/** Abort signal to cancel the request. */
|
|
54
|
+
signal?: AbortSignal | null
|
|
40
55
|
}) => Promise<RequestMethodResponse<T>>
|
|
41
56
|
|
|
57
|
+
/**
|
|
58
|
+
* The response returned by {@link RequestMethod}, extending the
|
|
59
|
+
* standard `Response` with a parsed `data` property.
|
|
60
|
+
*
|
|
61
|
+
* @template T The type of the parsed response data.
|
|
62
|
+
*/
|
|
42
63
|
export type RequestMethodResponse<T> = Response & { data: T }
|
|
43
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Describes a resource in the Dito.js server API. Resources can be
|
|
67
|
+
* nested via {@link ApiResource.parent} to build hierarchical API
|
|
68
|
+
* paths. The {@link ApiResource.type} determines how the path is
|
|
69
|
+
* constructed:
|
|
70
|
+
*
|
|
71
|
+
* - `'collection'` — uses `path` directly (e.g. `users`)
|
|
72
|
+
* - `'member'` — appends `id` to the path (e.g. `users/5`)
|
|
73
|
+
* - `'upload'` — builds an upload path under the parent collection
|
|
74
|
+
* (e.g. `users/upload/avatar`)
|
|
75
|
+
*
|
|
76
|
+
* Paths are built recursively through the `parent` chain, so a
|
|
77
|
+
* member nested under a collection produces paths like
|
|
78
|
+
* `users/1/comments/3`.
|
|
79
|
+
*/
|
|
44
80
|
export interface ApiResource {
|
|
45
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Determines how the resource path is constructed.
|
|
83
|
+
*
|
|
84
|
+
* @see {@link ApiResource} for the path-building rules per type.
|
|
85
|
+
*/
|
|
86
|
+
type: LiteralUnion<'collection' | 'member' | 'upload'>
|
|
87
|
+
/**
|
|
88
|
+
* URL path segment for this resource. If it starts with `/`, it is
|
|
89
|
+
* treated as absolute and parent nesting is skipped. Otherwise it
|
|
90
|
+
* is appended to the parent's resolved path.
|
|
91
|
+
*/
|
|
46
92
|
path?: string
|
|
93
|
+
/** HTTP method for the resource request. */
|
|
94
|
+
method?: HTTPMethod
|
|
95
|
+
/**
|
|
96
|
+
* Identifier of a specific resource item, used when
|
|
97
|
+
* {@link ApiResource.type} is `'member'` to append the id to the
|
|
98
|
+
* resolved path.
|
|
99
|
+
*/
|
|
100
|
+
id?: string | number
|
|
101
|
+
/**
|
|
102
|
+
* Parent resource for nested API paths. The parent's path is
|
|
103
|
+
* resolved first and this resource's path is appended to it,
|
|
104
|
+
* enabling hierarchical URLs.
|
|
105
|
+
*/
|
|
47
106
|
parent?: ApiResource
|
|
107
|
+
/** Query parameters appended to the request URL. */
|
|
108
|
+
query?: Record<string, string | number | (string | number)[]>
|
|
48
109
|
}
|
|
49
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Configuration for the admin's API layer. Merged from three
|
|
113
|
+
* sources in order of priority: the constructor `api` parameter,
|
|
114
|
+
* `dito.api` (passed from `AdminController` on the server), and
|
|
115
|
+
* built-in defaults.
|
|
116
|
+
*/
|
|
50
117
|
export interface ApiConfig {
|
|
51
118
|
/**
|
|
52
|
-
* The base
|
|
119
|
+
* The base path for the admin UI, as passed from
|
|
120
|
+
* `AdminController`.
|
|
121
|
+
*
|
|
122
|
+
* @defaultValue `'/'`
|
|
123
|
+
*/
|
|
124
|
+
base?: string
|
|
125
|
+
/**
|
|
126
|
+
* The base URL prepended to all API requests. Relative request
|
|
127
|
+
* URLs are combined with this value.
|
|
53
128
|
*/
|
|
54
129
|
url?: string
|
|
55
130
|
/**
|
|
56
|
-
*
|
|
131
|
+
* Locale used for date, time, and number formatting throughout
|
|
132
|
+
* the admin.
|
|
133
|
+
*
|
|
134
|
+
* @defaultValue `'en-US'`
|
|
57
135
|
*/
|
|
58
136
|
locale?: string
|
|
137
|
+
/**
|
|
138
|
+
* Default format options for numbers, dates, and times. Merged
|
|
139
|
+
* with the built-in `defaultFormats` from `@ditojs/utils`.
|
|
140
|
+
* Individual schemas can override these on a per-component basis.
|
|
141
|
+
*/
|
|
59
142
|
formats?: {
|
|
60
143
|
number?: NumberFormat
|
|
61
144
|
date?: DateFormat
|
|
62
145
|
time?: TimeFormat
|
|
63
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* The function used to perform HTTP requests. Defaults to a
|
|
149
|
+
* built-in `fetch` wrapper that applies {@link ApiConfig.headers},
|
|
150
|
+
* {@link ApiConfig.cors}, and {@link ApiConfig.getApiUrl}
|
|
151
|
+
* automatically for API URLs.
|
|
152
|
+
*/
|
|
64
153
|
request?: RequestMethod
|
|
65
154
|
/**
|
|
66
|
-
*
|
|
155
|
+
* Controls admin notification toasts. Set to `false` to disable
|
|
156
|
+
* all notifications, or provide an object to customize display
|
|
157
|
+
* duration.
|
|
67
158
|
*
|
|
68
|
-
* @
|
|
159
|
+
* @defaultValue `true`
|
|
69
160
|
*/
|
|
70
161
|
notifications?:
|
|
71
162
|
| boolean
|
|
72
163
|
| {
|
|
73
164
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
165
|
+
* Milliseconds per character used to calculate notification
|
|
166
|
+
* display duration. The formula is:
|
|
167
|
+
* `(40 + text.length + title.length) * durationFactor`.
|
|
168
|
+
*
|
|
76
169
|
* @defaultValue `20`
|
|
77
170
|
*/
|
|
78
171
|
durationFactor: number
|
|
79
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* CORS settings applied to API requests (where
|
|
175
|
+
* {@link ApiConfig.isApiUrl} returns `true`).
|
|
176
|
+
*/
|
|
80
177
|
cors?: {
|
|
81
178
|
/**
|
|
82
|
-
*
|
|
179
|
+
* Enables cross-site requests with credentials
|
|
180
|
+
* (`credentials: 'include'`).
|
|
83
181
|
*/
|
|
84
182
|
credentials: boolean
|
|
85
183
|
}
|
|
86
184
|
/**
|
|
87
|
-
*
|
|
88
|
-
*
|
|
185
|
+
* When `true`, sets {@link ApiConfig.normalizePath} to
|
|
186
|
+
* `hyphenate` (camelCase to kebab-case) and
|
|
187
|
+
* {@link ApiConfig.denormalizePath} to `camelize` (kebab-case to
|
|
188
|
+
* camelCase). Used for automatic path conversion between JS
|
|
189
|
+
* naming conventions and URL paths.
|
|
89
190
|
*
|
|
90
|
-
* @
|
|
91
|
-
* `
|
|
191
|
+
* @defaultValue Inherits from
|
|
192
|
+
* `Application.config.app.normalizePaths`, falling back
|
|
193
|
+
* to `false`.
|
|
92
194
|
*/
|
|
93
195
|
normalizePaths?: boolean
|
|
94
196
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
197
|
+
* Converts a camelCase path segment to its URL form. Applied
|
|
198
|
+
* when building schema routes and upload paths.
|
|
199
|
+
*
|
|
200
|
+
* @defaultValue `hyphenate` when {@link ApiConfig.normalizePaths}
|
|
201
|
+
* is `true`, otherwise an identity function.
|
|
98
202
|
*/
|
|
99
203
|
normalizePath?: (path: string) => string
|
|
100
204
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
205
|
+
* Converts a URL path segment back to its camelCase form.
|
|
206
|
+
*
|
|
207
|
+
* @defaultValue `camelize` when {@link ApiConfig.normalizePaths}
|
|
208
|
+
* is `true`, otherwise an identity function.
|
|
104
209
|
*/
|
|
105
210
|
denormalizePath?: (path: string) => string
|
|
106
211
|
/**
|
|
107
|
-
*
|
|
212
|
+
* Authentication resource configuration. The `path` defines the
|
|
213
|
+
* user collection endpoint, and `login`, `logout`, and `session`
|
|
214
|
+
* are nested as child resources under it (e.g. `users/login`).
|
|
108
215
|
*/
|
|
109
216
|
users?: {
|
|
217
|
+
/** The collection path for the user model. */
|
|
110
218
|
path: string
|
|
219
|
+
/** Login endpoint. */
|
|
111
220
|
login?: {
|
|
112
221
|
/**
|
|
113
222
|
* @defaultValue `'login'`
|
|
@@ -116,8 +225,9 @@ export interface ApiConfig {
|
|
|
116
225
|
/**
|
|
117
226
|
* @defaultValue `'post'`
|
|
118
227
|
*/
|
|
119
|
-
method?:
|
|
228
|
+
method?: HTTPMethod
|
|
120
229
|
}
|
|
230
|
+
/** Logout endpoint. */
|
|
121
231
|
logout?: {
|
|
122
232
|
/**
|
|
123
233
|
* @defaultValue `'logout'`
|
|
@@ -126,8 +236,12 @@ export interface ApiConfig {
|
|
|
126
236
|
/**
|
|
127
237
|
* @defaultValue `'post'`
|
|
128
238
|
*/
|
|
129
|
-
method?:
|
|
239
|
+
method?: HTTPMethod
|
|
130
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* Session endpoint for checking an existing authenticated
|
|
243
|
+
* session on page load.
|
|
244
|
+
*/
|
|
131
245
|
session?: {
|
|
132
246
|
/**
|
|
133
247
|
* @defaultValue `'session'`
|
|
@@ -136,46 +250,112 @@ export interface ApiConfig {
|
|
|
136
250
|
/**
|
|
137
251
|
* @defaultValue `'get'`
|
|
138
252
|
*/
|
|
139
|
-
method?:
|
|
253
|
+
method?: HTTPMethod
|
|
140
254
|
}
|
|
141
255
|
}
|
|
142
256
|
/**
|
|
143
|
-
*
|
|
257
|
+
* Custom resource path handlers, keyed by resource type. Merged
|
|
258
|
+
* with the built-in handlers (`any`, `default`, `collection`,
|
|
259
|
+
* `member`, `upload`). Each handler receives an
|
|
260
|
+
* {@link ApiResource} and returns the resolved path string.
|
|
144
261
|
*/
|
|
145
262
|
resources?: Record<string, (resource: ApiResource | string) => string>
|
|
146
263
|
|
|
147
264
|
/**
|
|
148
|
-
*
|
|
149
|
-
* @
|
|
150
|
-
*
|
|
151
|
-
*
|
|
265
|
+
* HTTP headers included in all API requests (where
|
|
266
|
+
* {@link ApiConfig.isApiUrl} returns `true`). Merged with the
|
|
267
|
+
* default `Content-Type: application/json` header, and can be
|
|
268
|
+
* further overridden per-request.
|
|
269
|
+
*
|
|
270
|
+
* @defaultValue `{ 'Content-Type': 'application/json' }`
|
|
152
271
|
*/
|
|
153
272
|
headers?: Record<string, string>
|
|
154
273
|
|
|
155
274
|
/**
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
275
|
+
* Returns the full API URL for a given request configuration.
|
|
276
|
+
* Prepends {@link ApiConfig.url} to relative URLs and appends
|
|
277
|
+
* formatted query parameters.
|
|
278
|
+
*/
|
|
279
|
+
getApiUrl?: (options: {
|
|
280
|
+
url: string
|
|
281
|
+
query?:
|
|
282
|
+
| Record<string, string | number | (string | number)[]>
|
|
283
|
+
| [string, string | number][]
|
|
284
|
+
| null
|
|
285
|
+
}) => string
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Returns `true` if the given URL is an API URL. A URL is
|
|
289
|
+
* considered an API URL if it is not absolute or if it starts
|
|
290
|
+
* with {@link ApiConfig.url}. When `true`, the request includes
|
|
291
|
+
* {@link ApiConfig.headers} and respects
|
|
292
|
+
* {@link ApiConfig.cors} settings.
|
|
163
293
|
*/
|
|
164
|
-
|
|
294
|
+
isApiUrl?: (url: string) => boolean
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Default schema property values per component type. During
|
|
298
|
+
* schema processing, defaults for a matching type are applied
|
|
299
|
+
* to the schema: top-level properties that are `undefined` are
|
|
300
|
+
* set directly, while existing object properties are
|
|
301
|
+
* deep-merged. When a function is provided, it receives the
|
|
302
|
+
* schema and can return defaults or modify it directly.
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* ```js
|
|
306
|
+
* defaults: {
|
|
307
|
+
* multiselect: {
|
|
308
|
+
* selectable: true
|
|
309
|
+
* }
|
|
310
|
+
* }
|
|
311
|
+
* ```
|
|
312
|
+
*/
|
|
313
|
+
defaults?: Record<
|
|
314
|
+
string,
|
|
315
|
+
| Record<string, any>
|
|
316
|
+
| ((schema: Component) => Record<string, any> | void)
|
|
317
|
+
>
|
|
165
318
|
}
|
|
166
319
|
|
|
167
320
|
export interface BaseSchema<$Item>
|
|
168
321
|
extends SchemaDitoMixin<$Item>,
|
|
169
322
|
SchemaTypeMixin<$Item> {
|
|
323
|
+
/**
|
|
324
|
+
* Value used when the field's key is absent from the
|
|
325
|
+
* data object.
|
|
326
|
+
*/
|
|
170
327
|
default?: OrItemAccessor<$Item>
|
|
328
|
+
/**
|
|
329
|
+
* Computes and sets the field value reactively. If
|
|
330
|
+
* the callback returns `undefined`, the current value
|
|
331
|
+
* is preserved.
|
|
332
|
+
*/
|
|
171
333
|
compute?: ItemAccessor<$Item>
|
|
334
|
+
/**
|
|
335
|
+
* Additional reactive data properties merged into
|
|
336
|
+
* the component's data scope.
|
|
337
|
+
*/
|
|
172
338
|
data?: OrItemAccessor<$Item, {}, Record<string, any>>
|
|
339
|
+
/**
|
|
340
|
+
* Custom CSS class(es) added to the component's container
|
|
341
|
+
* element. Accepts a string or an object of class-boolean
|
|
342
|
+
* pairs.
|
|
343
|
+
*/
|
|
344
|
+
class?: string | Record<string, boolean>
|
|
345
|
+
/**
|
|
346
|
+
* Whether the component type omits surrounding spacing.
|
|
347
|
+
*
|
|
348
|
+
* @internal Set as a static option on component type
|
|
349
|
+
* definitions, not configured in schemas.
|
|
350
|
+
*/
|
|
173
351
|
omitSpacing?: boolean
|
|
174
|
-
|
|
352
|
+
/**
|
|
353
|
+
* Forces a layout line break before, after, or on
|
|
354
|
+
* both sides of the component.
|
|
355
|
+
*/
|
|
356
|
+
break?: 'before' | 'after' | 'both'
|
|
175
357
|
}
|
|
176
358
|
|
|
177
|
-
// TODO: finish off DitoMixin docs
|
|
178
|
-
// (methods / computed / watch / events / `on[A-Z]`-style callbacks)
|
|
179
359
|
export interface SchemaDitoMixin<$Item> {
|
|
180
360
|
/**
|
|
181
361
|
* Only displays the component if the schema accessor returns `true`
|
|
@@ -188,6 +368,7 @@ export interface SchemaDitoMixin<$Item> {
|
|
|
188
368
|
* the component is rendered.
|
|
189
369
|
*/
|
|
190
370
|
rules?: {
|
|
371
|
+
/** Override whether the field is required. */
|
|
191
372
|
required?: boolean
|
|
192
373
|
}
|
|
193
374
|
}
|
|
@@ -200,7 +381,51 @@ export type ItemEventHandler<$Item = any> = (
|
|
|
200
381
|
itemParams: DitoContext<$Item>
|
|
201
382
|
) => void | false
|
|
202
383
|
|
|
203
|
-
export
|
|
384
|
+
export type OpenEventHandler<$Item = any> = (
|
|
385
|
+
itemParams: DitoContext<$Item> & { open: boolean }
|
|
386
|
+
) => void | false
|
|
387
|
+
|
|
388
|
+
export type ErrorEventHandler<$Item = any> = (
|
|
389
|
+
itemParams: DitoContext<$Item> & { error: Error }
|
|
390
|
+
) => void | false
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Event handlers shared by component schemas, views,
|
|
394
|
+
* and forms.
|
|
395
|
+
*/
|
|
396
|
+
export interface SchemaEvents<$Item = any> {
|
|
397
|
+
/**
|
|
398
|
+
* Fires when the schema's component tree is set up.
|
|
399
|
+
* @see {@link SchemaFields.onInitialize}
|
|
400
|
+
*/
|
|
401
|
+
initialize?: ItemEventHandler<$Item>
|
|
402
|
+
/**
|
|
403
|
+
* Fires when the schema component is unmounted.
|
|
404
|
+
* @see {@link SchemaFields.onDestroy}
|
|
405
|
+
*/
|
|
406
|
+
destroy?: ItemEventHandler<$Item>
|
|
407
|
+
/**
|
|
408
|
+
* Fires after data has been fetched from the API.
|
|
409
|
+
* @see {@link SchemaFields.onLoad}
|
|
410
|
+
*/
|
|
411
|
+
load?: ItemEventHandler<$Item>
|
|
412
|
+
/**
|
|
413
|
+
* Fires after a value change is committed.
|
|
414
|
+
* @see {@link SchemaFields.onChange}
|
|
415
|
+
*/
|
|
416
|
+
change?: ItemEventHandler<$Item>
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export interface SchemaOpen<$Item = any> {
|
|
420
|
+
/**
|
|
421
|
+
* Called when a collapsible schema section is
|
|
422
|
+
* toggled open or closed. The `open` property on
|
|
423
|
+
* the context indicates the new state.
|
|
424
|
+
*/
|
|
425
|
+
onOpen?: OpenEventHandler<$Item>
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
export interface SchemaTypeMixin<$Item> extends SchemaFields<$Item> {
|
|
204
429
|
/**
|
|
205
430
|
* The label of the component.
|
|
206
431
|
*
|
|
@@ -228,9 +453,11 @@ export interface SchemaTypeMixin<$Item> {
|
|
|
228
453
|
visible?: OrItemAccessor<$Item, {}, boolean>
|
|
229
454
|
|
|
230
455
|
/**
|
|
456
|
+
* Whether to exclude the field's value from the processed data
|
|
457
|
+
* sent to the server.
|
|
458
|
+
*
|
|
231
459
|
* @defaultValue `false`
|
|
232
460
|
*/
|
|
233
|
-
// TODO: document exclude
|
|
234
461
|
exclude?: OrItemAccessor<$Item, {}, boolean>
|
|
235
462
|
|
|
236
463
|
/**
|
|
@@ -259,10 +486,24 @@ export interface SchemaTypeMixin<$Item> {
|
|
|
259
486
|
clearable?: OrItemAccessor<$Item, {}, boolean>
|
|
260
487
|
|
|
261
488
|
/**
|
|
262
|
-
* Specifies a short hint intended to aid the user
|
|
263
|
-
* input has no value.
|
|
489
|
+
* Specifies a short hint intended to aid the user
|
|
490
|
+
* with data entry when the input has no value. Set
|
|
491
|
+
* to `false` to disable the placeholder, or `true`
|
|
492
|
+
* to use the component's auto-generated default
|
|
493
|
+
* (e.g. multiselect generates one based on
|
|
494
|
+
* `searchable` and `taggable`).
|
|
495
|
+
*/
|
|
496
|
+
placeholder?: OrItemAccessor<$Item, {}, string | boolean>
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Info text displayed near the component label.
|
|
264
500
|
*/
|
|
265
|
-
|
|
501
|
+
info?: OrItemAccessor<$Item, {}, string>
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* The maximum allowed length of the input value.
|
|
505
|
+
*/
|
|
506
|
+
maxLength?: OrItemAccessor<$Item, {}, number>
|
|
266
507
|
|
|
267
508
|
/**
|
|
268
509
|
* Whether the input field should have autocomplete enabled.
|
|
@@ -270,37 +511,166 @@ export interface SchemaTypeMixin<$Item> {
|
|
|
270
511
|
autocomplete?: OrItemAccessor<$Item, {}, 'on' | 'off'>
|
|
271
512
|
|
|
272
513
|
/**
|
|
273
|
-
* Specifies a function which
|
|
274
|
-
* before it is passed
|
|
514
|
+
* Specifies a function which transforms the stored
|
|
515
|
+
* value into a display format before it is passed
|
|
516
|
+
* to the component for rendering.
|
|
275
517
|
*/
|
|
276
518
|
format?: ItemAccessor<$Item, {}, any>
|
|
519
|
+
/**
|
|
520
|
+
* Whether the component is disabled.
|
|
521
|
+
*
|
|
522
|
+
* @defaultValue `false`
|
|
523
|
+
*/
|
|
277
524
|
disabled?: OrItemAccessor<$Item, {}, boolean>
|
|
278
525
|
|
|
279
526
|
/**
|
|
280
|
-
* Specifies a function which parses the component
|
|
281
|
-
*
|
|
527
|
+
* Specifies a function which parses the component
|
|
528
|
+
* value when it changes, transforming the raw
|
|
529
|
+
* input before it is stored.
|
|
282
530
|
*/
|
|
283
|
-
parse?: ItemAccessor<$Item,
|
|
531
|
+
parse?: ItemAccessor<$Item, {}>
|
|
284
532
|
|
|
285
|
-
|
|
286
|
-
|
|
533
|
+
/**
|
|
534
|
+
* Specifies a function which processes the field value after
|
|
535
|
+
* type-specific processing but before exclusion, allowing
|
|
536
|
+
* custom value transformation before sending data to the
|
|
537
|
+
* server. Can also modify sibling data via `processedItem`
|
|
538
|
+
* in the context, even when `exclude` is `true`.
|
|
539
|
+
*/
|
|
540
|
+
process?: ItemAccessor<$Item, {}>
|
|
287
541
|
|
|
288
|
-
|
|
542
|
+
/**
|
|
543
|
+
* The property key used to identify the field in data objects.
|
|
544
|
+
* Auto-assigned from the component's key if not provided.
|
|
545
|
+
*/
|
|
289
546
|
name?: string
|
|
290
547
|
|
|
548
|
+
/**
|
|
549
|
+
* Called when the input element receives focus.
|
|
550
|
+
*/
|
|
291
551
|
onFocus?: ItemEventHandler<$Item>
|
|
552
|
+
/**
|
|
553
|
+
* Called when the input element loses focus.
|
|
554
|
+
*/
|
|
292
555
|
onBlur?: ItemEventHandler<$Item>
|
|
293
|
-
|
|
556
|
+
/**
|
|
557
|
+
* Called on every keystroke or value modification. Unlike
|
|
558
|
+
* {@link BaseSchema.onChange}, fires synchronously.
|
|
559
|
+
*/
|
|
294
560
|
onInput?: ItemEventHandler<$Item>
|
|
295
|
-
|
|
561
|
+
/**
|
|
562
|
+
* Grouped event handlers, equivalent to the `on[A-Z]`-style
|
|
563
|
+
* callbacks on the schema (e.g. {@link BaseSchema.onFocus}).
|
|
564
|
+
*
|
|
565
|
+
* @see {@link SchemaFields.onInitialize} and other `on`-
|
|
566
|
+
* prefixed properties for per-event documentation.
|
|
567
|
+
*/
|
|
568
|
+
events?: SchemaEvents<$Item> & {
|
|
569
|
+
/** @see {@link BaseSchema.onFocus} */
|
|
296
570
|
focus?: ItemEventHandler<$Item>
|
|
571
|
+
/** @see {@link BaseSchema.onBlur} */
|
|
297
572
|
blur?: ItemEventHandler<$Item>
|
|
298
|
-
|
|
573
|
+
/** @see {@link BaseSchema.onInput} */
|
|
299
574
|
input?: ItemEventHandler<$Item>
|
|
300
575
|
}
|
|
301
576
|
}
|
|
302
577
|
|
|
303
578
|
export interface SchemaSourceMixin<$Item> {
|
|
579
|
+
/**
|
|
580
|
+
* The form schema used for editing items.
|
|
581
|
+
*/
|
|
582
|
+
form?: ResolvableForm<$Item>
|
|
583
|
+
/**
|
|
584
|
+
* Multiple form schemas keyed by item type, for
|
|
585
|
+
* sources with polymorphic content.
|
|
586
|
+
*/
|
|
587
|
+
forms?: {
|
|
588
|
+
[key: string]: ResolvableForm
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* The label given to items. If no itemLabel is given,
|
|
592
|
+
* the default is the 'name' property of the item,
|
|
593
|
+
* followed by the label of the form (plus item id)
|
|
594
|
+
* and other defaults.
|
|
595
|
+
*/
|
|
596
|
+
itemLabel?:
|
|
597
|
+
| OrItemAccessor<
|
|
598
|
+
$Item,
|
|
599
|
+
{},
|
|
600
|
+
| string
|
|
601
|
+
| {
|
|
602
|
+
text?: string
|
|
603
|
+
prefix?: string
|
|
604
|
+
suffix?: string
|
|
605
|
+
}
|
|
606
|
+
>
|
|
607
|
+
| false
|
|
608
|
+
/**
|
|
609
|
+
* The columns displayed in the table. Can be an array
|
|
610
|
+
* of property names or an object with column schemas.
|
|
611
|
+
*/
|
|
612
|
+
columns?: Columns<$Item> | (keyof $Item)[]
|
|
613
|
+
/**
|
|
614
|
+
* Scope names as defined on the model. When set, the
|
|
615
|
+
* admin renders scope buttons allowing the user to
|
|
616
|
+
* switch between them while editing.
|
|
617
|
+
*/
|
|
618
|
+
scopes?:
|
|
619
|
+
| string[]
|
|
620
|
+
| {
|
|
621
|
+
[scopeName: string]:
|
|
622
|
+
| {
|
|
623
|
+
label?: string
|
|
624
|
+
hint?: string
|
|
625
|
+
defaultScope?: boolean
|
|
626
|
+
}
|
|
627
|
+
| string
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Use a Vue component to render the items.
|
|
631
|
+
*/
|
|
632
|
+
component?: Resolvable<VueComponent>
|
|
633
|
+
/**
|
|
634
|
+
* Custom render function for items.
|
|
635
|
+
*/
|
|
636
|
+
render?: ItemAccessor<$Item, {}, string>
|
|
637
|
+
/**
|
|
638
|
+
* Maximum nesting depth for nested sources.
|
|
639
|
+
*
|
|
640
|
+
* @defaultValue `1`
|
|
641
|
+
*/
|
|
642
|
+
maxDepth?: number
|
|
643
|
+
/** Buttons for the source. */
|
|
644
|
+
buttons?: Buttons<$Item>
|
|
645
|
+
/**
|
|
646
|
+
* Whether to wrap primitive values in objects.
|
|
647
|
+
*/
|
|
648
|
+
wrapPrimitives?: boolean
|
|
649
|
+
/**
|
|
650
|
+
* URL path for the source items.
|
|
651
|
+
*/
|
|
652
|
+
path?: string
|
|
653
|
+
/**
|
|
654
|
+
* The property name used as the item's unique
|
|
655
|
+
* identifier.
|
|
656
|
+
*
|
|
657
|
+
* @defaultValue `'id'`
|
|
658
|
+
*/
|
|
659
|
+
idKey?: string
|
|
660
|
+
/**
|
|
661
|
+
* Whether the data is stored under its own key in the parent item.
|
|
662
|
+
* When `true`, an "address" source stores data at `item.address`.
|
|
663
|
+
* When `false`, its fields are stored directly on `item`.
|
|
664
|
+
*
|
|
665
|
+
* @defaultValue `true`
|
|
666
|
+
*/
|
|
667
|
+
nested?: boolean
|
|
668
|
+
/**
|
|
669
|
+
* Inline form components. When defined, items are
|
|
670
|
+
* edited inline rather than navigating to a separate
|
|
671
|
+
* page.
|
|
672
|
+
*/
|
|
673
|
+
components?: Components<$Item>
|
|
304
674
|
/**
|
|
305
675
|
* The number of items displayed per page. When not provided, all items are
|
|
306
676
|
* rendered.
|
|
@@ -308,8 +678,15 @@ export interface SchemaSourceMixin<$Item> {
|
|
|
308
678
|
* @defaultValue `false`
|
|
309
679
|
*/
|
|
310
680
|
paginate?: OrItemAccessor<$Item, {}, number>
|
|
311
|
-
// TODO: document inlined
|
|
312
681
|
/**
|
|
682
|
+
* The default page number for paginated sources.
|
|
683
|
+
*/
|
|
684
|
+
page?: number
|
|
685
|
+
/**
|
|
686
|
+
* Whether to display items inline in an expandable form rather
|
|
687
|
+
* than navigating to a separate page. Also implicitly `true`
|
|
688
|
+
* when `components` is defined on the schema.
|
|
689
|
+
*
|
|
313
690
|
* @defaultValue `false`
|
|
314
691
|
*/
|
|
315
692
|
inlined?: OrItemAccessor<$Item, {}, boolean>
|
|
@@ -347,21 +724,42 @@ export interface SchemaSourceMixin<$Item> {
|
|
|
347
724
|
* @defaultValue `null`
|
|
348
725
|
*/
|
|
349
726
|
collapsible?: OrItemAccessor<$Item, {}, boolean | null>
|
|
727
|
+
/** Whether the inlined form is collapsed. */
|
|
728
|
+
collapsed?: OrItemAccessor<$Item, {}, boolean>
|
|
350
729
|
/**
|
|
351
|
-
*
|
|
730
|
+
* Default sort configuration.
|
|
731
|
+
*/
|
|
732
|
+
defaultSort?:
|
|
733
|
+
| string
|
|
734
|
+
| { key: string; order: 'asc' | 'desc' }
|
|
735
|
+
/**
|
|
736
|
+
* Default scope name as defined on the model.
|
|
737
|
+
*/
|
|
738
|
+
defaultScope?: string
|
|
739
|
+
/**
|
|
740
|
+
* Resource configuration for loading data from the
|
|
741
|
+
* API.
|
|
352
742
|
*/
|
|
353
|
-
collapsed?: OrItemAccessor<$Item, {}, boolean>
|
|
354
743
|
resource?: Resource
|
|
744
|
+
/**
|
|
745
|
+
* The name of a view to reference for form schemas and
|
|
746
|
+
* editing navigation.
|
|
747
|
+
*/
|
|
748
|
+
view?: string
|
|
355
749
|
}
|
|
356
750
|
|
|
357
751
|
export type SchemaOptionsOption<$Value> =
|
|
358
752
|
| { label: string; value: $Value }
|
|
359
753
|
| $Value
|
|
360
754
|
export type SchemaOptions<$Item, $Option = any> =
|
|
361
|
-
| SchemaOptionsOption<$Option[]
|
|
755
|
+
| SchemaOptionsOption<$Option>[]
|
|
362
756
|
| {
|
|
363
757
|
/**
|
|
364
758
|
* The function which is called to load the options.
|
|
759
|
+
* Can be a double-function: the outer function
|
|
760
|
+
* receives the `DitoContext` and returns an inner
|
|
761
|
+
* function that is called to fetch the actual data,
|
|
762
|
+
* enabling reactive dependency tracking.
|
|
365
763
|
*/
|
|
366
764
|
data?: OrItemAccessor<
|
|
367
765
|
$Item,
|
|
@@ -377,23 +775,112 @@ export type SchemaOptions<$Item, $Option = any> =
|
|
|
377
775
|
*/
|
|
378
776
|
label?: keyof $Option | ItemAccessor<$Item, { option: $Option }, string>
|
|
379
777
|
/**
|
|
380
|
-
* Either the key of the option property which should be
|
|
381
|
-
* the value or a function returning the option
|
|
778
|
+
* Either the key of the option property which should be
|
|
779
|
+
* treated as the value or a function returning the option
|
|
780
|
+
* value.
|
|
382
781
|
*
|
|
383
|
-
* @defaultValue `'
|
|
384
|
-
* objects
|
|
782
|
+
* @defaultValue `'id'` when `relate` is set, otherwise
|
|
783
|
+
* `'value'` when the options are objects.
|
|
385
784
|
*/
|
|
386
|
-
// TODO: when relate is set, the default value is 'id'
|
|
387
785
|
value?: keyof $Option | ItemAccessor<$Item, { option: $Option }>
|
|
388
786
|
/**
|
|
389
787
|
* The key of the option property which should used to group the options.
|
|
390
788
|
*/
|
|
391
789
|
groupBy?: keyof $Option
|
|
790
|
+
/**
|
|
791
|
+
* Custom equality function for comparing options.
|
|
792
|
+
*/
|
|
793
|
+
equals?: (
|
|
794
|
+
a: $Option,
|
|
795
|
+
b: $Option
|
|
796
|
+
) => boolean
|
|
797
|
+
/**
|
|
798
|
+
* Relative path to resolve options from data
|
|
799
|
+
* within the same form. Uses filesystem-style
|
|
800
|
+
* path notation: `..` navigates up, `/` navigates
|
|
801
|
+
* into nested properties.
|
|
802
|
+
*
|
|
803
|
+
* @example Sibling data
|
|
804
|
+
* ```js
|
|
805
|
+
* // Form data: { tags: [...], selectedTags: [...] }
|
|
806
|
+
* selectedTags: {
|
|
807
|
+
* type: 'checkboxes',
|
|
808
|
+
* relate: true,
|
|
809
|
+
* options: { dataPath: '../tags' }
|
|
810
|
+
* }
|
|
811
|
+
* ```
|
|
812
|
+
*
|
|
813
|
+
* @example Parent data
|
|
814
|
+
* ```js
|
|
815
|
+
* // Root data: { categories: [...], items: [{ category: ... }] }
|
|
816
|
+
* // Inside a form for items:
|
|
817
|
+
* category: {
|
|
818
|
+
* type: 'select',
|
|
819
|
+
* options: { dataPath: '../../../categories' }
|
|
820
|
+
* }
|
|
821
|
+
* ```
|
|
822
|
+
*/
|
|
823
|
+
dataPath?: string
|
|
392
824
|
}
|
|
393
825
|
|
|
394
826
|
export interface SchemaOptionsMixin<$Item, $Option = any> {
|
|
827
|
+
/** The available options for selection. */
|
|
395
828
|
options?: SchemaOptions<$Item, $Option>
|
|
829
|
+
/**
|
|
830
|
+
* When true, treats options as related objects. The
|
|
831
|
+
* full object is used during editing, but only the
|
|
832
|
+
* `id` reference is stored on save.
|
|
833
|
+
*/
|
|
396
834
|
relate?: boolean
|
|
835
|
+
/**
|
|
836
|
+
* The property key used as the identifier when
|
|
837
|
+
* relating options. Only relevant when `relate` is
|
|
838
|
+
* `true`.
|
|
839
|
+
*
|
|
840
|
+
* @defaultValue `'id'`
|
|
841
|
+
*
|
|
842
|
+
* Note: Only `'id'` is currently supported.
|
|
843
|
+
*/
|
|
844
|
+
relateBy?: string
|
|
845
|
+
/**
|
|
846
|
+
* The key of the option property which should be used to
|
|
847
|
+
* group the options.
|
|
848
|
+
*/
|
|
849
|
+
groupBy?: OrItemAccessor<$Item, {}, string>
|
|
850
|
+
/**
|
|
851
|
+
* When defined, a search input field will be added to allow
|
|
852
|
+
* searching for specific options.
|
|
853
|
+
*/
|
|
854
|
+
search?:
|
|
855
|
+
| ItemAccessor<$Item, { query: string }, OrPromiseOf<$Option[]>>
|
|
856
|
+
| {
|
|
857
|
+
/**
|
|
858
|
+
* Filters options based on the search `query`
|
|
859
|
+
* available in the context. Returns matching
|
|
860
|
+
* options, optionally as a promise.
|
|
861
|
+
*/
|
|
862
|
+
filter?: ItemAccessor<$Item, { query: string }, OrPromiseOf<$Option[]>>
|
|
863
|
+
/**
|
|
864
|
+
* Debounce config for the filter. Delays
|
|
865
|
+
* invocation until input pauses.
|
|
866
|
+
*/
|
|
867
|
+
debounce?:
|
|
868
|
+
| number
|
|
869
|
+
| {
|
|
870
|
+
delay: number
|
|
871
|
+
immediate?: boolean
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* Whether the selected option can be edited by navigating
|
|
876
|
+
* to it.
|
|
877
|
+
*/
|
|
878
|
+
editable?: OrItemAccessor<$Item, {}, boolean>
|
|
879
|
+
/**
|
|
880
|
+
* The name of a view to reference for form schemas and
|
|
881
|
+
* editing navigation.
|
|
882
|
+
*/
|
|
883
|
+
view?: string
|
|
397
884
|
}
|
|
398
885
|
|
|
399
886
|
export interface SchemaNumberMixin<$Item> {
|
|
@@ -420,120 +907,320 @@ export interface SchemaNumberMixin<$Item> {
|
|
|
420
907
|
* The amount of decimals to round to.
|
|
421
908
|
*/
|
|
422
909
|
decimals?: OrItemAccessor<$Item, {}, number>
|
|
910
|
+
/** Validation rules for numeric constraints. */
|
|
423
911
|
rules?: Omit<SchemaNumberMixin<$Item>, 'rules'> & {
|
|
912
|
+
/** Restrict the value to whole numbers. */
|
|
424
913
|
integer?: boolean
|
|
425
914
|
}
|
|
426
915
|
}
|
|
427
916
|
|
|
428
|
-
export
|
|
429
|
-
type: 'component'
|
|
917
|
+
export interface SchemaTextMixin<$Item> {
|
|
430
918
|
/**
|
|
431
|
-
*
|
|
432
|
-
* like this: import(...).
|
|
919
|
+
* Whether to trim whitespace from the value.
|
|
433
920
|
*/
|
|
434
|
-
|
|
921
|
+
trim?: OrItemAccessor<$Item, {}, boolean>
|
|
435
922
|
}
|
|
436
923
|
|
|
437
|
-
export type
|
|
924
|
+
export type SchemaAffix =
|
|
925
|
+
| string
|
|
926
|
+
| {
|
|
927
|
+
/** The component type name for the affix. */
|
|
928
|
+
type?: string
|
|
929
|
+
/** Plain text content for the affix. */
|
|
930
|
+
text?: string
|
|
931
|
+
/** Raw HTML content for the affix. */
|
|
932
|
+
html?: string
|
|
933
|
+
/** Conditionally display the affix. */
|
|
934
|
+
if?: OrItemAccessor<any, {}, boolean>
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
export interface SchemaAffixMixin<$Item> {
|
|
438
938
|
/**
|
|
439
|
-
*
|
|
939
|
+
* Prefix content displayed before the input.
|
|
440
940
|
*/
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
| 'domain'
|
|
447
|
-
| 'tel'
|
|
448
|
-
| 'password'
|
|
449
|
-
| 'creditcard'
|
|
450
|
-
| 'computed'
|
|
451
|
-
rules?: {
|
|
452
|
-
text?: boolean
|
|
453
|
-
email?: boolean
|
|
454
|
-
url?: boolean
|
|
455
|
-
hostname?: boolean
|
|
456
|
-
domain?: boolean
|
|
457
|
-
// TODO: check why there is no 'tel' validation
|
|
458
|
-
// tel: boolean,
|
|
459
|
-
password?: boolean
|
|
460
|
-
creditcard?: boolean
|
|
461
|
-
}
|
|
941
|
+
prefix?: OrArrayOf<SchemaAffix>
|
|
942
|
+
/**
|
|
943
|
+
* Suffix content displayed after the input.
|
|
944
|
+
*/
|
|
945
|
+
suffix?: OrArrayOf<SchemaAffix>
|
|
462
946
|
}
|
|
463
947
|
|
|
464
|
-
export
|
|
948
|
+
export interface SchemaDataMixin<$Item> {
|
|
465
949
|
/**
|
|
466
|
-
*
|
|
950
|
+
* Data source for the component.
|
|
467
951
|
*/
|
|
468
|
-
|
|
952
|
+
data?: OrItemAccessor<$Item, {}, any>
|
|
469
953
|
/**
|
|
470
|
-
*
|
|
954
|
+
* Path to retrieve data from parent context.
|
|
471
955
|
*/
|
|
472
|
-
|
|
473
|
-
dateFormat?: OrItemAccessor<$Item, {}, DateFormat>
|
|
956
|
+
dataPath?: string
|
|
474
957
|
}
|
|
475
958
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
959
|
+
/**
|
|
960
|
+
* Properties shared by all schemas that support custom
|
|
961
|
+
* instance members and lifecycle events — component
|
|
962
|
+
* schemas, views, and forms.
|
|
963
|
+
*/
|
|
964
|
+
export interface SchemaFields<$Item> {
|
|
480
965
|
/**
|
|
481
|
-
*
|
|
966
|
+
* Methods accessible via `this` from event handlers,
|
|
967
|
+
* computed properties, watchers, and templates. Unlike
|
|
968
|
+
* event handlers, methods do not receive a context
|
|
969
|
+
* parameter — use `this.context` to access it.
|
|
482
970
|
*/
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
text?: OrItemAccessor<$Item, {}, string>
|
|
486
|
-
resource?: Resource
|
|
487
|
-
onClick?: $EventHandler
|
|
488
|
-
onSuccess?: $EventHandler
|
|
489
|
-
onError?: $EventHandler
|
|
490
|
-
events?: {
|
|
491
|
-
click?: $EventHandler
|
|
492
|
-
success?: $EventHandler
|
|
493
|
-
error?: $EventHandler
|
|
494
|
-
}
|
|
495
|
-
}
|
|
971
|
+
methods?: Record<string, (...args: any[]) => any> &
|
|
972
|
+
ThisType<DitoComponentInstance<$Item>>
|
|
496
973
|
|
|
497
|
-
export type SwitchSchema<$Item = any> = BaseSchema<$Item> & {
|
|
498
974
|
/**
|
|
499
|
-
*
|
|
975
|
+
* Computed properties defined on the component. Can be a
|
|
976
|
+
* getter function or a `{ get, set }` object for
|
|
977
|
+
* read-write computed properties. Getters and setters
|
|
978
|
+
* are called with the component as `this`. Like
|
|
979
|
+
* {@link SchemaFields.methods}, use `this.context` to
|
|
980
|
+
* access the context.
|
|
500
981
|
*/
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
982
|
+
computed?: Record<
|
|
983
|
+
string,
|
|
984
|
+
| ((this: DitoComponentInstance<$Item>) => any)
|
|
985
|
+
| {
|
|
986
|
+
get: (this: DitoComponentInstance<$Item>) => any
|
|
987
|
+
set: (
|
|
988
|
+
this: DitoComponentInstance<$Item>,
|
|
989
|
+
value: any
|
|
990
|
+
) => void
|
|
991
|
+
}
|
|
992
|
+
>
|
|
993
|
+
|
|
994
|
+
/**
|
|
995
|
+
* Watchers on data properties or expression paths. Keys
|
|
996
|
+
* are either component names (resolved to
|
|
997
|
+
* `data.${name}`) or arbitrary expression paths. Can be
|
|
998
|
+
* a plain handler function or an object with `handler`,
|
|
999
|
+
* `deep`, and `immediate` options.
|
|
1000
|
+
*/
|
|
1001
|
+
watch?:
|
|
1002
|
+
| WatchHandlers<$Item>
|
|
1003
|
+
| ((
|
|
1004
|
+
this: DitoComponentInstance<$Item>
|
|
1005
|
+
) => WatchHandlers<$Item>)
|
|
1006
|
+
|
|
1007
|
+
/**
|
|
1008
|
+
* Panel schemas rendered in the sidebar. Panels share
|
|
1009
|
+
* the parent's data unless their schema defines its
|
|
1010
|
+
* own `data` property.
|
|
1011
|
+
*/
|
|
1012
|
+
panels?: Record<string, PanelSchema<$Item>>
|
|
1013
|
+
|
|
1014
|
+
/**
|
|
1015
|
+
* Called when the schema's component tree is set up.
|
|
1016
|
+
*/
|
|
1017
|
+
onInitialize?: ItemEventHandler<$Item>
|
|
1018
|
+
/**
|
|
1019
|
+
* Called once when the schema component is unmounted
|
|
1020
|
+
* from the DOM.
|
|
1021
|
+
*/
|
|
1022
|
+
onDestroy?: ItemEventHandler<$Item>
|
|
1023
|
+
/**
|
|
1024
|
+
* Called after data has been fetched from the API.
|
|
1025
|
+
* Fires after all reactive updates have propagated.
|
|
1026
|
+
*/
|
|
1027
|
+
onLoad?: ItemEventHandler<$Item>
|
|
1028
|
+
/**
|
|
1029
|
+
* Called after a value change is committed. Fires
|
|
1030
|
+
* after all reactive updates have propagated. Bubbles
|
|
1031
|
+
* to parent schemas — return `false` to stop
|
|
1032
|
+
* propagation.
|
|
1033
|
+
*/
|
|
1034
|
+
onChange?: ItemEventHandler<$Item>
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
/** @deprecated Use {@link SchemaFields} instead. */
|
|
1038
|
+
export type SchemaSetupMixin<$Item = any> = SchemaFields<$Item>
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* Properties shared by route-level schemas
|
|
1042
|
+
* ({@link ViewSchema} and {@link Form}).
|
|
1043
|
+
*/
|
|
1044
|
+
export interface SchemaRoute<$Item = any>
|
|
1045
|
+
extends SchemaFields<$Item>,
|
|
1046
|
+
SchemaOpen<$Item> {
|
|
1047
|
+
/**
|
|
1048
|
+
* Renders with reduced spacing.
|
|
1049
|
+
*
|
|
1050
|
+
* @defaultValue `false`
|
|
1051
|
+
*/
|
|
1052
|
+
compact?: boolean
|
|
1053
|
+
/**
|
|
1054
|
+
* Resource configuration for loading data from
|
|
1055
|
+
* the API.
|
|
1056
|
+
*/
|
|
1057
|
+
resource?: Resource
|
|
1058
|
+
/**
|
|
1059
|
+
* Enables copy/paste for the data. Set to `true`
|
|
1060
|
+
* for default behavior or provide custom
|
|
1061
|
+
* copy/paste handlers.
|
|
1062
|
+
*/
|
|
1063
|
+
clipboard?: ClipboardConfig
|
|
1064
|
+
/**
|
|
1065
|
+
* Additional reactive data properties merged into
|
|
1066
|
+
* the component's data scope.
|
|
1067
|
+
*/
|
|
1068
|
+
data?: OrItemAccessor<$Item, {}, Record<string, any>>
|
|
1069
|
+
/**
|
|
1070
|
+
* Whether to use a wider content area.
|
|
1071
|
+
*
|
|
1072
|
+
* @defaultValue `false`
|
|
1073
|
+
*/
|
|
1074
|
+
wide?: OrItemAccessor<$Item, {}, boolean>
|
|
1075
|
+
/**
|
|
1076
|
+
* Custom breadcrumb text shown in page navigation.
|
|
1077
|
+
*
|
|
1078
|
+
* @defaultValue `${breadcrumbPrefix} ${label}`
|
|
1079
|
+
*/
|
|
1080
|
+
breadcrumb?: string
|
|
1081
|
+
buttons?: Buttons<$Item>
|
|
1082
|
+
/**
|
|
1083
|
+
* Conditionally display this view or form.
|
|
1084
|
+
*/
|
|
1085
|
+
if?: OrItemAccessor<$Item, {}, boolean>
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
/** @deprecated Use {@link SchemaRoute} instead. */
|
|
1089
|
+
export type SchemaRouteMixin<$Item = any> = SchemaRoute<$Item>
|
|
1090
|
+
|
|
1091
|
+
export interface ComponentSchema<$Item = any> extends BaseSchema<$Item> {
|
|
1092
|
+
type: 'component'
|
|
1093
|
+
/**
|
|
1094
|
+
* Use a Vue component to render the component. The component is specified
|
|
1095
|
+
* like this: import(...).
|
|
1096
|
+
*/
|
|
1097
|
+
component: Resolvable<VueComponent>
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
export interface InputSchema<$Item = any>
|
|
1101
|
+
extends BaseSchema<$Item>,
|
|
1102
|
+
SchemaTextMixin<$Item>,
|
|
1103
|
+
SchemaAffixMixin<$Item> {
|
|
1104
|
+
/**
|
|
1105
|
+
* The type of the component.
|
|
1106
|
+
*/
|
|
1107
|
+
type:
|
|
1108
|
+
| 'text'
|
|
1109
|
+
| 'email'
|
|
1110
|
+
| 'url'
|
|
1111
|
+
| 'hostname'
|
|
1112
|
+
| 'domain'
|
|
1113
|
+
| 'tel'
|
|
1114
|
+
| 'password'
|
|
1115
|
+
| 'creditcard'
|
|
1116
|
+
rules?: {
|
|
1117
|
+
text?: boolean
|
|
1118
|
+
email?: boolean
|
|
1119
|
+
url?: boolean
|
|
1120
|
+
hostname?: boolean
|
|
1121
|
+
domain?: boolean
|
|
1122
|
+
password?: boolean
|
|
1123
|
+
creditcard?: boolean
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
export interface DateSchema<$Item = any>
|
|
1128
|
+
extends BaseSchema<$Item>,
|
|
1129
|
+
SchemaAffixMixin<$Item> {
|
|
1130
|
+
/**
|
|
1131
|
+
* The type of the component.
|
|
1132
|
+
*/
|
|
1133
|
+
type: 'date' | 'datetime' | 'time'
|
|
1134
|
+
/**
|
|
1135
|
+
* @defaultValue `En/US`
|
|
1136
|
+
*/
|
|
1137
|
+
locale?: string
|
|
1138
|
+
/**
|
|
1139
|
+
* Format configuration for date/time display.
|
|
1140
|
+
*/
|
|
1141
|
+
formats?: OrItemAccessor<
|
|
1142
|
+
$Item,
|
|
1143
|
+
{},
|
|
1144
|
+
{
|
|
1145
|
+
date?: DateFormat
|
|
1146
|
+
time?: TimeFormat
|
|
1147
|
+
}
|
|
1148
|
+
>
|
|
1149
|
+
/**
|
|
1150
|
+
* @deprecated Use `formats` instead.
|
|
1151
|
+
*/
|
|
1152
|
+
dateFormat?: OrItemAccessor<$Item, {}, DateFormat>
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
export interface ButtonSchema<$Item = any>
|
|
1156
|
+
extends BaseSchema<$Item>,
|
|
1157
|
+
SchemaAffixMixin<$Item> {
|
|
1158
|
+
/**
|
|
1159
|
+
* The type of the component.
|
|
1160
|
+
*/
|
|
1161
|
+
type: 'button' | 'submit'
|
|
1162
|
+
closeForm?: OrItemAccessor<$Item, {}, boolean>
|
|
1163
|
+
text?: OrItemAccessor<$Item, {}, string>
|
|
1164
|
+
resource?: Resource
|
|
1165
|
+
onClick?: ItemEventHandler<$Item>
|
|
1166
|
+
onSuccess?: ItemEventHandler<$Item>
|
|
1167
|
+
onError?: ErrorEventHandler<$Item>
|
|
1168
|
+
events?: {
|
|
1169
|
+
click?: ItemEventHandler<$Item>
|
|
1170
|
+
success?: ItemEventHandler<$Item>
|
|
1171
|
+
error?: ErrorEventHandler<$Item>
|
|
524
1172
|
}
|
|
1173
|
+
}
|
|
525
1174
|
|
|
526
|
-
export
|
|
527
|
-
|
|
1175
|
+
export interface SwitchSchema<$Item = any> extends BaseSchema<$Item> {
|
|
1176
|
+
/**
|
|
1177
|
+
* The type of the component.
|
|
1178
|
+
*/
|
|
1179
|
+
type: 'switch'
|
|
1180
|
+
labels?: {
|
|
528
1181
|
/**
|
|
529
|
-
* The
|
|
1182
|
+
* The displayed label when the switch is checked.
|
|
1183
|
+
*
|
|
1184
|
+
* @defaultValue `'on'`
|
|
1185
|
+
*/
|
|
1186
|
+
checked?: string
|
|
1187
|
+
/**
|
|
1188
|
+
* The displayed label when the switch is unchecked.
|
|
1189
|
+
*
|
|
1190
|
+
* @defaultValue `'off'`
|
|
530
1191
|
*/
|
|
531
|
-
|
|
532
|
-
// TODO: document what the input SliderSchema option does
|
|
533
|
-
input?: OrItemAccessor<$Item>
|
|
1192
|
+
unchecked?: string
|
|
534
1193
|
}
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
export interface NumberSchema<$Item = any>
|
|
1197
|
+
extends SchemaNumberMixin<$Item>,
|
|
1198
|
+
BaseSchema<$Item>,
|
|
1199
|
+
SchemaAffixMixin<$Item> {
|
|
1200
|
+
/**
|
|
1201
|
+
* The type of the component.
|
|
1202
|
+
*/
|
|
1203
|
+
type: 'number' | 'integer'
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
export interface SliderSchema<$Item = any>
|
|
1207
|
+
extends SchemaNumberMixin<$Item>,
|
|
1208
|
+
BaseSchema<$Item> {
|
|
1209
|
+
/**
|
|
1210
|
+
* The type of the component.
|
|
1211
|
+
*/
|
|
1212
|
+
type: 'slider'
|
|
1213
|
+
/**
|
|
1214
|
+
* Whether to show a number input alongside the slider.
|
|
1215
|
+
*
|
|
1216
|
+
* @defaultValue `true`
|
|
1217
|
+
*/
|
|
1218
|
+
input?: OrItemAccessor<$Item, {}, boolean>
|
|
1219
|
+
}
|
|
535
1220
|
|
|
536
|
-
export
|
|
1221
|
+
export interface TextareaSchema<$Item = any>
|
|
1222
|
+
extends BaseSchema<$Item>,
|
|
1223
|
+
SchemaTextMixin<$Item> {
|
|
537
1224
|
/**
|
|
538
1225
|
* The type of the component.
|
|
539
1226
|
*/
|
|
@@ -541,7 +1228,7 @@ export type TextareaSchema<$Item = any> = BaseSchema<$Item> & {
|
|
|
541
1228
|
/**
|
|
542
1229
|
* Whether the input element is resizable.
|
|
543
1230
|
*/
|
|
544
|
-
resizable?: boolean
|
|
1231
|
+
resizable?: OrItemAccessor<$Item, {}, boolean>
|
|
545
1232
|
/**
|
|
546
1233
|
* The amount of visible lines.
|
|
547
1234
|
*
|
|
@@ -550,7 +1237,7 @@ export type TextareaSchema<$Item = any> = BaseSchema<$Item> & {
|
|
|
550
1237
|
lines?: number
|
|
551
1238
|
}
|
|
552
1239
|
|
|
553
|
-
export
|
|
1240
|
+
export interface CodeSchema<$Item = any> extends BaseSchema<$Item> {
|
|
554
1241
|
/**
|
|
555
1242
|
* The type of the component.
|
|
556
1243
|
*/
|
|
@@ -560,22 +1247,26 @@ export type CodeSchema<$Item = any> = BaseSchema<$Item> & {
|
|
|
560
1247
|
*
|
|
561
1248
|
* @defaultValue `js`
|
|
562
1249
|
*/
|
|
563
|
-
language?: string
|
|
1250
|
+
language?: OrItemAccessor<$Item, {}, string>
|
|
564
1251
|
/**
|
|
565
1252
|
* The indent size.
|
|
566
1253
|
*
|
|
567
1254
|
* @defaultValue `2`
|
|
568
1255
|
*/
|
|
569
|
-
indentSize?: number
|
|
1256
|
+
indentSize?: OrItemAccessor<$Item, {}, number>
|
|
570
1257
|
/**
|
|
571
1258
|
* The amount of visible lines.
|
|
572
1259
|
*
|
|
573
1260
|
* @defaultValue `3`
|
|
574
1261
|
*/
|
|
575
|
-
lines?: number
|
|
1262
|
+
lines?: OrItemAccessor<$Item, {}, number>
|
|
1263
|
+
/**
|
|
1264
|
+
* Whether the input element is resizable.
|
|
1265
|
+
*/
|
|
1266
|
+
resizable?: OrItemAccessor<$Item, {}, boolean>
|
|
576
1267
|
}
|
|
577
1268
|
|
|
578
|
-
export
|
|
1269
|
+
export interface MarkupSchema<$Item = any> extends BaseSchema<$Item> {
|
|
579
1270
|
/**
|
|
580
1271
|
* The type of the component.
|
|
581
1272
|
*/
|
|
@@ -599,7 +1290,13 @@ export type MarkupSchema<$Item = any> = BaseSchema<$Item> & {
|
|
|
599
1290
|
*/
|
|
600
1291
|
lines?: number
|
|
601
1292
|
|
|
602
|
-
|
|
1293
|
+
/**
|
|
1294
|
+
* Whether TipTap input and paste rules are enabled. When
|
|
1295
|
+
* `true`, both input and paste rules are active. Can also be
|
|
1296
|
+
* an object to control input and paste rules independently.
|
|
1297
|
+
*
|
|
1298
|
+
* @defaultValue `false`
|
|
1299
|
+
*/
|
|
603
1300
|
enableRules?: OrItemAccessor<
|
|
604
1301
|
$Item,
|
|
605
1302
|
{},
|
|
@@ -609,6 +1306,11 @@ export type MarkupSchema<$Item = any> = BaseSchema<$Item> & {
|
|
|
609
1306
|
paste: boolean
|
|
610
1307
|
}
|
|
611
1308
|
>
|
|
1309
|
+
/**
|
|
1310
|
+
* Whether Enter creates a hard break instead of a new
|
|
1311
|
+
* paragraph.
|
|
1312
|
+
*/
|
|
1313
|
+
hardBreak?: boolean
|
|
612
1314
|
marks?: {
|
|
613
1315
|
bold?: boolean
|
|
614
1316
|
italic?: boolean
|
|
@@ -616,6 +1318,8 @@ export type MarkupSchema<$Item = any> = BaseSchema<$Item> & {
|
|
|
616
1318
|
strike?: boolean
|
|
617
1319
|
small?: boolean
|
|
618
1320
|
code?: boolean
|
|
1321
|
+
subscript?: boolean
|
|
1322
|
+
superscript?: boolean
|
|
619
1323
|
link?: boolean
|
|
620
1324
|
}
|
|
621
1325
|
nodes?: {
|
|
@@ -628,24 +1332,31 @@ export type MarkupSchema<$Item = any> = BaseSchema<$Item> & {
|
|
|
628
1332
|
}
|
|
629
1333
|
tools?: {
|
|
630
1334
|
history?: boolean
|
|
1335
|
+
footnotes?: boolean
|
|
631
1336
|
}
|
|
632
1337
|
}
|
|
633
1338
|
|
|
634
|
-
export
|
|
1339
|
+
export interface LabelSchema<$Item = any> extends BaseSchema<$Item> {
|
|
635
1340
|
/**
|
|
636
1341
|
* The type of the component.
|
|
637
1342
|
*/
|
|
638
1343
|
type: 'label'
|
|
639
1344
|
}
|
|
640
1345
|
|
|
641
|
-
|
|
1346
|
+
/**
|
|
1347
|
+
* A non-visible component that includes a computed or
|
|
1348
|
+
* derived value in the form data without rendering it.
|
|
1349
|
+
*/
|
|
1350
|
+
export interface HiddenSchema<$Item = any>
|
|
1351
|
+
extends BaseSchema<$Item>,
|
|
1352
|
+
SchemaDataMixin<$Item> {
|
|
642
1353
|
/**
|
|
643
1354
|
* The type of the component.
|
|
644
1355
|
*/
|
|
645
1356
|
type: 'hidden'
|
|
646
1357
|
}
|
|
647
1358
|
|
|
648
|
-
export
|
|
1359
|
+
export interface UploadSchema<$Item = any> extends BaseSchema<$Item> {
|
|
649
1360
|
/**
|
|
650
1361
|
* The type of the component.
|
|
651
1362
|
*/
|
|
@@ -679,103 +1390,262 @@ export type UploadSchema<$Item = any> = BaseSchema<$Item> & {
|
|
|
679
1390
|
* @see {@link https://github.com/patrickkettner/filesize-parser/blob/master/test.js String Examples}
|
|
680
1391
|
*/
|
|
681
1392
|
maxSize?: string | number
|
|
682
|
-
|
|
683
|
-
|
|
1393
|
+
/**
|
|
1394
|
+
* Whether uploaded files can be reordered by dragging.
|
|
1395
|
+
*
|
|
1396
|
+
* @defaultValue `false`
|
|
1397
|
+
*/
|
|
1398
|
+
draggable?: OrItemAccessor<$Item, {}, boolean>
|
|
684
1399
|
/**
|
|
685
1400
|
* Whether files can be deleted.
|
|
686
1401
|
*/
|
|
687
|
-
deletable?: boolean
|
|
1402
|
+
deletable?: OrItemAccessor<$Item, {}, boolean>
|
|
1403
|
+
/**
|
|
1404
|
+
* Custom render function for file display.
|
|
1405
|
+
*/
|
|
1406
|
+
render?: ItemAccessor<$Item, {}, string>
|
|
1407
|
+
/**
|
|
1408
|
+
* Whether to display thumbnails for uploaded files, or
|
|
1409
|
+
* thumbnail size.
|
|
1410
|
+
*/
|
|
1411
|
+
thumbnails?: OrItemAccessor<$Item, {}, boolean | string>
|
|
1412
|
+
/**
|
|
1413
|
+
* URL or function returning URL for file thumbnails.
|
|
1414
|
+
*/
|
|
1415
|
+
thumbnailUrl?: OrItemAccessor<$Item, {}, string>
|
|
1416
|
+
/**
|
|
1417
|
+
* URL or function returning URL for file downloads.
|
|
1418
|
+
*/
|
|
1419
|
+
downloadUrl?: OrItemAccessor<$Item, {}, string>
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
export interface MultiselectSchema<$Item = any, $Option = any>
|
|
1423
|
+
extends BaseSchema<$Item>,
|
|
1424
|
+
SchemaOptionsMixin<$Item, $Option>,
|
|
1425
|
+
SchemaAffixMixin<$Item> {
|
|
1426
|
+
/**
|
|
1427
|
+
* The type of the component.
|
|
1428
|
+
*/
|
|
1429
|
+
type: 'multiselect'
|
|
1430
|
+
/**
|
|
1431
|
+
* Whether more than one option can be selected.
|
|
1432
|
+
*
|
|
1433
|
+
* @defaultValue `false`
|
|
1434
|
+
*/
|
|
1435
|
+
multiple?: boolean
|
|
1436
|
+
/**
|
|
1437
|
+
* Whether to enable a search input field in the dropdown
|
|
1438
|
+
* for filtering options.
|
|
1439
|
+
*
|
|
1440
|
+
* @defaultValue `false`
|
|
1441
|
+
*/
|
|
1442
|
+
searchable?: boolean
|
|
1443
|
+
/**
|
|
1444
|
+
* Whether the dropdown stays open after selecting an option,
|
|
1445
|
+
* useful for making multiple selections without repeated
|
|
1446
|
+
* opening.
|
|
1447
|
+
*
|
|
1448
|
+
* @defaultValue `false`
|
|
1449
|
+
*/
|
|
1450
|
+
stayOpen?: boolean
|
|
1451
|
+
/**
|
|
1452
|
+
* Whether users can create new options by typing and
|
|
1453
|
+
* pressing Enter, adding custom tags not in the options
|
|
1454
|
+
* list.
|
|
1455
|
+
*
|
|
1456
|
+
* @defaultValue `false`
|
|
1457
|
+
*/
|
|
1458
|
+
taggable?: boolean
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
export interface SelectSchema<$Item = any>
|
|
1462
|
+
extends BaseSchema<$Item>,
|
|
1463
|
+
SchemaOptionsMixin<$Item>,
|
|
1464
|
+
SchemaAffixMixin<$Item> {
|
|
1465
|
+
/**
|
|
1466
|
+
* The type of the component.
|
|
1467
|
+
*/
|
|
1468
|
+
type: 'select'
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
export interface RadioSchema<$Item = any>
|
|
1472
|
+
extends BaseSchema<$Item>,
|
|
1473
|
+
SchemaOptionsMixin<$Item> {
|
|
1474
|
+
/**
|
|
1475
|
+
* The type of the component.
|
|
1476
|
+
*/
|
|
1477
|
+
type: 'radio'
|
|
1478
|
+
/**
|
|
1479
|
+
* @defaultValue `'vertical'`
|
|
1480
|
+
*/
|
|
1481
|
+
layout?: 'horizontal' | 'vertical'
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
type SectionContent<$Data> = {
|
|
1485
|
+
/** The section's field components. */
|
|
1486
|
+
components?: Components<$Data>
|
|
1487
|
+
/**
|
|
1488
|
+
* A form schema for the section's content. Use this
|
|
1489
|
+
* instead of `components` to get form-level options
|
|
1490
|
+
* like `label`, `tabs`, and `mutate`.
|
|
1491
|
+
*/
|
|
1492
|
+
form?: ResolvableForm<$Data>
|
|
1493
|
+
/**
|
|
1494
|
+
* Display several schemas in different tabs
|
|
1495
|
+
* within the section.
|
|
1496
|
+
*/
|
|
1497
|
+
tabs?: Record<
|
|
1498
|
+
string,
|
|
1499
|
+
Omit<Form<$Data>, 'tabs' | 'type'> & {
|
|
1500
|
+
type: 'tab'
|
|
1501
|
+
defaultTab?: OrItemAccessor<$Data, {}, boolean>
|
|
1502
|
+
}
|
|
1503
|
+
>
|
|
688
1504
|
}
|
|
689
1505
|
|
|
690
|
-
|
|
691
|
-
|
|
1506
|
+
/**
|
|
1507
|
+
* A visual grouping of components within a form.
|
|
1508
|
+
*
|
|
1509
|
+
* By default, the section's components read and write fields
|
|
1510
|
+
* on the parent item directly. When `nested` is `true`, the
|
|
1511
|
+
* section's fields are stored under their own key on the
|
|
1512
|
+
* parent item instead (e.g. `item.address`).
|
|
1513
|
+
*
|
|
1514
|
+
* For non-nested sections, declare the key as `never` in
|
|
1515
|
+
* your item type. For nested sections, declare it as the
|
|
1516
|
+
* object type of the nested data (see {@link Components}).
|
|
1517
|
+
*
|
|
1518
|
+
* @template $Item The parent item type, used for callbacks
|
|
1519
|
+
* like `label` and `collapsible`.
|
|
1520
|
+
* @template $Nested The type of the section's own data.
|
|
1521
|
+
* For nested sections this is the value type at the
|
|
1522
|
+
* section's key (e.g. `Address`). For non-nested sections
|
|
1523
|
+
* this defaults to `$Item`.
|
|
1524
|
+
*
|
|
1525
|
+
* @example Non-nested section (fields stored on parent item)
|
|
1526
|
+
* ```ts
|
|
1527
|
+
* type Item = {
|
|
1528
|
+
* title: string
|
|
1529
|
+
* details: never // UI-only key
|
|
1530
|
+
* }
|
|
1531
|
+
*
|
|
1532
|
+
* const components: Components<Item> = {
|
|
1533
|
+
* details: {
|
|
1534
|
+
* type: 'section',
|
|
1535
|
+
* components: {
|
|
1536
|
+
* title: { type: 'text' }
|
|
1537
|
+
* }
|
|
1538
|
+
* }
|
|
1539
|
+
* }
|
|
1540
|
+
* ```
|
|
1541
|
+
*
|
|
1542
|
+
* @example Nested section (fields stored at `item.address`)
|
|
1543
|
+
* ```ts
|
|
1544
|
+
* type Address = { street: string; city: string }
|
|
1545
|
+
*
|
|
1546
|
+
* type Item = {
|
|
1547
|
+
* title: string
|
|
1548
|
+
* address: Address // data key for nested section
|
|
1549
|
+
* }
|
|
1550
|
+
*
|
|
1551
|
+
* const components: Components<Item> = {
|
|
1552
|
+
* address: {
|
|
1553
|
+
* type: 'section',
|
|
1554
|
+
* nested: true,
|
|
1555
|
+
* components: {
|
|
1556
|
+
* street: { type: 'text' },
|
|
1557
|
+
* city: { type: 'text' }
|
|
1558
|
+
* }
|
|
1559
|
+
* }
|
|
1560
|
+
* }
|
|
1561
|
+
* ```
|
|
1562
|
+
*/
|
|
1563
|
+
export type SectionSchema<$Item = any, $Nested = $Item> = BaseSchema<$Item> &
|
|
1564
|
+
SchemaOpen<$Item> & {
|
|
692
1565
|
/**
|
|
693
1566
|
* The type of the component.
|
|
694
1567
|
*/
|
|
695
|
-
type: '
|
|
696
|
-
/**
|
|
697
|
-
* Whether more than one option can be selected.
|
|
698
|
-
*
|
|
699
|
-
* @defaultValue `false`
|
|
700
|
-
*/
|
|
701
|
-
multiple?: boolean
|
|
702
|
-
// TODO: document searchable
|
|
703
|
-
/**
|
|
704
|
-
* @defaultValue `false`
|
|
705
|
-
*/
|
|
706
|
-
searchable?: boolean
|
|
707
|
-
// TODO: document stayOpen
|
|
708
|
-
/**
|
|
709
|
-
* @defaultValue `false`
|
|
710
|
-
*/
|
|
711
|
-
stayOpen?: boolean
|
|
1568
|
+
type: 'section'
|
|
712
1569
|
/**
|
|
713
|
-
*
|
|
714
|
-
*
|
|
1570
|
+
* Multiple form schemas keyed by item type, for
|
|
1571
|
+
* sections with polymorphic content.
|
|
715
1572
|
*/
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
debounce?:
|
|
719
|
-
| number
|
|
720
|
-
| {
|
|
721
|
-
delay: number
|
|
722
|
-
immediate?: boolean
|
|
723
|
-
}
|
|
1573
|
+
forms?: {
|
|
1574
|
+
[key: string]: ResolvableForm
|
|
724
1575
|
}
|
|
725
1576
|
/**
|
|
1577
|
+
* Renders the section with reduced spacing.
|
|
1578
|
+
*
|
|
726
1579
|
* @defaultValue `false`
|
|
727
1580
|
*/
|
|
728
|
-
|
|
729
|
-
taggable?: boolean
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
export type SelectSchema<$Item = any> = BaseSchema<$Item> &
|
|
733
|
-
SchemaOptionsMixin<$Item> & {
|
|
1581
|
+
compact?: boolean
|
|
734
1582
|
/**
|
|
735
|
-
*
|
|
1583
|
+
* Enables copy/paste for the section's data.
|
|
736
1584
|
*/
|
|
737
|
-
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
export type RadioSchema<$Item = any> = BaseSchema<$Item> &
|
|
741
|
-
SchemaOptionsMixin<$Item> & {
|
|
1585
|
+
clipboard?: ClipboardConfig
|
|
742
1586
|
/**
|
|
743
|
-
*
|
|
1587
|
+
* Whether the section can be collapsed.
|
|
744
1588
|
*/
|
|
745
|
-
|
|
1589
|
+
collapsible?: OrItemAccessor<$Item, {}, boolean>
|
|
1590
|
+
/** Whether the section is collapsed. */
|
|
1591
|
+
collapsed?: OrItemAccessor<$Item, {}, boolean>
|
|
746
1592
|
/**
|
|
747
|
-
*
|
|
1593
|
+
* Grouped event handlers.
|
|
748
1594
|
*/
|
|
749
|
-
|
|
750
|
-
|
|
1595
|
+
events?: {
|
|
1596
|
+
/**
|
|
1597
|
+
* Called when a collapsible section is toggled
|
|
1598
|
+
* open or closed.
|
|
1599
|
+
*/
|
|
1600
|
+
open?: OpenEventHandler<$Item>
|
|
1601
|
+
}
|
|
1602
|
+
} & (
|
|
1603
|
+
| ({
|
|
1604
|
+
/**
|
|
1605
|
+
* Whether the data is stored under its own key
|
|
1606
|
+
* on the parent item. When `true`, an "address"
|
|
1607
|
+
* section stores data at `item.address`. When
|
|
1608
|
+
* `false` or omitted, the section's fields are
|
|
1609
|
+
* stored directly on the parent item.
|
|
1610
|
+
*
|
|
1611
|
+
* @defaultValue `false`
|
|
1612
|
+
*/
|
|
1613
|
+
nested?: false
|
|
1614
|
+
} & SectionContent<$Item>)
|
|
1615
|
+
| ({
|
|
1616
|
+
/**
|
|
1617
|
+
* Whether the data is stored under its own key
|
|
1618
|
+
* on the parent item. When `true`, an "address"
|
|
1619
|
+
* section stores data at `item.address`. When
|
|
1620
|
+
* `false` or omitted, the section's fields are
|
|
1621
|
+
* stored directly on the parent item.
|
|
1622
|
+
*
|
|
1623
|
+
* @defaultValue `false`
|
|
1624
|
+
*/
|
|
1625
|
+
nested: true
|
|
1626
|
+
} & SectionContent<$Nested>)
|
|
1627
|
+
)
|
|
751
1628
|
|
|
752
|
-
export
|
|
1629
|
+
export interface CheckboxSchema<$Item = any> extends BaseSchema<$Item> {
|
|
753
1630
|
/**
|
|
754
1631
|
* The type of the component.
|
|
755
1632
|
*/
|
|
756
|
-
type: '
|
|
757
|
-
components?: Components<$Item>
|
|
1633
|
+
type: 'checkbox'
|
|
758
1634
|
}
|
|
759
1635
|
|
|
760
|
-
export
|
|
1636
|
+
export interface CheckboxesSchema<$Item = any>
|
|
1637
|
+
extends BaseSchema<$Item>,
|
|
1638
|
+
SchemaOptionsMixin<$Item> {
|
|
761
1639
|
/**
|
|
762
1640
|
* The type of the component.
|
|
763
1641
|
*/
|
|
764
|
-
type: '
|
|
1642
|
+
type: 'checkboxes'
|
|
1643
|
+
/**
|
|
1644
|
+
* @defaultValue `'vertical'`
|
|
1645
|
+
*/
|
|
1646
|
+
layout?: 'horizontal' | 'vertical'
|
|
765
1647
|
}
|
|
766
1648
|
|
|
767
|
-
export type CheckboxesSchema<$Item = any> = BaseSchema<$Item> &
|
|
768
|
-
SchemaOptionsMixin<$Item> & {
|
|
769
|
-
/**
|
|
770
|
-
* The type of the component.
|
|
771
|
-
*/
|
|
772
|
-
type: 'checkboxes'
|
|
773
|
-
/**
|
|
774
|
-
* @defaultValue `'vertical'`
|
|
775
|
-
*/
|
|
776
|
-
layout?: 'horizontal' | 'vertical'
|
|
777
|
-
}
|
|
778
|
-
|
|
779
1649
|
export type ColorFormat =
|
|
780
1650
|
| 'rgb'
|
|
781
1651
|
| 'prgb'
|
|
@@ -787,7 +1657,9 @@ export type ColorFormat =
|
|
|
787
1657
|
| 'name'
|
|
788
1658
|
| 'hsl'
|
|
789
1659
|
| 'hsv'
|
|
790
|
-
export
|
|
1660
|
+
export interface ColorSchema<$Item = any>
|
|
1661
|
+
extends BaseSchema<$Item>,
|
|
1662
|
+
SchemaAffixMixin<$Item> {
|
|
791
1663
|
/**
|
|
792
1664
|
* The type of the component.
|
|
793
1665
|
*/
|
|
@@ -803,10 +1675,9 @@ export type ColorSchema<$Item = any> = BaseSchema<$Item> & {
|
|
|
803
1675
|
*/
|
|
804
1676
|
alpha?: OrItemAccessor<$Item, {}, boolean>
|
|
805
1677
|
/**
|
|
806
|
-
*
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
/**
|
|
1678
|
+
* Whether to display input fields for manual color value
|
|
1679
|
+
* entry (e.g. RGB, HSL) in the color picker.
|
|
1680
|
+
*
|
|
810
1681
|
* @defaultValue `true`
|
|
811
1682
|
*/
|
|
812
1683
|
inputs?: OrItemAccessor<$Item, {}, boolean>
|
|
@@ -818,7 +1689,7 @@ export type ColorSchema<$Item = any> = BaseSchema<$Item> & {
|
|
|
818
1689
|
presets?: OrItemAccessor<$Item, {}, string[]>
|
|
819
1690
|
}
|
|
820
1691
|
|
|
821
|
-
export type ColumnSchema<$Item = any> = {
|
|
1692
|
+
export type ColumnSchema<$Item = any, $Value = any> = {
|
|
822
1693
|
/**
|
|
823
1694
|
* The label of the column.
|
|
824
1695
|
* @defaultValue The labelized column key.
|
|
@@ -838,7 +1709,7 @@ export type ColumnSchema<$Item = any> = {
|
|
|
838
1709
|
* If the column is sortable, the column is sorted by value and not by
|
|
839
1710
|
* rendered name.
|
|
840
1711
|
*/
|
|
841
|
-
render?: ItemAccessor<$Item, {}, string>
|
|
1712
|
+
render?: ItemAccessor<$Item, { value: $Value }, string | null | undefined>
|
|
842
1713
|
/**
|
|
843
1714
|
* The provided string is applied to the class property of the column
|
|
844
1715
|
* cell html elements.
|
|
@@ -854,91 +1725,69 @@ export type ColumnSchema<$Item = any> = {
|
|
|
854
1725
|
* first column to specify `defaultSort`.
|
|
855
1726
|
*/
|
|
856
1727
|
defaultSort?: 'asc' | 'desc'
|
|
857
|
-
/**
|
|
858
|
-
|
|
859
|
-
*/
|
|
860
|
-
if?: ItemAccessor<$Item, {}, boolean>
|
|
1728
|
+
/** Whether to display the column. */
|
|
1729
|
+
if?: OrItemAccessor<$Item, {}, boolean>
|
|
861
1730
|
}
|
|
862
1731
|
|
|
1732
|
+
/**
|
|
1733
|
+
* A form that can be provided directly, as a record of named forms
|
|
1734
|
+
* (e.g. a module namespace from `import()`), wrapped in a promise,
|
|
1735
|
+
* or returned from a function.
|
|
1736
|
+
*/
|
|
863
1737
|
export type ResolvableForm<$Item = any> = Resolvable<Form<$Item>>
|
|
864
1738
|
|
|
865
|
-
export
|
|
866
|
-
SchemaSourceMixin<$Item
|
|
867
|
-
BaseSchema<$Item
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
* The form.
|
|
874
|
-
*/
|
|
875
|
-
form?: ResolvableForm
|
|
876
|
-
/**
|
|
877
|
-
* The forms.
|
|
878
|
-
*/
|
|
879
|
-
forms?: {
|
|
880
|
-
[key: string]: ResolvableForm
|
|
881
|
-
}
|
|
882
|
-
/**
|
|
883
|
-
* The label given to the items. If no itemLabel is given, the default is
|
|
884
|
-
* the 'name' property of the item, followed by label of the form of the
|
|
885
|
-
* view (plus item id) and other defaults.
|
|
886
|
-
*/
|
|
887
|
-
itemLabel?: OrItemAccessor<any, {}, string>
|
|
888
|
-
/**
|
|
889
|
-
* The columns displayed in the table. While columns can be supplied as an
|
|
890
|
-
* array where each entry is the name of a property of the item, it is
|
|
891
|
-
* usually beneficial to assign an object with further options to the
|
|
892
|
-
* columns property.
|
|
893
|
-
*/
|
|
894
|
-
columns?: Record<string, ColumnSchema<$Item>> | (keyof $Item)[]
|
|
895
|
-
/**
|
|
896
|
-
* Scope names as defined on the model. When set, the admin renders a set
|
|
897
|
-
* of scope buttons, allowing the user to switch between them while
|
|
898
|
-
* editing.
|
|
899
|
-
*/
|
|
900
|
-
scopes?:
|
|
901
|
-
| string[]
|
|
902
|
-
| {
|
|
903
|
-
[scopeName: string]:
|
|
904
|
-
| {
|
|
905
|
-
label?: string
|
|
906
|
-
hint?: string
|
|
907
|
-
defaultScope?: boolean
|
|
908
|
-
}
|
|
909
|
-
| string
|
|
910
|
-
}
|
|
911
|
-
/**
|
|
912
|
-
* Default scope name as defined on the model.
|
|
913
|
-
*/
|
|
914
|
-
scope?: string
|
|
1739
|
+
export interface ListSchema<$Item = { [key: string]: any }>
|
|
1740
|
+
extends SchemaSourceMixin<$Item>,
|
|
1741
|
+
BaseSchema<$Item>,
|
|
1742
|
+
SchemaOpen<$Item> {
|
|
1743
|
+
/**
|
|
1744
|
+
* The type of the component.
|
|
1745
|
+
*/
|
|
1746
|
+
type: 'list'
|
|
915
1747
|
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
1748
|
+
/**
|
|
1749
|
+
* Filter definitions that render a filter panel above the
|
|
1750
|
+
* list, allowing users to filter displayed items. Each
|
|
1751
|
+
* filter can be a text filter with operators, a date-range
|
|
1752
|
+
* filter, or a custom filter with components.
|
|
1753
|
+
*/
|
|
1754
|
+
filters?: {
|
|
1755
|
+
/**
|
|
1756
|
+
* Whether the filters panel header sticks to
|
|
1757
|
+
* the top of the scroll container.
|
|
1758
|
+
*/
|
|
1759
|
+
sticky?: boolean
|
|
1760
|
+
[k: string]:
|
|
1761
|
+
| {
|
|
1762
|
+
label?: string
|
|
1763
|
+
filter: 'text'
|
|
1764
|
+
/**
|
|
1765
|
+
* @defaultValue `['contains']`
|
|
1766
|
+
*/
|
|
1767
|
+
operators?: ('contains' | 'equals' | 'starts-with' | 'ends-with')[]
|
|
1768
|
+
}
|
|
1769
|
+
| {
|
|
1770
|
+
label?: string
|
|
1771
|
+
filter: 'date-range'
|
|
1772
|
+
}
|
|
1773
|
+
| {
|
|
1774
|
+
label?: string
|
|
1775
|
+
components: Components
|
|
1776
|
+
}
|
|
1777
|
+
| boolean
|
|
1778
|
+
| undefined
|
|
1779
|
+
}
|
|
1780
|
+
/**
|
|
1781
|
+
* Grouped event handlers.
|
|
1782
|
+
*/
|
|
1783
|
+
events?: {
|
|
1784
|
+
/**
|
|
1785
|
+
* Called when a collapsible inlined list is
|
|
1786
|
+
* toggled open or closed.
|
|
1787
|
+
*/
|
|
1788
|
+
open?: OpenEventHandler<$Item>
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
942
1791
|
|
|
943
1792
|
export type OrItemAccessor<
|
|
944
1793
|
$Item = any,
|
|
@@ -946,87 +1795,186 @@ export type OrItemAccessor<
|
|
|
946
1795
|
$ReturnValue = any
|
|
947
1796
|
> = ItemAccessor<$Item, $Params, $ReturnValue> | $ReturnValue
|
|
948
1797
|
|
|
1798
|
+
/**
|
|
1799
|
+
* Merges two object types into a single flat mapped type.
|
|
1800
|
+
* Unlike `A & B`, this preserves contextual typing for
|
|
1801
|
+
* callback parameters in complex intersections.
|
|
1802
|
+
*/
|
|
1803
|
+
type Merge<A, B> = {
|
|
1804
|
+
[K in keyof A | keyof B]: K extends keyof B
|
|
1805
|
+
? B[K]
|
|
1806
|
+
: K extends keyof A
|
|
1807
|
+
? A[K]
|
|
1808
|
+
: never
|
|
1809
|
+
}
|
|
1810
|
+
|
|
949
1811
|
export type ItemAccessor<
|
|
950
1812
|
$Item = any,
|
|
951
1813
|
$Params extends {} = {},
|
|
952
1814
|
$ReturnValue = any
|
|
953
|
-
> = (params: DitoContext<$Item
|
|
1815
|
+
> = (params: Merge<DitoContext<$Item>, $Params>) => $ReturnValue
|
|
954
1816
|
|
|
955
1817
|
export type DitoContext<$Item = any> = {
|
|
956
1818
|
/**
|
|
957
|
-
* `
|
|
958
|
-
* `false` when it points to the item itself.
|
|
1819
|
+
* `true` when the data-path points to a value inside
|
|
1820
|
+
* an item, `false` when it points to the item itself.
|
|
959
1821
|
*/
|
|
960
1822
|
nested: boolean
|
|
1823
|
+
/** The current value of the component. */
|
|
961
1824
|
value: any
|
|
1825
|
+
/** Full dot-separated path to the current data. */
|
|
962
1826
|
dataPath: string
|
|
1827
|
+
/** The property name of the current component. */
|
|
963
1828
|
name: string
|
|
964
|
-
index
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
/**
|
|
971
|
-
*
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1829
|
+
/** The index within a list, if applicable. */
|
|
1830
|
+
index: number | null
|
|
1831
|
+
/**
|
|
1832
|
+
* Data path of the closest item ancestor.
|
|
1833
|
+
*/
|
|
1834
|
+
itemDataPath: string
|
|
1835
|
+
/**
|
|
1836
|
+
* Data path of the parent item ancestor.
|
|
1837
|
+
*/
|
|
1838
|
+
parentItemDataPath: string
|
|
1839
|
+
/** Index of the closest item in its list. */
|
|
1840
|
+
itemIndex: number | null
|
|
1841
|
+
/** Index of the parent item in its list. */
|
|
1842
|
+
parentItemIndex: number | null
|
|
1843
|
+
/** The current data item. */
|
|
1844
|
+
item: OmitNever<$Item>
|
|
1845
|
+
/**
|
|
1846
|
+
* NOTE: `parentItem` isn't the closest data parent to `item`,
|
|
1847
|
+
* it's the closest parent that isn't an array, e.g. for
|
|
1848
|
+
* relations or nested JSON data. This is why the term `item`
|
|
1849
|
+
* was chosen over `data`, e.g. VS the use of `parentData` in
|
|
1850
|
+
* server-sided validation, which is the closest parent.
|
|
977
1851
|
*/
|
|
978
1852
|
parentItem: any
|
|
1853
|
+
/** The top-level root data item. */
|
|
979
1854
|
rootItem: any
|
|
1855
|
+
/**
|
|
1856
|
+
* The cloned data being prepared for server
|
|
1857
|
+
* submission. Available during `process` callbacks,
|
|
1858
|
+
* allowing modification of sibling fields.
|
|
1859
|
+
*/
|
|
980
1860
|
processedItem: any
|
|
1861
|
+
/**
|
|
1862
|
+
* The root-level cloned data being prepared for
|
|
1863
|
+
* server submission.
|
|
1864
|
+
*/
|
|
1865
|
+
processedRootItem: any
|
|
1866
|
+
/**
|
|
1867
|
+
* The form's current data processed for clipboard
|
|
1868
|
+
* copy/paste operations.
|
|
1869
|
+
*/
|
|
981
1870
|
clipboardItem: any
|
|
1871
|
+
/** The currently authenticated user. */
|
|
982
1872
|
user: {
|
|
983
1873
|
roles?: string[]
|
|
984
1874
|
hasRole(...roles: string[]): boolean
|
|
985
1875
|
}
|
|
1876
|
+
/** The admin API configuration. */
|
|
986
1877
|
api: ApiConfig
|
|
987
|
-
|
|
1878
|
+
/** The schema definition for the current component. */
|
|
1879
|
+
schema: Component | null
|
|
1880
|
+
/** All registered top-level views. */
|
|
1881
|
+
views: Record<string, View>
|
|
1882
|
+
/** All views flattened into a single record. */
|
|
1883
|
+
flattenedViews: Record<string, ViewSchema>
|
|
1884
|
+
/** Display label of the current item. */
|
|
988
1885
|
itemLabel: string | null
|
|
1886
|
+
/** Display label of the current form. */
|
|
989
1887
|
formLabel: string | null
|
|
990
|
-
component
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1888
|
+
/** The current Vue component instance. */
|
|
1889
|
+
component: DitoComponentInstanceBase | null
|
|
1890
|
+
/**
|
|
1891
|
+
* The nearest ancestor `DitoSchema` component that
|
|
1892
|
+
* manages this field's layout.
|
|
1893
|
+
*/
|
|
1894
|
+
schemaComponent: DitoSchemaInstance | null
|
|
1895
|
+
/** The nearest ancestor form component. */
|
|
1896
|
+
formComponent: DitoFormInstance
|
|
1897
|
+
/** The nearest ancestor view component. */
|
|
1898
|
+
viewComponent: DitoViewInstance | null
|
|
1899
|
+
/** The nearest ancestor dialog component. */
|
|
1900
|
+
dialogComponent: DitoComponentInstanceBase | null
|
|
1901
|
+
/** The nearest ancestor panel component. */
|
|
1902
|
+
panelComponent: DitoComponentInstanceBase | null
|
|
1903
|
+
/** The nearest ancestor resource component. */
|
|
1904
|
+
resourceComponent:
|
|
1905
|
+
| DitoFormInstance
|
|
1906
|
+
| DitoSourceInstance
|
|
1907
|
+
| null
|
|
1908
|
+
/** The nearest ancestor source component. */
|
|
1909
|
+
sourceComponent: DitoSourceInstance | null
|
|
1910
|
+
/** The currently focused option in a select. */
|
|
998
1911
|
option: any
|
|
1912
|
+
/** All available options in a select. */
|
|
999
1913
|
options: any
|
|
1000
|
-
|
|
1001
|
-
|
|
1914
|
+
/**
|
|
1915
|
+
* Whether a pulldown/select is currently open.
|
|
1916
|
+
*/
|
|
1917
|
+
open: boolean | undefined
|
|
1918
|
+
/**
|
|
1919
|
+
* The current search term in select components.
|
|
1920
|
+
*/
|
|
1921
|
+
searchTerm: string | undefined
|
|
1922
|
+
/**
|
|
1923
|
+
* Whether a button request is currently running.
|
|
1924
|
+
*/
|
|
1925
|
+
isRunning: boolean
|
|
1926
|
+
/** Current URL query parameters. */
|
|
1927
|
+
query: Record<string, string | (string | null)[]>
|
|
1928
|
+
/**
|
|
1929
|
+
* The error object, populated in button `error`
|
|
1930
|
+
* event handler contexts.
|
|
1931
|
+
*/
|
|
1932
|
+
error: unknown
|
|
1933
|
+
/**
|
|
1934
|
+
* Whether the event handler already called
|
|
1935
|
+
* `context.notify()`, used to suppress the default
|
|
1936
|
+
* notification for button events.
|
|
1937
|
+
*/
|
|
1002
1938
|
wasNotified: boolean
|
|
1003
1939
|
|
|
1004
1940
|
// Helper Methods
|
|
1005
1941
|
|
|
1942
|
+
/** Performs an API request with optional caching. */
|
|
1006
1943
|
request<T>(options: {
|
|
1007
1944
|
/**
|
|
1008
1945
|
* Allows caching of loaded data on two levels:
|
|
1009
1946
|
* - 'global': cache globally, for the entire admin session
|
|
1010
|
-
* - 'local': cache locally within the closest route
|
|
1011
|
-
* associated with a resource and loads
|
|
1947
|
+
* - 'local': cache locally within the closest route
|
|
1948
|
+
* component that is associated with a resource and loads
|
|
1949
|
+
* its own data.
|
|
1012
1950
|
*/
|
|
1013
1951
|
cache?: 'local' | 'global'
|
|
1014
1952
|
url: string
|
|
1015
1953
|
/**
|
|
1016
1954
|
* @default 'get'
|
|
1017
1955
|
*/
|
|
1018
|
-
method?:
|
|
1019
|
-
query?:
|
|
1020
|
-
|
|
1956
|
+
method?: HTTPMethod
|
|
1957
|
+
query?:
|
|
1958
|
+
| Record<string, string | number | (string | number)[]>
|
|
1959
|
+
| [string, string | number][]
|
|
1960
|
+
data?: unknown
|
|
1021
1961
|
resource?: Resource
|
|
1022
1962
|
}): Promise<T>
|
|
1963
|
+
/** Formats values using locale-aware formatters. */
|
|
1023
1964
|
format: typeof utilsFormat
|
|
1965
|
+
/** Navigates to a route programmatically. */
|
|
1024
1966
|
navigate: VueRouter['push']
|
|
1967
|
+
/**
|
|
1968
|
+
* Triggers a file download from the given URL or
|
|
1969
|
+
* options.
|
|
1970
|
+
*/
|
|
1025
1971
|
download: {
|
|
1026
1972
|
(url: string): void
|
|
1027
1973
|
(options: { url: string; filename: string }): void
|
|
1028
1974
|
}
|
|
1029
|
-
|
|
1975
|
+
/** Returns the full URL for a given resource. */
|
|
1976
|
+
getResourceUrl(resource: Resource): string
|
|
1977
|
+
/** Displays a notification to the user. */
|
|
1030
1978
|
notify(options: {
|
|
1031
1979
|
type?: LiteralUnion<'warning' | 'error' | 'info' | 'success'>
|
|
1032
1980
|
title?: string
|
|
@@ -1034,21 +1982,950 @@ export type DitoContext<$Item = any> = {
|
|
|
1034
1982
|
}): void
|
|
1035
1983
|
}
|
|
1036
1984
|
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1985
|
+
/**
|
|
1986
|
+
* The `this` type inside schema `methods`, `computed`,
|
|
1987
|
+
* and `watch` handlers. Unlike the context passed to
|
|
1988
|
+
* schema accessors like `if` and `label`, this is the
|
|
1989
|
+
* live component instance.
|
|
1990
|
+
*
|
|
1991
|
+
* @template $Item The data item type.
|
|
1992
|
+
* @template $Members Additional schema-defined methods
|
|
1993
|
+
* and computed properties available on `this`.
|
|
1994
|
+
*/
|
|
1995
|
+
export type DitoComponentInstance<
|
|
1996
|
+
$Item = any,
|
|
1997
|
+
$Members extends Record<string, any> = {}
|
|
1998
|
+
> = DitoComponentInstanceBase<$Item> & $Members
|
|
1999
|
+
|
|
2000
|
+
export interface DitoComponentInstanceBase<$Item = any> extends EmitterMixin {
|
|
2001
|
+
// -- Data access (ValueMixin, ContextMixin, TypeMixin) --
|
|
2002
|
+
|
|
2003
|
+
/** The current value of the component (getter/setter). */
|
|
2004
|
+
value: any
|
|
2005
|
+
/** The current data item. */
|
|
2006
|
+
item: OmitNever<$Item>
|
|
2007
|
+
/**
|
|
2008
|
+
* The closest parent item that isn't an array (e.g.
|
|
2009
|
+
* for relations or nested JSON data).
|
|
2010
|
+
*/
|
|
2011
|
+
parentItem: any
|
|
2012
|
+
/** The top-level root data item. */
|
|
2013
|
+
rootItem: any
|
|
2014
|
+
/**
|
|
2015
|
+
* The cloned data being prepared for server
|
|
2016
|
+
* submission. Available during `process` callbacks.
|
|
2017
|
+
*/
|
|
2018
|
+
processedItem: any
|
|
2019
|
+
/** The root-level cloned data for server submission. */
|
|
2020
|
+
processedRootItem: any
|
|
2021
|
+
/** The component's data object. */
|
|
2022
|
+
data: Record<string, any>
|
|
2023
|
+
/** Parent data object, or `null` if same as data. */
|
|
2024
|
+
parentData: Record<string, any> | null
|
|
2025
|
+
/** The property name of the current component. */
|
|
2026
|
+
name: string
|
|
2027
|
+
/** Full dot-separated path to the current data. */
|
|
2028
|
+
dataPath: string
|
|
2029
|
+
/** The schema definition for the current component. */
|
|
2030
|
+
schema: Component
|
|
2031
|
+
/** The component type from the schema. */
|
|
2032
|
+
type: string
|
|
2033
|
+
|
|
2034
|
+
// -- State (TypeMixin, ValidationMixin) --
|
|
2035
|
+
|
|
2036
|
+
/** Whether the component currently has focus. */
|
|
2037
|
+
focused: boolean
|
|
2038
|
+
/** The value after applying `schema.parse()`. */
|
|
2039
|
+
parsedValue: any
|
|
2040
|
+
/** Whether the field has been focused at least once. */
|
|
2041
|
+
isTouched: boolean
|
|
2042
|
+
/** Whether the field value has been modified. */
|
|
2043
|
+
isDirty: boolean
|
|
2044
|
+
/** Whether the field is currently valid. */
|
|
2045
|
+
isValid: boolean
|
|
2046
|
+
/** Whether validation has been run on the field. */
|
|
2047
|
+
isValidated: boolean
|
|
2048
|
+
/** Validation error messages, or `null`. */
|
|
2049
|
+
errors: string[] | null
|
|
2050
|
+
/** Whether the field has validation errors. */
|
|
2051
|
+
hasErrors: boolean
|
|
2052
|
+
/** Whether async data is currently being loaded. */
|
|
2053
|
+
isLoading: boolean
|
|
2054
|
+
/**
|
|
2055
|
+
* Sets the loading state. Optionally propagates
|
|
2056
|
+
* to the root or view component.
|
|
2057
|
+
*/
|
|
2058
|
+
setLoading(
|
|
2059
|
+
isLoading: boolean,
|
|
2060
|
+
options?: { updateRoot?: boolean; updateView?: boolean }
|
|
2061
|
+
): void
|
|
2062
|
+
/**
|
|
2063
|
+
* Whether the component works with data not yet
|
|
2064
|
+
* persisted to the server.
|
|
2065
|
+
*/
|
|
2066
|
+
isTransient: boolean
|
|
2067
|
+
/** Whether the component is mounted. */
|
|
2068
|
+
isMounted: boolean
|
|
2069
|
+
/** Whether the component tree is populated. */
|
|
2070
|
+
isPopulated: boolean
|
|
2071
|
+
/**
|
|
2072
|
+
* Whether this component loads its own data from
|
|
2073
|
+
* a resource.
|
|
2074
|
+
*/
|
|
2075
|
+
providesData: boolean
|
|
2076
|
+
/** The schema of the source component. */
|
|
2077
|
+
sourceSchema: Component | null
|
|
2078
|
+
/** Action verb labels (create, save, delete, etc.). */
|
|
2079
|
+
verbs: Record<string, string>
|
|
2080
|
+
|
|
2081
|
+
// -- Resolved schema accessors (TypeMixin) --
|
|
2082
|
+
|
|
2083
|
+
/** Resolved `schema.visible` value. */
|
|
2084
|
+
visible: boolean
|
|
2085
|
+
/** Resolved `schema.exclude` value. */
|
|
2086
|
+
exclude: boolean
|
|
2087
|
+
/** Resolved `schema.required` value. */
|
|
2088
|
+
required: boolean
|
|
2089
|
+
/** Resolved `schema.readonly` value. */
|
|
2090
|
+
readonly: boolean
|
|
2091
|
+
/** Resolved `schema.disabled` value. */
|
|
2092
|
+
disabled: boolean
|
|
2093
|
+
/** Resolved `schema.clearable` value. */
|
|
2094
|
+
clearable: boolean
|
|
2095
|
+
/** Resolved `schema.autofocus` value. */
|
|
2096
|
+
autofocus: boolean
|
|
2097
|
+
/** Resolved `schema.placeholder` value. */
|
|
2098
|
+
placeholder: string | undefined
|
|
2099
|
+
/** Resolved `schema.info` value. */
|
|
2100
|
+
info: string | null
|
|
2101
|
+
/** Resolved `schema.maxLength` value. */
|
|
2102
|
+
maxLength: number | undefined
|
|
2103
|
+
/** Resolved `schema.autocomplete` value. */
|
|
2104
|
+
autocomplete: string | undefined
|
|
2105
|
+
|
|
2106
|
+
// -- Component hierarchy (DitoMixin) --
|
|
2107
|
+
|
|
2108
|
+
/** The `DitoContext` for this component. */
|
|
2109
|
+
context: DitoContext<$Item>
|
|
2110
|
+
/** The nearest `DitoSchema` managing layout. */
|
|
2111
|
+
schemaComponent: DitoSchemaInstance
|
|
2112
|
+
/** The nearest ancestor form component. */
|
|
2113
|
+
formComponent: DitoFormInstance
|
|
2114
|
+
/** The nearest ancestor view component. */
|
|
2115
|
+
viewComponent: DitoViewInstance | null
|
|
2116
|
+
/** The nearest ancestor dialog component. */
|
|
2117
|
+
dialogComponent: DitoComponentInstanceBase | null
|
|
2118
|
+
/** The nearest ancestor panel component. */
|
|
2119
|
+
panelComponent: DitoComponentInstanceBase | null
|
|
2120
|
+
/** The nearest ancestor resource component. */
|
|
2121
|
+
resourceComponent: DitoFormInstance | DitoSourceInstance
|
|
2122
|
+
/** The nearest ancestor source component. */
|
|
2123
|
+
sourceComponent: DitoSourceInstance
|
|
2124
|
+
/**
|
|
2125
|
+
* The nearest route component (form or view) in the
|
|
2126
|
+
* ancestor chain.
|
|
2127
|
+
*/
|
|
2128
|
+
routeComponent: DitoFormInstance | DitoViewInstance | null
|
|
2129
|
+
/**
|
|
2130
|
+
* The first parent route component that provides and
|
|
2131
|
+
* loads its own data from the API.
|
|
2132
|
+
*/
|
|
2133
|
+
dataComponent: DitoFormInstance | DitoViewInstance | null
|
|
2134
|
+
/** The parent schema component. */
|
|
2135
|
+
parentSchemaComponent: DitoComponentInstanceBase | null
|
|
2136
|
+
/** The parent form component. */
|
|
2137
|
+
parentFormComponent: DitoComponentInstanceBase | null
|
|
2138
|
+
/** The root component instance. */
|
|
2139
|
+
rootComponent: DitoComponentInstanceBase | null
|
|
2140
|
+
/** The nearest ancestor tab component. */
|
|
2141
|
+
tabComponent: DitoComponentInstanceBase | null
|
|
2142
|
+
/** The parent route component. */
|
|
2143
|
+
parentRouteComponent:
|
|
2144
|
+
| DitoFormInstance
|
|
2145
|
+
| DitoViewInstance
|
|
2146
|
+
| null
|
|
2147
|
+
/** The parent resource component. */
|
|
2148
|
+
parentResourceComponent:
|
|
2149
|
+
| DitoFormInstance
|
|
2150
|
+
| DitoSourceInstance
|
|
2151
|
+
| null
|
|
2152
|
+
|
|
2153
|
+
// -- Environment (DitoMixin) --
|
|
2154
|
+
|
|
2155
|
+
/** The currently authenticated user. */
|
|
2156
|
+
user: DitoContext['user']
|
|
2157
|
+
/** The admin API configuration. */
|
|
2158
|
+
api: ApiConfig
|
|
2159
|
+
/** Current locale from the API config. */
|
|
2160
|
+
locale: string
|
|
2161
|
+
/** All registered top-level views. */
|
|
2162
|
+
views: Record<string, View>
|
|
2163
|
+
/** All views flattened into a single record. */
|
|
2164
|
+
flattenedViews: Record<string, ViewSchema>
|
|
2165
|
+
/** Data from the first parent route that loads data. */
|
|
2166
|
+
rootData: any
|
|
2167
|
+
|
|
2168
|
+
// -- Actions (DitoMixin) --
|
|
2169
|
+
|
|
2170
|
+
/** Performs an API request with optional caching. */
|
|
2171
|
+
request: DitoContext['request']
|
|
2172
|
+
/** Formats values using locale-aware formatters. */
|
|
2173
|
+
format: DitoContext['format']
|
|
2174
|
+
/** Navigates to a route programmatically. */
|
|
2175
|
+
navigate: DitoContext['navigate']
|
|
2176
|
+
/** Triggers a file download. */
|
|
2177
|
+
download: DitoContext['download']
|
|
2178
|
+
/** Displays a notification to the user. */
|
|
2179
|
+
notify: DitoContext['notify']
|
|
2180
|
+
/** Returns the full URL for a given resource. */
|
|
2181
|
+
getResourceUrl: DitoContext['getResourceUrl']
|
|
2182
|
+
/**
|
|
2183
|
+
* Sends an HTTP request to the API.
|
|
2184
|
+
*/
|
|
2185
|
+
sendRequest(options: {
|
|
2186
|
+
method?: HTTPMethod
|
|
2187
|
+
url?: string
|
|
2188
|
+
resource?: Resource
|
|
2189
|
+
query?:
|
|
2190
|
+
| Record<string, string | number | (string | number)[]>
|
|
2191
|
+
| [string, string | number][]
|
|
2192
|
+
data?: unknown
|
|
2193
|
+
signal?: AbortSignal
|
|
2194
|
+
internal?: boolean
|
|
2195
|
+
}): Promise<unknown>
|
|
2196
|
+
/**
|
|
2197
|
+
* Shows a modal dialog and returns a promise that
|
|
2198
|
+
* resolves with the dialog result.
|
|
2199
|
+
*/
|
|
2200
|
+
showDialog(options: {
|
|
2201
|
+
components?: Components
|
|
2202
|
+
buttons?: Buttons<any>
|
|
2203
|
+
data?: Record<string, any>
|
|
2204
|
+
settings?: Record<string, any>
|
|
2205
|
+
}): Promise<unknown>
|
|
2206
|
+
/**
|
|
2207
|
+
* Resolves a schema value by key or data-path,
|
|
2208
|
+
* with optional type coercion and default.
|
|
2209
|
+
*/
|
|
2210
|
+
getSchemaValue(
|
|
2211
|
+
keyOrDataPath: string,
|
|
2212
|
+
options?: {
|
|
2213
|
+
type?: Function | Function[]
|
|
2214
|
+
default?: any
|
|
2215
|
+
schema?: Component
|
|
2216
|
+
context?: DitoContext
|
|
2217
|
+
callback?: boolean
|
|
2218
|
+
}
|
|
2219
|
+
): any
|
|
2220
|
+
/** Returns a human-readable label for a schema. */
|
|
2221
|
+
getLabel(
|
|
2222
|
+
schema: Component | null,
|
|
2223
|
+
name?: string
|
|
2224
|
+
): string
|
|
2225
|
+
/**
|
|
2226
|
+
* Returns a Vue Router location object with the
|
|
2227
|
+
* given query params and the current hash
|
|
2228
|
+
* preserved (for tab navigation).
|
|
2229
|
+
*/
|
|
2230
|
+
getQueryLink(
|
|
2231
|
+
query: Record<string, any>
|
|
2232
|
+
): { query: Record<string, any>; hash: string }
|
|
2233
|
+
/**
|
|
2234
|
+
* Returns `true` if the schema's `if` accessor
|
|
2235
|
+
* evaluates to `true` (or is absent).
|
|
2236
|
+
*/
|
|
2237
|
+
shouldRenderSchema(
|
|
2238
|
+
schema?: Component | null
|
|
2239
|
+
): boolean
|
|
2240
|
+
/**
|
|
2241
|
+
* Returns the resolved `visible` value for a
|
|
2242
|
+
* schema. Defaults to `true`.
|
|
2243
|
+
*/
|
|
2244
|
+
shouldShowSchema(
|
|
2245
|
+
schema?: Component | null
|
|
2246
|
+
): boolean
|
|
2247
|
+
/**
|
|
2248
|
+
* Returns the resolved `disabled` value for a
|
|
2249
|
+
* schema. Defaults to `false`.
|
|
2250
|
+
*/
|
|
2251
|
+
shouldDisableSchema(
|
|
2252
|
+
schema?: Component | null
|
|
2253
|
+
): boolean
|
|
2254
|
+
/**
|
|
2255
|
+
* Emits a schema event by name (e.g. `'change'`,
|
|
2256
|
+
* `'focus'`). Calls the matching `on[Event]`
|
|
2257
|
+
* handler and the `events[event]` handler on the
|
|
2258
|
+
* schema. Returns the handler result, or
|
|
2259
|
+
* `undefined` if no handler was found. The event
|
|
2260
|
+
* bubbles to parent schemas unless the handler
|
|
2261
|
+
* returns `false`.
|
|
2262
|
+
*
|
|
2263
|
+
* @param event The event name to emit.
|
|
2264
|
+
* @param options.context Custom context properties
|
|
2265
|
+
* merged into the `DitoContext` passed to the
|
|
2266
|
+
* event handler.
|
|
2267
|
+
*/
|
|
2268
|
+
emitEvent(
|
|
2269
|
+
event: string,
|
|
2270
|
+
options?: {
|
|
2271
|
+
context?: DitoContext
|
|
1043
2272
|
}
|
|
2273
|
+
): Promise<any>
|
|
2274
|
+
/**
|
|
2275
|
+
* Emits a schema event on the nearest schema
|
|
2276
|
+
* component (rather than `this`). Used by form
|
|
2277
|
+
* and resource components to emit lifecycle
|
|
2278
|
+
* events like `'load'` and `'submit'`.
|
|
2279
|
+
*/
|
|
2280
|
+
emitSchemaEvent(
|
|
2281
|
+
event: string,
|
|
2282
|
+
params?: Record<string, any>
|
|
2283
|
+
): Promise<any>
|
|
2284
|
+
/** Converts a camelCase name to a human-readable label. */
|
|
2285
|
+
labelize(name: string): string
|
|
2286
|
+
/** Gets a value from the component store. */
|
|
2287
|
+
getStore(key: string): any
|
|
2288
|
+
/** Sets a value in the component store. */
|
|
2289
|
+
setStore(key: string, value: any): any
|
|
2290
|
+
/** Removes a value from the component store. */
|
|
2291
|
+
removeStore(key: string): void
|
|
2292
|
+
|
|
2293
|
+
// -- Actions (TypeMixin) --
|
|
2294
|
+
|
|
2295
|
+
/** Focuses the component and scrolls it into view. */
|
|
2296
|
+
focus(): Promise<void>
|
|
2297
|
+
/** Blurs the component. */
|
|
2298
|
+
blur(): void
|
|
2299
|
+
/** Clears the value, blurs, and triggers onChange. */
|
|
2300
|
+
clear(): void
|
|
2301
|
+
/** Scrolls the component into view. */
|
|
2302
|
+
scrollIntoView(): Promise<void>
|
|
2303
|
+
|
|
2304
|
+
// -- Actions (ValidationMixin) --
|
|
2305
|
+
|
|
2306
|
+
/**
|
|
2307
|
+
* Validates the field. Returns `true` if valid.
|
|
2308
|
+
* When `notify` is `true` (default), updates state
|
|
2309
|
+
* and emits errors.
|
|
2310
|
+
*/
|
|
2311
|
+
validate(notify?: boolean): boolean
|
|
2312
|
+
/** Validates without notifying (shorthand). */
|
|
2313
|
+
verify(): boolean
|
|
2314
|
+
/** Marks the field as touched and clears errors. */
|
|
2315
|
+
markTouched(): void
|
|
2316
|
+
/** Marks the field as dirty and resets validation. */
|
|
2317
|
+
markDirty(): void
|
|
2318
|
+
/** Resets all validation state. */
|
|
2319
|
+
resetValidation(): void
|
|
2320
|
+
/** Adds an error message to the errors array. */
|
|
2321
|
+
addError(error: string, addLabel?: boolean): void
|
|
2322
|
+
/**
|
|
2323
|
+
* Shows server-side validation errors on the
|
|
2324
|
+
* component. Returns `true` if errors were shown.
|
|
2325
|
+
*/
|
|
2326
|
+
showValidationErrors(
|
|
2327
|
+
errors: { message: string }[],
|
|
2328
|
+
focus: boolean
|
|
2329
|
+
): boolean
|
|
2330
|
+
/** Returns a copy of the current errors, or `null`. */
|
|
2331
|
+
getErrors(): string[] | null
|
|
2332
|
+
/** Clears all validation errors. */
|
|
2333
|
+
clearErrors(): void
|
|
2334
|
+
/** Closes all notification toasts. */
|
|
2335
|
+
closeNotifications(): void
|
|
2336
|
+
}
|
|
2337
|
+
|
|
2338
|
+
export interface EmitterMixin {
|
|
2339
|
+
/** Registers one or more event listeners. */
|
|
2340
|
+
on(
|
|
2341
|
+
event:
|
|
2342
|
+
| string
|
|
2343
|
+
| string[]
|
|
2344
|
+
| Record<string, Function>,
|
|
2345
|
+
callback?: Function
|
|
2346
|
+
): this
|
|
2347
|
+
/** Registers a one-time event listener. */
|
|
2348
|
+
once(event: string, callback: Function): this
|
|
2349
|
+
/** Removes event listener(s). */
|
|
2350
|
+
off(
|
|
2351
|
+
event?:
|
|
2352
|
+
| string
|
|
2353
|
+
| string[]
|
|
2354
|
+
| Record<string, Function>,
|
|
2355
|
+
callback?: Function
|
|
2356
|
+
): this
|
|
2357
|
+
/** Emits an event asynchronously (queued). */
|
|
2358
|
+
emit(event: string, ...args: any[]): Promise<any>
|
|
2359
|
+
/** Returns `true` if listeners exist for the event(s). */
|
|
2360
|
+
hasListeners(event: string | string[]): boolean
|
|
2361
|
+
/** Re-emits events from this component on the target. */
|
|
2362
|
+
delegate(
|
|
2363
|
+
event: string | string[],
|
|
2364
|
+
target: EmitterMixin
|
|
2365
|
+
): this
|
|
2366
|
+
}
|
|
2367
|
+
|
|
2368
|
+
export interface DitoFormInstance<$Item = any>
|
|
2369
|
+
extends DitoComponentInstanceBase<$Item> {
|
|
2370
|
+
/**
|
|
2371
|
+
* Whether this form is creating a new item
|
|
2372
|
+
* (`true`) or editing an existing one (`false`).
|
|
2373
|
+
*/
|
|
2374
|
+
isCreating: boolean
|
|
2375
|
+
|
|
2376
|
+
/**
|
|
2377
|
+
* Submits the form data to the API. Returns
|
|
2378
|
+
* `true` on success, `false` if validation
|
|
2379
|
+
* fails or the request errors.
|
|
2380
|
+
*/
|
|
2381
|
+
submit(
|
|
2382
|
+
button?: DitoComponentInstanceBase,
|
|
2383
|
+
options?: {
|
|
2384
|
+
validate?: boolean
|
|
2385
|
+
closeForm?: boolean
|
|
2386
|
+
}
|
|
2387
|
+
): Promise<boolean>
|
|
2388
|
+
|
|
2389
|
+
/**
|
|
2390
|
+
* Cancels the form and navigates to the parent
|
|
2391
|
+
* route.
|
|
2392
|
+
*/
|
|
2393
|
+
cancel(): Promise<void>
|
|
2394
|
+
|
|
2395
|
+
/**
|
|
2396
|
+
* Closes the form and navigates to the parent
|
|
2397
|
+
* route.
|
|
2398
|
+
*/
|
|
2399
|
+
close(): Promise<void>
|
|
2400
|
+
|
|
2401
|
+
/**
|
|
2402
|
+
* Validates all fields in the form. Optionally
|
|
2403
|
+
* filter fields with a match pattern. Returns
|
|
2404
|
+
* `true` if all matched fields are valid.
|
|
2405
|
+
*/
|
|
2406
|
+
validateAll(
|
|
2407
|
+
match?:
|
|
2408
|
+
| string
|
|
2409
|
+
| string[]
|
|
2410
|
+
| RegExp
|
|
2411
|
+
| ((field: string) => boolean),
|
|
2412
|
+
notify?: boolean
|
|
2413
|
+
): boolean
|
|
2414
|
+
|
|
2415
|
+
/**
|
|
2416
|
+
* Like {@link validateAll} but without
|
|
2417
|
+
* triggering error notifications.
|
|
2418
|
+
*/
|
|
2419
|
+
verifyAll(
|
|
2420
|
+
match?:
|
|
2421
|
+
| string
|
|
2422
|
+
| string[]
|
|
2423
|
+
| RegExp
|
|
2424
|
+
| ((field: string) => boolean)
|
|
2425
|
+
): boolean
|
|
2426
|
+
|
|
2427
|
+
// -- Resource & route (ResourceMixin, RouteMixin) --
|
|
2428
|
+
|
|
2429
|
+
/** Display label for this form. */
|
|
2430
|
+
label: string
|
|
2431
|
+
/** Breadcrumb text for navigation. */
|
|
2432
|
+
breadcrumb: string
|
|
2433
|
+
/** Prefix prepended to the breadcrumb label. */
|
|
2434
|
+
breadcrumbPrefix: string
|
|
2435
|
+
/** Whether this is the last route in the hierarchy. */
|
|
2436
|
+
isLastRoute: boolean
|
|
2437
|
+
/** Whether this route is nested inside another route. */
|
|
2438
|
+
isNestedRoute: boolean
|
|
2439
|
+
/** Zero-based depth of this route in the hierarchy. */
|
|
2440
|
+
routeLevel: number
|
|
2441
|
+
|
|
2442
|
+
/**
|
|
2443
|
+
* The resolved API resource for this component,
|
|
2444
|
+
* or `null` if none is configured.
|
|
2445
|
+
*/
|
|
2446
|
+
resource: Resource | null
|
|
2447
|
+
/**
|
|
2448
|
+
* Whether loaded data is available on this
|
|
2449
|
+
* component.
|
|
2450
|
+
*/
|
|
2451
|
+
hasData: boolean
|
|
2452
|
+
/**
|
|
2453
|
+
* Reloads data from the API without clearing
|
|
2454
|
+
* the existing data first.
|
|
2455
|
+
*/
|
|
2456
|
+
reloadData(): void
|
|
2457
|
+
/**
|
|
2458
|
+
* Ensures data is loaded: reloads if data
|
|
2459
|
+
* exists, otherwise loads fresh.
|
|
2460
|
+
*/
|
|
2461
|
+
ensureData(): void
|
|
2462
|
+
/** Clears the loaded data. */
|
|
2463
|
+
clearData(): void
|
|
2464
|
+
/** Sets the component's loaded data directly. */
|
|
2465
|
+
setData(data: any): void
|
|
2466
|
+
/**
|
|
2467
|
+
* Creates a new data object with default values
|
|
2468
|
+
* from the schema. Optionally sets a `type`
|
|
2469
|
+
* property for polymorphic forms.
|
|
2470
|
+
*/
|
|
2471
|
+
createData(
|
|
2472
|
+
schema: Component,
|
|
2473
|
+
type?: string
|
|
2474
|
+
): Record<string, any>
|
|
2475
|
+
/**
|
|
2476
|
+
* The route parameter value for this route
|
|
2477
|
+
* component (e.g. an item id or `'create'`).
|
|
2478
|
+
*/
|
|
2479
|
+
param: string | number | null
|
|
2480
|
+
/**
|
|
2481
|
+
* Whether the form directly mutates the
|
|
2482
|
+
* parent's data instead of working on a copy.
|
|
2483
|
+
*/
|
|
2484
|
+
isMutating: boolean
|
|
2485
|
+
/**
|
|
2486
|
+
* Builds a child route path relative to this
|
|
2487
|
+
* route component's path.
|
|
2488
|
+
*/
|
|
2489
|
+
getChildPath(path: string): string
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2492
|
+
export interface DitoViewInstance<$Item = any>
|
|
2493
|
+
extends DitoComponentInstanceBase<$Item> {
|
|
2494
|
+
/** Always `true` for view components. */
|
|
2495
|
+
isView: true
|
|
2496
|
+
|
|
2497
|
+
// -- Route (RouteMixin) --
|
|
2498
|
+
|
|
2499
|
+
/** Display label for this view. */
|
|
2500
|
+
label: string
|
|
2501
|
+
/** Breadcrumb text for navigation. */
|
|
2502
|
+
breadcrumb: string
|
|
2503
|
+
/** Prefix prepended to the breadcrumb label. */
|
|
2504
|
+
breadcrumbPrefix: string
|
|
2505
|
+
/** Whether this is the last route in the hierarchy. */
|
|
2506
|
+
isLastRoute: boolean
|
|
2507
|
+
/** Whether this route is nested inside another route. */
|
|
2508
|
+
isNestedRoute: boolean
|
|
2509
|
+
/** Zero-based depth of this route in the hierarchy. */
|
|
2510
|
+
routeLevel: number
|
|
2511
|
+
/**
|
|
2512
|
+
* The route parameter value for this route
|
|
2513
|
+
* component (e.g. an item id or `'create'`).
|
|
2514
|
+
*/
|
|
2515
|
+
param: string | number | null
|
|
2516
|
+
/**
|
|
2517
|
+
* Whether the view directly mutates the
|
|
2518
|
+
* parent's data instead of working on a copy.
|
|
2519
|
+
*/
|
|
2520
|
+
isMutating: boolean
|
|
2521
|
+
/**
|
|
2522
|
+
* Builds a child route path relative to this
|
|
2523
|
+
* route component's path.
|
|
2524
|
+
*/
|
|
2525
|
+
getChildPath(path: string): string
|
|
2526
|
+
|
|
2527
|
+
// -- Data & schema (DitoView) --
|
|
2528
|
+
|
|
2529
|
+
/** The view's reactive data object. */
|
|
2530
|
+
data: Record<string, any>
|
|
2531
|
+
/** The resolved view schema definition. */
|
|
2532
|
+
viewSchema: ViewSchema
|
|
2533
|
+
/**
|
|
2534
|
+
* Whether this view contains a single inlined
|
|
2535
|
+
* source component (renders without a table header).
|
|
2536
|
+
*/
|
|
2537
|
+
isSingleComponentView: boolean
|
|
2538
|
+
/**
|
|
2539
|
+
* Whether this view loads its own data from
|
|
2540
|
+
* a resource.
|
|
2541
|
+
*/
|
|
2542
|
+
providesData: boolean
|
|
2543
|
+
/** Sets the view's data directly. */
|
|
2544
|
+
setData(data: any): void
|
|
2545
|
+
|
|
2546
|
+
// -- Validation (ValidatorMixin) --
|
|
2547
|
+
|
|
2548
|
+
/**
|
|
2549
|
+
* Validates all fields in the view.
|
|
2550
|
+
* Optionally filter fields with a match pattern.
|
|
2551
|
+
* Returns `true` if all matched fields are valid.
|
|
2552
|
+
*/
|
|
2553
|
+
validateAll(
|
|
2554
|
+
match?:
|
|
2555
|
+
| string
|
|
2556
|
+
| string[]
|
|
2557
|
+
| RegExp
|
|
2558
|
+
| ((field: string) => boolean),
|
|
2559
|
+
notify?: boolean
|
|
2560
|
+
): boolean
|
|
2561
|
+
|
|
2562
|
+
/**
|
|
2563
|
+
* Like {@link validateAll} but without
|
|
2564
|
+
* triggering error notifications.
|
|
2565
|
+
*/
|
|
2566
|
+
verifyAll(
|
|
2567
|
+
match?:
|
|
2568
|
+
| string
|
|
2569
|
+
| string[]
|
|
2570
|
+
| RegExp
|
|
2571
|
+
| ((field: string) => boolean)
|
|
2572
|
+
): boolean
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
export interface DitoSchemaInstance<$Item = any>
|
|
2576
|
+
extends DitoComponentInstanceBase<$Item> {
|
|
2577
|
+
/**
|
|
2578
|
+
* Validates all fields in the schema.
|
|
2579
|
+
* Optionally filter fields with a match pattern
|
|
2580
|
+
* (string, string[], RegExp, or function).
|
|
2581
|
+
* Returns `true` if all matched fields are
|
|
2582
|
+
* valid.
|
|
2583
|
+
*/
|
|
2584
|
+
validateAll(
|
|
2585
|
+
match?:
|
|
2586
|
+
| string
|
|
2587
|
+
| string[]
|
|
2588
|
+
| RegExp
|
|
2589
|
+
| ((field: string) => boolean),
|
|
2590
|
+
notify?: boolean
|
|
2591
|
+
): boolean
|
|
2592
|
+
|
|
2593
|
+
/**
|
|
2594
|
+
* Like {@link validateAll} but without
|
|
2595
|
+
* triggering error notifications.
|
|
2596
|
+
*/
|
|
2597
|
+
verifyAll(
|
|
2598
|
+
match?:
|
|
2599
|
+
| string
|
|
2600
|
+
| string[]
|
|
2601
|
+
| RegExp
|
|
2602
|
+
| ((field: string) => boolean)
|
|
2603
|
+
): boolean
|
|
2604
|
+
}
|
|
2605
|
+
|
|
2606
|
+
export interface DitoSourceInstance<$Item = any>
|
|
2607
|
+
extends DitoComponentInstanceBase<$Item> {
|
|
2608
|
+
// -- Data access (SourceMixin) --
|
|
2609
|
+
|
|
2610
|
+
/** The list data array (getter/setter). */
|
|
2611
|
+
listData: any[]
|
|
2612
|
+
/** The object data (getter/setter). */
|
|
2613
|
+
objectData: Record<string, any> | null
|
|
2614
|
+
/** Total number of items (for pagination). */
|
|
2615
|
+
total: number
|
|
2616
|
+
/** Current query parameters (getter/setter). */
|
|
2617
|
+
query: Record<string, any>
|
|
2618
|
+
/** Whether this source manages a list. */
|
|
2619
|
+
isListSource: boolean
|
|
2620
|
+
/** Whether this source manages an object. */
|
|
2621
|
+
isObjectSource: boolean
|
|
2622
|
+
/** Whether the source renders inline. */
|
|
2623
|
+
isInlined: boolean
|
|
2624
|
+
/**
|
|
2625
|
+
* Nesting depth of sources (0 for top-level,
|
|
2626
|
+
* increments for nested sources).
|
|
2627
|
+
*/
|
|
2628
|
+
sourceDepth: number
|
|
2629
|
+
/** The URL path for this source. */
|
|
2630
|
+
path: string
|
|
2631
|
+
|
|
2632
|
+
// -- Resolved schema accessors (SourceMixin) --
|
|
2633
|
+
|
|
2634
|
+
/** Whether new items can be created. */
|
|
2635
|
+
creatable: boolean
|
|
2636
|
+
/** Whether existing items can be edited. */
|
|
2637
|
+
editable: boolean
|
|
2638
|
+
/** Whether items can be deleted. */
|
|
2639
|
+
deletable: boolean
|
|
2640
|
+
/** Whether items can be reordered by dragging. */
|
|
2641
|
+
draggable: boolean
|
|
2642
|
+
/** Whether inlined forms are collapsible. */
|
|
2643
|
+
collapsible: boolean
|
|
2644
|
+
/** Whether inlined forms are collapsed. */
|
|
2645
|
+
collapsed: boolean
|
|
2646
|
+
/** Resolved pagination page size. */
|
|
2647
|
+
paginate: number | undefined
|
|
2648
|
+
/** Maximum nesting depth for nested sources. */
|
|
2649
|
+
maxDepth: number
|
|
2650
|
+
/** Whether the source renders in compact mode. */
|
|
2651
|
+
isCompact: boolean
|
|
2652
|
+
|
|
2653
|
+
// -- Schema introspection (SourceMixin) --
|
|
2654
|
+
|
|
2655
|
+
/** Resolved column definitions. */
|
|
2656
|
+
columns: Record<string, ColumnSchema> | null
|
|
2657
|
+
/** Resolved scope definitions. */
|
|
2658
|
+
scopes: Record<string, any> | null
|
|
2659
|
+
/** Resolved form definitions. */
|
|
2660
|
+
forms: Form[]
|
|
2661
|
+
/** Resolved button schemas. */
|
|
2662
|
+
buttonSchemas: Record<string, ButtonSchema<any>>
|
|
2663
|
+
|
|
2664
|
+
// -- Item operations (SourceMixin) --
|
|
2665
|
+
|
|
2666
|
+
/**
|
|
2667
|
+
* Creates a new data item with defaults from the
|
|
2668
|
+
* schema. Optionally sets a `type` property for
|
|
2669
|
+
* polymorphic forms.
|
|
2670
|
+
*/
|
|
2671
|
+
createItem(
|
|
2672
|
+
schema: Component,
|
|
2673
|
+
type?: string
|
|
2674
|
+
): Record<string, any>
|
|
2675
|
+
/** Removes an item from the list data locally. */
|
|
2676
|
+
removeItem(item: any, index: number): void
|
|
2677
|
+
/**
|
|
2678
|
+
* Deletes an item via the API and removes it
|
|
2679
|
+
* from the list.
|
|
2680
|
+
*/
|
|
2681
|
+
deleteItem(item: any, index: number): void
|
|
2682
|
+
/**
|
|
2683
|
+
* Navigates to a component identified by its
|
|
2684
|
+
* data path.
|
|
2685
|
+
*/
|
|
2686
|
+
navigateToComponent(
|
|
2687
|
+
dataPath: string,
|
|
2688
|
+
onComplete?: Function
|
|
2689
|
+
): Promise<boolean>
|
|
2690
|
+
/**
|
|
2691
|
+
* Navigates to the route component associated
|
|
2692
|
+
* with a data path.
|
|
2693
|
+
*/
|
|
2694
|
+
navigateToRouteComponent(
|
|
2695
|
+
dataPath: string,
|
|
2696
|
+
onComplete?: Function
|
|
2697
|
+
): Promise<boolean>
|
|
2698
|
+
|
|
2699
|
+
// -- Resource (ResourceMixin) --
|
|
2700
|
+
|
|
2701
|
+
/**
|
|
2702
|
+
* The resolved API resource for this component,
|
|
2703
|
+
* or `null` if none is configured.
|
|
2704
|
+
*/
|
|
2705
|
+
resource: Resource | null
|
|
2706
|
+
/**
|
|
2707
|
+
* Whether loaded data is available on this
|
|
2708
|
+
* component.
|
|
2709
|
+
*/
|
|
2710
|
+
hasData: boolean
|
|
2711
|
+
/**
|
|
2712
|
+
* Reloads data from the API without clearing
|
|
2713
|
+
* the existing data first.
|
|
2714
|
+
*/
|
|
2715
|
+
reloadData(): void
|
|
2716
|
+
/**
|
|
2717
|
+
* Ensures data is loaded: reloads if data
|
|
2718
|
+
* exists, otherwise loads fresh.
|
|
2719
|
+
*/
|
|
2720
|
+
ensureData(): void
|
|
2721
|
+
/** Clears the loaded data. */
|
|
2722
|
+
clearData(): void
|
|
2723
|
+
/** Sets the component's loaded data directly. */
|
|
2724
|
+
setData(data: any): void
|
|
2725
|
+
/**
|
|
2726
|
+
* Creates a new data object with default values
|
|
2727
|
+
* from the schema. Optionally sets a `type`
|
|
2728
|
+
* property for polymorphic forms.
|
|
2729
|
+
*/
|
|
2730
|
+
createData(
|
|
2731
|
+
schema: Component,
|
|
2732
|
+
type?: string
|
|
2733
|
+
): Record<string, any>
|
|
2734
|
+
}
|
|
2735
|
+
|
|
2736
|
+
export interface MenuSchema<$Item = any> {
|
|
2737
|
+
type: 'menu'
|
|
2738
|
+
/**
|
|
2739
|
+
* The label shown in the navigation menu.
|
|
2740
|
+
*/
|
|
2741
|
+
label?: string
|
|
2742
|
+
/**
|
|
2743
|
+
* The name of the menu group.
|
|
2744
|
+
*
|
|
2745
|
+
* @defaultValue Camelized from `label`.
|
|
2746
|
+
*/
|
|
2747
|
+
name?: string
|
|
2748
|
+
/** Sub-views shown as menu items under this group. */
|
|
2749
|
+
items: Record<string, OrPromiseOf<View<$Item>>>
|
|
2750
|
+
}
|
|
2751
|
+
|
|
2752
|
+
export type ClipboardConfig =
|
|
2753
|
+
| boolean
|
|
1044
2754
|
| {
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
clipboard?: Form['clipboard']
|
|
1048
|
-
components?: Components<$Item>
|
|
2755
|
+
copy?: (context: DitoContext) => unknown
|
|
2756
|
+
paste?: (context: DitoContext) => unknown
|
|
1049
2757
|
}
|
|
1050
2758
|
|
|
1051
|
-
export type
|
|
2759
|
+
export type View<$Item = any> =
|
|
2760
|
+
| ViewSchema<$Item>
|
|
2761
|
+
| MenuSchema<$Item>
|
|
2762
|
+
|
|
2763
|
+
export interface ViewSchema<$Item = any> extends SchemaRoute<$Item> {
|
|
2764
|
+
type: 'view'
|
|
2765
|
+
/**
|
|
2766
|
+
* The label shown in the navigation menu.
|
|
2767
|
+
*
|
|
2768
|
+
* @defaultValue The title-cased view name.
|
|
2769
|
+
*/
|
|
2770
|
+
label?: string
|
|
2771
|
+
/**
|
|
2772
|
+
* The URL path for the view.
|
|
2773
|
+
*/
|
|
2774
|
+
path?: string
|
|
2775
|
+
/**
|
|
2776
|
+
* The name of the view.
|
|
2777
|
+
*/
|
|
2778
|
+
name?: string
|
|
2779
|
+
/**
|
|
2780
|
+
* Display several schemas in different tabs within
|
|
2781
|
+
* the view.
|
|
2782
|
+
*/
|
|
2783
|
+
tabs?: Record<
|
|
2784
|
+
string,
|
|
2785
|
+
Omit<ViewSchema<$Item>, 'tabs' | 'type'> & {
|
|
2786
|
+
type: 'tab'
|
|
2787
|
+
/**
|
|
2788
|
+
* Whether this tab is selected by default.
|
|
2789
|
+
*/
|
|
2790
|
+
defaultTab?: OrItemAccessor<$Item, {}, boolean>
|
|
2791
|
+
}
|
|
2792
|
+
>
|
|
2793
|
+
/**
|
|
2794
|
+
* Grouped event handlers, equivalent to the
|
|
2795
|
+
* `on[A-Z]`-style callbacks on the view schema
|
|
2796
|
+
* (e.g. {@link ViewSchema.onOpen}).
|
|
2797
|
+
*
|
|
2798
|
+
* @see {@link SchemaFields.onInitialize} and
|
|
2799
|
+
* other `on`-prefixed properties for per-event
|
|
2800
|
+
* documentation.
|
|
2801
|
+
*/
|
|
2802
|
+
events?: SchemaEvents<$Item> & {
|
|
2803
|
+
/**
|
|
2804
|
+
* Called when a collapsible schema section is
|
|
2805
|
+
* toggled open or closed.
|
|
2806
|
+
*/
|
|
2807
|
+
open?: OpenEventHandler<$Item>
|
|
2808
|
+
}
|
|
2809
|
+
component?: Component<$Item>
|
|
2810
|
+
components?: Components<$Item>
|
|
2811
|
+
}
|
|
2812
|
+
|
|
2813
|
+
/**
|
|
2814
|
+
* A non-visible component that computes a value and
|
|
2815
|
+
* stores it in the form data.
|
|
2816
|
+
*/
|
|
2817
|
+
export interface ComputedSchema<$Item = any>
|
|
2818
|
+
extends BaseSchema<$Item>,
|
|
2819
|
+
SchemaDataMixin<$Item> {
|
|
2820
|
+
/**
|
|
2821
|
+
* The type of the component.
|
|
2822
|
+
*/
|
|
2823
|
+
type: 'computed'
|
|
2824
|
+
}
|
|
2825
|
+
|
|
2826
|
+
/**
|
|
2827
|
+
* A non-visible component that fetches external data
|
|
2828
|
+
* and stores it in the form data.
|
|
2829
|
+
*/
|
|
2830
|
+
export interface DataSchema<$Item = any>
|
|
2831
|
+
extends BaseSchema<$Item>,
|
|
2832
|
+
SchemaDataMixin<$Item> {
|
|
2833
|
+
/**
|
|
2834
|
+
* The type of the component.
|
|
2835
|
+
*/
|
|
2836
|
+
type: 'data'
|
|
2837
|
+
}
|
|
2838
|
+
|
|
2839
|
+
export interface ObjectSchema<$Item = { [key: string]: any }>
|
|
2840
|
+
extends SchemaSourceMixin<$Item>,
|
|
2841
|
+
BaseSchema<$Item>,
|
|
2842
|
+
SchemaOpen<$Item> {
|
|
2843
|
+
/**
|
|
2844
|
+
* The type of the component.
|
|
2845
|
+
*/
|
|
2846
|
+
type: 'object'
|
|
2847
|
+
/**
|
|
2848
|
+
* Grouped event handlers.
|
|
2849
|
+
*/
|
|
2850
|
+
events?: {
|
|
2851
|
+
/**
|
|
2852
|
+
* Called when a collapsible inlined object is
|
|
2853
|
+
* toggled open or closed.
|
|
2854
|
+
*/
|
|
2855
|
+
open?: OpenEventHandler<$Item>
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
|
|
2859
|
+
interface TreeSchema<$Item, $Type extends 'tree-list' | 'tree-object'>
|
|
2860
|
+
extends SchemaSourceMixin<$Item>,
|
|
2861
|
+
BaseSchema<$Item> {
|
|
2862
|
+
/**
|
|
2863
|
+
* The type of the component.
|
|
2864
|
+
*/
|
|
2865
|
+
type: $Type
|
|
2866
|
+
/**
|
|
2867
|
+
* Nested tree schema describing the recursive
|
|
2868
|
+
* children of each node. The `name` property
|
|
2869
|
+
* identifies which data property holds the
|
|
2870
|
+
* children array.
|
|
2871
|
+
*/
|
|
2872
|
+
children?: Omit<TreeListSchema<$Item>, 'type'> & {
|
|
2873
|
+
name: string
|
|
2874
|
+
}
|
|
2875
|
+
/**
|
|
2876
|
+
* Properties schema for tree nodes.
|
|
2877
|
+
*/
|
|
2878
|
+
properties?: Record<string, Component<$Item>>
|
|
2879
|
+
/**
|
|
2880
|
+
* Whether child nodes are expanded by default.
|
|
2881
|
+
*/
|
|
2882
|
+
open?: boolean
|
|
2883
|
+
}
|
|
2884
|
+
|
|
2885
|
+
export type TreeListSchema<$Item = any> = TreeSchema<$Item, 'tree-list'>
|
|
2886
|
+
export type TreeObjectSchema<$Item = any> = TreeSchema<$Item, 'tree-object'>
|
|
2887
|
+
export type PanelSchema<$Item = any> = BaseSchema<$Item> & {
|
|
2888
|
+
/**
|
|
2889
|
+
* The type of the component.
|
|
2890
|
+
*/
|
|
2891
|
+
type: 'panel'
|
|
2892
|
+
/**
|
|
2893
|
+
* The components within the panel.
|
|
2894
|
+
*/
|
|
2895
|
+
components?: Components<$Item>
|
|
2896
|
+
/** Buttons rendered at the bottom of the panel. */
|
|
2897
|
+
buttons?: Buttons<$Item>
|
|
2898
|
+
/**
|
|
2899
|
+
* Buttons rendered in the panel header, next to the
|
|
2900
|
+
* title. Displayed at a smaller size.
|
|
2901
|
+
*/
|
|
2902
|
+
panelButtons?: Buttons<$Item>
|
|
2903
|
+
/**
|
|
2904
|
+
* Whether the panel header sticks to the top of the
|
|
2905
|
+
* scroll container.
|
|
2906
|
+
*
|
|
2907
|
+
* @defaultValue `false`
|
|
2908
|
+
*/
|
|
2909
|
+
sticky?: OrItemAccessor<$Item, {}, boolean>
|
|
2910
|
+
}
|
|
2911
|
+
|
|
2912
|
+
export interface SpacerSchema<$Item = any> extends BaseSchema<$Item> {
|
|
2913
|
+
/**
|
|
2914
|
+
* The type of the component.
|
|
2915
|
+
*/
|
|
2916
|
+
type: 'spacer'
|
|
2917
|
+
}
|
|
2918
|
+
|
|
2919
|
+
export interface ProgressSchema<$Item = any>
|
|
2920
|
+
extends SchemaNumberMixin<$Item>,
|
|
2921
|
+
BaseSchema<$Item> {
|
|
2922
|
+
/**
|
|
2923
|
+
* The type of the component.
|
|
2924
|
+
*/
|
|
2925
|
+
type: 'progress'
|
|
2926
|
+
}
|
|
2927
|
+
|
|
2928
|
+
type NonSectionComponent<$Item = any> =
|
|
1052
2929
|
| InputSchema<$Item>
|
|
1053
2930
|
| RadioSchema<$Item>
|
|
1054
2931
|
| CheckboxSchema<$Item>
|
|
@@ -1068,13 +2945,127 @@ export type Component<$Item = any> =
|
|
|
1068
2945
|
| DateSchema<$Item>
|
|
1069
2946
|
| ComponentSchema<$Item>
|
|
1070
2947
|
| LabelSchema<$Item>
|
|
1071
|
-
| SectionSchema<$Item>
|
|
1072
2948
|
| HiddenSchema<$Item>
|
|
2949
|
+
| ObjectSchema<$Item>
|
|
2950
|
+
| TreeListSchema<$Item>
|
|
2951
|
+
| TreeObjectSchema<$Item>
|
|
2952
|
+
| ComputedSchema<$Item>
|
|
2953
|
+
| DataSchema<$Item>
|
|
2954
|
+
| SpacerSchema<$Item>
|
|
2955
|
+
| ProgressSchema<$Item>
|
|
1073
2956
|
|
|
1074
|
-
export type
|
|
1075
|
-
|
|
|
1076
|
-
|
|
|
1077
|
-
|
|
2957
|
+
export type Component<$Item = any> =
|
|
2958
|
+
| NonSectionComponent<$Item>
|
|
2959
|
+
| SectionSchema<$Item>
|
|
2960
|
+
|
|
2961
|
+
/**
|
|
2962
|
+
* Source components (list, object, tree) that contain nested
|
|
2963
|
+
* items with their own item type.
|
|
2964
|
+
*/
|
|
2965
|
+
export type SourceComponent<$Item = any> =
|
|
2966
|
+
| ListSchema<$Item>
|
|
2967
|
+
| ObjectSchema<$Item>
|
|
2968
|
+
| TreeListSchema<$Item>
|
|
2969
|
+
| TreeObjectSchema<$Item>
|
|
2970
|
+
|
|
2971
|
+
/**
|
|
2972
|
+
* Strips properties with `never` values from a type.
|
|
2973
|
+
*/
|
|
2974
|
+
type OmitNever<T> = {
|
|
2975
|
+
[K in keyof T as [T[K]] extends [never] ? never : K]: T[K]
|
|
2976
|
+
} & {}
|
|
2977
|
+
|
|
2978
|
+
/**
|
|
2979
|
+
* Defines the components for a form or view.
|
|
2980
|
+
*
|
|
2981
|
+
* When you provide an `$Item` type, each component key must match
|
|
2982
|
+
* a property on that type, and callbacks receive a typed `item`
|
|
2983
|
+
* whose type depends on that property:
|
|
2984
|
+
*
|
|
2985
|
+
* - **Regular data fields** (e.g. `title: string`): callbacks
|
|
2986
|
+
* receive the full parent item type.
|
|
2987
|
+
* - **Array fields** (e.g. `entries: Entry[]`): nested list or
|
|
2988
|
+
* tree components use the array element type (`Entry`).
|
|
2989
|
+
* - **UI-only keys** (e.g. `viewButton: never`): for components
|
|
2990
|
+
* like buttons, spacers, or sections that exist only in the UI
|
|
2991
|
+
* and are not actual data fields. Declare these keys as `never`.
|
|
2992
|
+
* They are omitted from `item` in callbacks.
|
|
2993
|
+
*
|
|
2994
|
+
* Only keys defined in `$Item` are allowed. Unknown keys are a
|
|
2995
|
+
* type error.
|
|
2996
|
+
*
|
|
2997
|
+
* @example
|
|
2998
|
+
* ```ts
|
|
2999
|
+
* type Entry = { id: number; title: string }
|
|
3000
|
+
*
|
|
3001
|
+
* type Item = {
|
|
3002
|
+
* title: string
|
|
3003
|
+
* entries: Entry[]
|
|
3004
|
+
* viewButton: never // UI-only key for a button
|
|
3005
|
+
* details: never // UI-only key for a section
|
|
3006
|
+
* }
|
|
3007
|
+
*
|
|
3008
|
+
* const components: Components<Item> = {
|
|
3009
|
+
* // regular data field — callbacks receive Item
|
|
3010
|
+
* title: { type: 'text' },
|
|
3011
|
+
*
|
|
3012
|
+
* // array field — callbacks receive Entry, not Item
|
|
3013
|
+
* entries: {
|
|
3014
|
+
* type: 'list',
|
|
3015
|
+
* form: {
|
|
3016
|
+
* type: 'form',
|
|
3017
|
+
* components: {
|
|
3018
|
+
* title: {
|
|
3019
|
+
* type: 'text',
|
|
3020
|
+
* // item is typed as Entry, not Item
|
|
3021
|
+
* onChange({ item }) { console.log(item.title) }
|
|
3022
|
+
* }
|
|
3023
|
+
* }
|
|
3024
|
+
* }
|
|
3025
|
+
* },
|
|
3026
|
+
*
|
|
3027
|
+
* // UI-only key — item omits viewButton and details
|
|
3028
|
+
* viewButton: {
|
|
3029
|
+
* type: 'button',
|
|
3030
|
+
* events: {
|
|
3031
|
+
* click({ item }) { ... }
|
|
3032
|
+
* }
|
|
3033
|
+
* },
|
|
3034
|
+
*
|
|
3035
|
+
* // UI-only key — sections group fields from the parent item
|
|
3036
|
+
* details: {
|
|
3037
|
+
* type: 'section',
|
|
3038
|
+
* components: {
|
|
3039
|
+
* title: { type: 'text' }
|
|
3040
|
+
* }
|
|
3041
|
+
* }
|
|
3042
|
+
* }
|
|
3043
|
+
* ```
|
|
3044
|
+
*/
|
|
3045
|
+
export type Components<$Item = any> = 0 extends 1 & $Item
|
|
3046
|
+
? Record<string, Component>
|
|
3047
|
+
: {
|
|
3048
|
+
[K in keyof $Item]?: [$Item[K]] extends [never]
|
|
3049
|
+
? NonSectionComponent<$Item> | SectionSchema<$Item>
|
|
3050
|
+
: $Item[K] extends (infer E)[]
|
|
3051
|
+
? E extends Record<string, any>
|
|
3052
|
+
? NonSectionComponent<E>
|
|
3053
|
+
: NonSectionComponent<$Item>
|
|
3054
|
+
: $Item[K] extends Record<string, any>
|
|
3055
|
+
?
|
|
3056
|
+
| NonSectionComponent<$Item>
|
|
3057
|
+
| SectionSchema<$Item, $Item[K]>
|
|
3058
|
+
:
|
|
3059
|
+
| NonSectionComponent<$Item>
|
|
3060
|
+
| SectionSchema<$Item>
|
|
3061
|
+
}
|
|
3062
|
+
|
|
3063
|
+
export type Columns<$Item = any> = 0 extends 1 & $Item
|
|
3064
|
+
? { [key: string]: ColumnSchema | undefined }
|
|
3065
|
+
: {
|
|
3066
|
+
[K in keyof $Item]?: ColumnSchema<$Item, $Item[K]>
|
|
3067
|
+
} & {
|
|
3068
|
+
[key: string]: ColumnSchema<$Item> | undefined
|
|
1078
3069
|
}
|
|
1079
3070
|
|
|
1080
3071
|
export type Buttons<$Item> = Record<
|
|
@@ -1082,7 +3073,7 @@ export type Buttons<$Item> = Record<
|
|
|
1082
3073
|
SetOptional<ButtonSchema<$Item>, 'type'>
|
|
1083
3074
|
>
|
|
1084
3075
|
|
|
1085
|
-
export
|
|
3076
|
+
export interface Form<$Item = any> extends SchemaRoute<$Item> {
|
|
1086
3077
|
type: 'form'
|
|
1087
3078
|
|
|
1088
3079
|
/**
|
|
@@ -1094,101 +3085,214 @@ export type Form<$Item = any> = {
|
|
|
1094
3085
|
*/
|
|
1095
3086
|
label?: OrItemAccessor<$Item, {}, string | boolean>
|
|
1096
3087
|
/**
|
|
3088
|
+
* Whether the form directly mutates the parent data instead
|
|
3089
|
+
* of working on a copy.
|
|
3090
|
+
*
|
|
1097
3091
|
* @defaultValue `false`
|
|
1098
3092
|
*/
|
|
1099
|
-
|
|
1100
|
-
|
|
3093
|
+
mutate?: boolean
|
|
3094
|
+
/**
|
|
3095
|
+
* The property name used as the item's unique identifier.
|
|
3096
|
+
*
|
|
3097
|
+
* @defaultValue `'id'`
|
|
3098
|
+
*/
|
|
3099
|
+
idKey?: string
|
|
1101
3100
|
/**
|
|
1102
3101
|
* Display several forms in different tabs within the form.
|
|
1103
3102
|
*/
|
|
1104
3103
|
tabs?: Record<
|
|
1105
3104
|
string,
|
|
1106
3105
|
Omit<Form<$Item>, 'tabs' | 'type'> & {
|
|
3106
|
+
type: 'tab'
|
|
3107
|
+
/**
|
|
3108
|
+
* Whether this tab is selected by default.
|
|
3109
|
+
*/
|
|
1107
3110
|
defaultTab?: OrItemAccessor<$Item, {}, boolean>
|
|
1108
3111
|
}
|
|
1109
3112
|
>
|
|
1110
|
-
|
|
3113
|
+
/** The form's field components. */
|
|
1111
3114
|
components?: Components<$Item>
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
3115
|
+
/**
|
|
3116
|
+
* Grouped event handlers, equivalent to the
|
|
3117
|
+
* `on[A-Z]`-style callbacks on the form schema
|
|
3118
|
+
* (e.g. {@link Form.onOpen}).
|
|
3119
|
+
*
|
|
3120
|
+
* @see {@link SchemaFields.onInitialize} and
|
|
3121
|
+
* other `on`-prefixed properties for per-event
|
|
3122
|
+
* documentation.
|
|
3123
|
+
*/
|
|
3124
|
+
events?: SchemaEvents<$Item> & {
|
|
3125
|
+
/**
|
|
3126
|
+
* Called when a collapsible schema section is
|
|
3127
|
+
* toggled open or closed.
|
|
3128
|
+
*/
|
|
3129
|
+
open?: OpenEventHandler<$Item>
|
|
3130
|
+
/**
|
|
3131
|
+
* Called after a new item is successfully
|
|
3132
|
+
* created and persisted.
|
|
3133
|
+
*/
|
|
3134
|
+
create?: ItemEventHandler<$Item>
|
|
3135
|
+
/**
|
|
3136
|
+
* Called after an existing item is successfully
|
|
3137
|
+
* submitted and persisted.
|
|
3138
|
+
*/
|
|
3139
|
+
submit?: ItemEventHandler<$Item>
|
|
3140
|
+
/**
|
|
3141
|
+
* Called when a submit request fails. The
|
|
3142
|
+
* `error` property on the context contains the
|
|
3143
|
+
* request error.
|
|
3144
|
+
*/
|
|
3145
|
+
error?: ErrorEventHandler<$Item>
|
|
3146
|
+
}
|
|
3147
|
+
/**
|
|
3148
|
+
* Called after a new item is successfully
|
|
3149
|
+
* created and persisted.
|
|
3150
|
+
*/
|
|
3151
|
+
onCreate?: ItemEventHandler<$Item>
|
|
3152
|
+
/**
|
|
3153
|
+
* Called after an existing item is successfully
|
|
3154
|
+
* submitted and persisted.
|
|
3155
|
+
*/
|
|
3156
|
+
onSubmit?: ItemEventHandler<$Item>
|
|
3157
|
+
/**
|
|
3158
|
+
* Called when a submit request fails. The
|
|
3159
|
+
* `error` property on the context contains the
|
|
3160
|
+
* request error.
|
|
3161
|
+
*/
|
|
3162
|
+
onError?: ErrorEventHandler<$Item>
|
|
1121
3163
|
}
|
|
1122
3164
|
|
|
1123
3165
|
export type Resource =
|
|
1124
3166
|
| string
|
|
1125
3167
|
| RequireAtLeastOne<{
|
|
1126
3168
|
path?: string
|
|
1127
|
-
method?:
|
|
1128
|
-
|
|
1129
|
-
data?: any
|
|
3169
|
+
method?: HTTPMethod
|
|
3170
|
+
data?: unknown
|
|
1130
3171
|
}>
|
|
1131
3172
|
|
|
1132
3173
|
export class DitoAdmin<
|
|
1133
|
-
$Views extends Record<string,
|
|
3174
|
+
$Views extends Record<string, OrPromiseOf<View>> = Record<
|
|
3175
|
+
string,
|
|
3176
|
+
OrPromiseOf<View>
|
|
3177
|
+
>
|
|
1134
3178
|
> {
|
|
3179
|
+
/** The DOM element the admin is mounted to. */
|
|
3180
|
+
el: Element
|
|
3181
|
+
/** The resolved API configuration. */
|
|
1135
3182
|
api: ApiConfig
|
|
1136
|
-
|
|
1137
|
-
|
|
3183
|
+
/** The Vue application instance. */
|
|
3184
|
+
app: import('vue').App
|
|
3185
|
+
/** Additional options passed at construction. */
|
|
3186
|
+
options: Record<string, any>
|
|
3187
|
+
|
|
1138
3188
|
constructor(
|
|
1139
3189
|
element: Element | string,
|
|
1140
3190
|
options?: {
|
|
1141
|
-
// `dito` contains the base and api settings passed from
|
|
3191
|
+
// `dito` contains the base and api settings passed from
|
|
3192
|
+
// `AdminController`
|
|
1142
3193
|
dito?: DitoGlobal
|
|
1143
3194
|
api?: ApiConfig
|
|
1144
3195
|
views: OrFunctionReturning<OrPromiseOf<$Views>>
|
|
1145
|
-
|
|
1146
|
-
|
|
3196
|
+
login?: {
|
|
3197
|
+
additionalComponents?: Components
|
|
3198
|
+
redirectAfterLogin?: string
|
|
3199
|
+
}
|
|
3200
|
+
/**
|
|
3201
|
+
* Controls the loading spinner displayed in the
|
|
3202
|
+
* admin header. Set to `null` to disable it.
|
|
3203
|
+
*/
|
|
3204
|
+
spinner?: {
|
|
3205
|
+
size?: string
|
|
3206
|
+
color?: string
|
|
3207
|
+
} | null
|
|
3208
|
+
[key: string]: any
|
|
1147
3209
|
}
|
|
1148
3210
|
)
|
|
1149
3211
|
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
3212
|
+
/**
|
|
3213
|
+
* Registers a custom component type with the admin.
|
|
3214
|
+
*/
|
|
3215
|
+
register(
|
|
3216
|
+
type: OrArrayOf<string>,
|
|
3217
|
+
options: Record<string, unknown>
|
|
3218
|
+
): VueComponent
|
|
1153
3219
|
}
|
|
1154
|
-
export type
|
|
3220
|
+
export type HTTPMethod =
|
|
3221
|
+
| 'get'
|
|
3222
|
+
| 'head'
|
|
3223
|
+
| 'post'
|
|
3224
|
+
| 'put'
|
|
3225
|
+
| 'delete'
|
|
3226
|
+
| 'patch'
|
|
3227
|
+
| 'options'
|
|
3228
|
+
| 'trace'
|
|
3229
|
+
| 'connect'
|
|
3230
|
+
/** @deprecated Use `HTTPMethod` instead. */
|
|
3231
|
+
export type HTTPVerb = HTTPMethod
|
|
1155
3232
|
|
|
1156
3233
|
export type SchemaByType<$Item = any> = {
|
|
1157
|
-
button: ButtonSchema<$Item>
|
|
1158
|
-
checkbox: CheckboxSchema<$Item>
|
|
1159
|
-
checkboxes: CheckboxesSchema<$Item>
|
|
1160
|
-
code: CodeSchema<$Item>
|
|
1161
|
-
color: ColorSchema<$Item>
|
|
1162
|
-
component: ComponentSchema<$Item>
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
3234
|
+
'button': ButtonSchema<$Item>
|
|
3235
|
+
'checkbox': CheckboxSchema<$Item>
|
|
3236
|
+
'checkboxes': CheckboxesSchema<$Item>
|
|
3237
|
+
'code': CodeSchema<$Item>
|
|
3238
|
+
'color': ColorSchema<$Item>
|
|
3239
|
+
'component': ComponentSchema<$Item>
|
|
3240
|
+
'computed': ComputedSchema<$Item>
|
|
3241
|
+
'creditcard': InputSchema<$Item>
|
|
3242
|
+
'data': DataSchema<$Item>
|
|
3243
|
+
'date': DateSchema<$Item>
|
|
3244
|
+
'datetime': DateSchema<$Item>
|
|
3245
|
+
'domain': InputSchema<$Item>
|
|
3246
|
+
'email': InputSchema<$Item>
|
|
3247
|
+
'hostname': InputSchema<$Item>
|
|
3248
|
+
'integer': NumberSchema<$Item>
|
|
3249
|
+
'list': ListSchema<$Item>
|
|
3250
|
+
'markup': MarkupSchema<$Item>
|
|
3251
|
+
'multiselect': MultiselectSchema<$Item>
|
|
3252
|
+
'number': NumberSchema<$Item>
|
|
3253
|
+
'object': ObjectSchema<$Item>
|
|
3254
|
+
'password': InputSchema<$Item>
|
|
3255
|
+
'progress': ProgressSchema<$Item>
|
|
3256
|
+
'radio': RadioSchema<$Item>
|
|
3257
|
+
'select': SelectSchema<$Item>
|
|
3258
|
+
'slider': SliderSchema<$Item>
|
|
3259
|
+
'spacer': SpacerSchema<$Item>
|
|
3260
|
+
'submit': ButtonSchema<$Item>
|
|
3261
|
+
'switch': SwitchSchema<$Item>
|
|
3262
|
+
'tel': InputSchema<$Item>
|
|
3263
|
+
'text': InputSchema<$Item>
|
|
3264
|
+
'textarea': TextareaSchema<$Item>
|
|
3265
|
+
'time': DateSchema<$Item>
|
|
3266
|
+
'tree-list': TreeListSchema<$Item>
|
|
3267
|
+
'tree-object': TreeObjectSchema<$Item>
|
|
3268
|
+
'upload': UploadSchema<$Item>
|
|
3269
|
+
'url': InputSchema<$Item>
|
|
3270
|
+
'label': LabelSchema<$Item>
|
|
3271
|
+
'section': SectionSchema<$Item>
|
|
3272
|
+
'hidden': HiddenSchema<$Item>
|
|
3273
|
+
'unknown': never
|
|
1179
3274
|
}
|
|
1180
3275
|
|
|
1181
|
-
type OrRecordOf<T> = T | Record<string, T>
|
|
1182
|
-
type OrPromiseOf<T> = T | Promise<T>
|
|
1183
|
-
type OrFunctionReturning<T> = (() => T) | T
|
|
1184
|
-
type OrArrayOf<T> = T | T[]
|
|
1185
|
-
type Resolvable<T> = OrFunctionReturning<OrPromiseOf<OrRecordOf<T>>>
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
3276
|
+
export type OrRecordOf<T> = T | Record<string, T>
|
|
3277
|
+
export type OrPromiseOf<T> = T | Promise<T>
|
|
3278
|
+
export type OrFunctionReturning<T> = (() => T) | T
|
|
3279
|
+
export type OrArrayOf<T> = T | T[]
|
|
3280
|
+
export type Resolvable<T> = OrFunctionReturning<OrPromiseOf<OrRecordOf<T>>>
|
|
3281
|
+
|
|
3282
|
+
type WatchHandler<$Item> = (
|
|
3283
|
+
this: DitoComponentInstance<$Item>,
|
|
3284
|
+
value: any,
|
|
3285
|
+
oldValue: any
|
|
3286
|
+
) => void
|
|
3287
|
+
|
|
3288
|
+
type WatchEntry<$Item> =
|
|
3289
|
+
| WatchHandler<$Item>
|
|
3290
|
+
| {
|
|
3291
|
+
handler: WatchHandler<$Item>
|
|
3292
|
+
deep?: boolean
|
|
3293
|
+
immediate?: boolean
|
|
3294
|
+
}
|
|
3295
|
+
|
|
3296
|
+
type WatchHandlers<$Item> = Record<string, WatchEntry<$Item>>
|
|
1193
3297
|
|
|
1194
3298
|
type LiteralUnion<T extends U, U = string> = T | (U & Record<never, never>)
|