@radio-garden/ditojs-admin 2.85.2-0.5067ad799
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +180 -0
- package/dist/dito-admin.css +1 -0
- package/dist/dito-admin.es.js +12106 -0
- package/dist/dito-admin.umd.js +7 -0
- package/package.json +96 -0
- package/src/DitoAdmin.js +293 -0
- package/src/DitoComponent.js +34 -0
- package/src/DitoContext.js +318 -0
- package/src/DitoTypeComponent.js +42 -0
- package/src/DitoUser.js +12 -0
- package/src/appState.js +12 -0
- package/src/components/DitoAccount.vue +60 -0
- package/src/components/DitoAffix.vue +68 -0
- package/src/components/DitoAffixes.vue +200 -0
- package/src/components/DitoButtons.vue +80 -0
- package/src/components/DitoClipboard.vue +186 -0
- package/src/components/DitoContainer.vue +374 -0
- package/src/components/DitoCreateButton.vue +146 -0
- package/src/components/DitoDialog.vue +242 -0
- package/src/components/DitoDraggable.vue +117 -0
- package/src/components/DitoEditButtons.vue +135 -0
- package/src/components/DitoErrors.vue +83 -0
- package/src/components/DitoForm.vue +521 -0
- package/src/components/DitoFormInner.vue +26 -0
- package/src/components/DitoFormNested.vue +17 -0
- package/src/components/DitoHeader.vue +84 -0
- package/src/components/DitoLabel.vue +200 -0
- package/src/components/DitoMenu.vue +186 -0
- package/src/components/DitoNavigation.vue +40 -0
- package/src/components/DitoNotifications.vue +170 -0
- package/src/components/DitoPagination.vue +42 -0
- package/src/components/DitoPane.vue +334 -0
- package/src/components/DitoPanel.vue +256 -0
- package/src/components/DitoPanels.vue +61 -0
- package/src/components/DitoRoot.vue +524 -0
- package/src/components/DitoSchema.vue +846 -0
- package/src/components/DitoSchemaInlined.vue +97 -0
- package/src/components/DitoScopes.vue +76 -0
- package/src/components/DitoSidebar.vue +50 -0
- package/src/components/DitoSpinner.vue +95 -0
- package/src/components/DitoTableCell.vue +64 -0
- package/src/components/DitoTableHead.vue +121 -0
- package/src/components/DitoTabs.vue +103 -0
- package/src/components/DitoTrail.vue +124 -0
- package/src/components/DitoTreeItem.vue +420 -0
- package/src/components/DitoUploadFile.vue +199 -0
- package/src/components/DitoVNode.vue +14 -0
- package/src/components/DitoView.vue +143 -0
- package/src/components/index.js +42 -0
- package/src/directives/resize.js +83 -0
- package/src/index.js +1 -0
- package/src/mixins/ContextMixin.js +68 -0
- package/src/mixins/DataMixin.js +131 -0
- package/src/mixins/DitoMixin.js +591 -0
- package/src/mixins/DomMixin.js +29 -0
- package/src/mixins/EmitterMixin.js +158 -0
- package/src/mixins/ItemMixin.js +144 -0
- package/src/mixins/LoadingMixin.js +23 -0
- package/src/mixins/NumberMixin.js +118 -0
- package/src/mixins/OptionsMixin.js +304 -0
- package/src/mixins/PulldownMixin.js +63 -0
- package/src/mixins/ResourceMixin.js +398 -0
- package/src/mixins/RouteMixin.js +190 -0
- package/src/mixins/SchemaParentMixin.js +33 -0
- package/src/mixins/SortableMixin.js +49 -0
- package/src/mixins/SourceMixin.js +734 -0
- package/src/mixins/TextMixin.js +26 -0
- package/src/mixins/TypeMixin.js +280 -0
- package/src/mixins/ValidationMixin.js +119 -0
- package/src/mixins/ValidatorMixin.js +57 -0
- package/src/mixins/ValueMixin.js +31 -0
- package/src/styles/_base.scss +17 -0
- package/src/styles/_button.scss +191 -0
- package/src/styles/_imports.scss +3 -0
- package/src/styles/_info.scss +19 -0
- package/src/styles/_layout.scss +19 -0
- package/src/styles/_pulldown.scss +38 -0
- package/src/styles/_scroll.scss +13 -0
- package/src/styles/_settings.scss +88 -0
- package/src/styles/_table.scss +223 -0
- package/src/styles/_tippy.scss +45 -0
- package/src/styles/style.scss +9 -0
- package/src/types/DitoTypeButton.vue +143 -0
- package/src/types/DitoTypeCheckbox.vue +27 -0
- package/src/types/DitoTypeCheckboxes.vue +65 -0
- package/src/types/DitoTypeCode.vue +199 -0
- package/src/types/DitoTypeColor.vue +272 -0
- package/src/types/DitoTypeComponent.vue +31 -0
- package/src/types/DitoTypeComputed.vue +50 -0
- package/src/types/DitoTypeDate.vue +99 -0
- package/src/types/DitoTypeLabel.vue +23 -0
- package/src/types/DitoTypeList.vue +364 -0
- package/src/types/DitoTypeMarkup.vue +700 -0
- package/src/types/DitoTypeMultiselect.vue +522 -0
- package/src/types/DitoTypeNumber.vue +66 -0
- package/src/types/DitoTypeObject.vue +136 -0
- package/src/types/DitoTypePanel.vue +18 -0
- package/src/types/DitoTypeProgress.vue +40 -0
- package/src/types/DitoTypeRadio.vue +45 -0
- package/src/types/DitoTypeSection.vue +80 -0
- package/src/types/DitoTypeSelect.vue +133 -0
- package/src/types/DitoTypeSlider.vue +66 -0
- package/src/types/DitoTypeSpacer.vue +11 -0
- package/src/types/DitoTypeSwitch.vue +40 -0
- package/src/types/DitoTypeText.vue +101 -0
- package/src/types/DitoTypeTextarea.vue +48 -0
- package/src/types/DitoTypeTreeList.vue +193 -0
- package/src/types/DitoTypeUpload.vue +503 -0
- package/src/types/index.js +30 -0
- package/src/utils/SchemaGraph.js +147 -0
- package/src/utils/accessor.js +75 -0
- package/src/utils/agent.js +47 -0
- package/src/utils/data.js +92 -0
- package/src/utils/filter.js +266 -0
- package/src/utils/math.js +14 -0
- package/src/utils/options.js +48 -0
- package/src/utils/path.js +5 -0
- package/src/utils/resource.js +44 -0
- package/src/utils/route.js +53 -0
- package/src/utils/schema.js +1121 -0
- package/src/utils/type.js +81 -0
- package/src/utils/uid.js +15 -0
- package/src/utils/units.js +5 -0
- package/src/validators/_creditcard.js +6 -0
- package/src/validators/_decimals.js +11 -0
- package/src/validators/_domain.js +6 -0
- package/src/validators/_email.js +6 -0
- package/src/validators/_hostname.js +6 -0
- package/src/validators/_integer.js +6 -0
- package/src/validators/_max.js +6 -0
- package/src/validators/_min.js +6 -0
- package/src/validators/_password.js +5 -0
- package/src/validators/_range.js +6 -0
- package/src/validators/_required.js +9 -0
- package/src/validators/_url.js +6 -0
- package/src/validators/index.js +12 -0
- package/src/verbs.js +17 -0
- package/types/index.d.ts +3298 -0
- 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
ADDED
|
@@ -0,0 +1,3298 @@
|
|
|
1
|
+
// Type definitions for Dito.js admin
|
|
2
|
+
// Project: <https://github.com/ditojs/dito/>
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
DateFormat,
|
|
6
|
+
format as utilsFormat,
|
|
7
|
+
NumberFormat,
|
|
8
|
+
TimeFormat
|
|
9
|
+
} from '@ditojs/utils'
|
|
10
|
+
import { RequireAtLeastOne, SetOptional } from 'type-fest'
|
|
11
|
+
import { Component as VueComponent } from 'vue'
|
|
12
|
+
import { Router as VueRouter } from 'vue-router'
|
|
13
|
+
|
|
14
|
+
declare global {
|
|
15
|
+
const dito: DitoGlobal
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default DitoAdmin
|
|
19
|
+
export interface DitoGlobal {
|
|
20
|
+
/** Global API configuration shared across the admin. */
|
|
21
|
+
api?: ApiConfig
|
|
22
|
+
/** Base URL path for the admin application. */
|
|
23
|
+
base?: string
|
|
24
|
+
/** Arbitrary settings accessible via `dito.settings`. */
|
|
25
|
+
settings?: Record<string, any>
|
|
26
|
+
}
|
|
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. */
|
|
37
|
+
url: string
|
|
38
|
+
/**
|
|
39
|
+
* The HTTP method to use.
|
|
40
|
+
*
|
|
41
|
+
* @default 'get'
|
|
42
|
+
*/
|
|
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
|
|
55
|
+
}) => Promise<RequestMethodResponse<T>>
|
|
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
|
+
*/
|
|
63
|
+
export type RequestMethodResponse<T> = Response & { data: T }
|
|
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
|
+
*/
|
|
80
|
+
export interface ApiResource {
|
|
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
|
+
*/
|
|
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
|
+
*/
|
|
106
|
+
parent?: ApiResource
|
|
107
|
+
/** Query parameters appended to the request URL. */
|
|
108
|
+
query?: Record<string, string | number | (string | number)[]>
|
|
109
|
+
}
|
|
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
|
+
*/
|
|
117
|
+
export interface ApiConfig {
|
|
118
|
+
/**
|
|
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.
|
|
128
|
+
*/
|
|
129
|
+
url?: string
|
|
130
|
+
/**
|
|
131
|
+
* Locale used for date, time, and number formatting throughout
|
|
132
|
+
* the admin.
|
|
133
|
+
*
|
|
134
|
+
* @defaultValue `'en-US'`
|
|
135
|
+
*/
|
|
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
|
+
*/
|
|
142
|
+
formats?: {
|
|
143
|
+
number?: NumberFormat
|
|
144
|
+
date?: DateFormat
|
|
145
|
+
time?: TimeFormat
|
|
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
|
+
*/
|
|
153
|
+
request?: RequestMethod
|
|
154
|
+
/**
|
|
155
|
+
* Controls admin notification toasts. Set to `false` to disable
|
|
156
|
+
* all notifications, or provide an object to customize display
|
|
157
|
+
* duration.
|
|
158
|
+
*
|
|
159
|
+
* @defaultValue `true`
|
|
160
|
+
*/
|
|
161
|
+
notifications?:
|
|
162
|
+
| boolean
|
|
163
|
+
| {
|
|
164
|
+
/**
|
|
165
|
+
* Milliseconds per character used to calculate notification
|
|
166
|
+
* display duration. The formula is:
|
|
167
|
+
* `(40 + text.length + title.length) * durationFactor`.
|
|
168
|
+
*
|
|
169
|
+
* @defaultValue `20`
|
|
170
|
+
*/
|
|
171
|
+
durationFactor: number
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* CORS settings applied to API requests (where
|
|
175
|
+
* {@link ApiConfig.isApiUrl} returns `true`).
|
|
176
|
+
*/
|
|
177
|
+
cors?: {
|
|
178
|
+
/**
|
|
179
|
+
* Enables cross-site requests with credentials
|
|
180
|
+
* (`credentials: 'include'`).
|
|
181
|
+
*/
|
|
182
|
+
credentials: boolean
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
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.
|
|
190
|
+
*
|
|
191
|
+
* @defaultValue Inherits from
|
|
192
|
+
* `Application.config.app.normalizePaths`, falling back
|
|
193
|
+
* to `false`.
|
|
194
|
+
*/
|
|
195
|
+
normalizePaths?: boolean
|
|
196
|
+
/**
|
|
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.
|
|
202
|
+
*/
|
|
203
|
+
normalizePath?: (path: string) => string
|
|
204
|
+
/**
|
|
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.
|
|
209
|
+
*/
|
|
210
|
+
denormalizePath?: (path: string) => string
|
|
211
|
+
/**
|
|
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`).
|
|
215
|
+
*/
|
|
216
|
+
users?: {
|
|
217
|
+
/** The collection path for the user model. */
|
|
218
|
+
path: string
|
|
219
|
+
/** Login endpoint. */
|
|
220
|
+
login?: {
|
|
221
|
+
/**
|
|
222
|
+
* @defaultValue `'login'`
|
|
223
|
+
*/
|
|
224
|
+
path?: string
|
|
225
|
+
/**
|
|
226
|
+
* @defaultValue `'post'`
|
|
227
|
+
*/
|
|
228
|
+
method?: HTTPMethod
|
|
229
|
+
}
|
|
230
|
+
/** Logout endpoint. */
|
|
231
|
+
logout?: {
|
|
232
|
+
/**
|
|
233
|
+
* @defaultValue `'logout'`
|
|
234
|
+
*/
|
|
235
|
+
path?: string
|
|
236
|
+
/**
|
|
237
|
+
* @defaultValue `'post'`
|
|
238
|
+
*/
|
|
239
|
+
method?: HTTPMethod
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Session endpoint for checking an existing authenticated
|
|
243
|
+
* session on page load.
|
|
244
|
+
*/
|
|
245
|
+
session?: {
|
|
246
|
+
/**
|
|
247
|
+
* @defaultValue `'session'`
|
|
248
|
+
*/
|
|
249
|
+
path?: string
|
|
250
|
+
/**
|
|
251
|
+
* @defaultValue `'get'`
|
|
252
|
+
*/
|
|
253
|
+
method?: HTTPMethod
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
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.
|
|
261
|
+
*/
|
|
262
|
+
resources?: Record<string, (resource: ApiResource | string) => string>
|
|
263
|
+
|
|
264
|
+
/**
|
|
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' }`
|
|
271
|
+
*/
|
|
272
|
+
headers?: Record<string, string>
|
|
273
|
+
|
|
274
|
+
/**
|
|
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.
|
|
293
|
+
*/
|
|
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
|
+
>
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
export interface BaseSchema<$Item>
|
|
321
|
+
extends SchemaDitoMixin<$Item>,
|
|
322
|
+
SchemaTypeMixin<$Item> {
|
|
323
|
+
/**
|
|
324
|
+
* Value used when the field's key is absent from the
|
|
325
|
+
* data object.
|
|
326
|
+
*/
|
|
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
|
+
*/
|
|
333
|
+
compute?: ItemAccessor<$Item>
|
|
334
|
+
/**
|
|
335
|
+
* Additional reactive data properties merged into
|
|
336
|
+
* the component's data scope.
|
|
337
|
+
*/
|
|
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
|
+
*/
|
|
351
|
+
omitSpacing?: boolean
|
|
352
|
+
/**
|
|
353
|
+
* Forces a layout line break before, after, or on
|
|
354
|
+
* both sides of the component.
|
|
355
|
+
*/
|
|
356
|
+
break?: 'before' | 'after' | 'both'
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export interface SchemaDitoMixin<$Item> {
|
|
360
|
+
/**
|
|
361
|
+
* Only displays the component if the schema accessor returns `true`
|
|
362
|
+
*/
|
|
363
|
+
if?: OrItemAccessor<$Item, {}, boolean>
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Specifies validations rules to add, remove (by setting to `undefined`) or
|
|
367
|
+
* change before value validation occurs. Rule changes do not influence how
|
|
368
|
+
* the component is rendered.
|
|
369
|
+
*/
|
|
370
|
+
rules?: {
|
|
371
|
+
/** Override whether the field is required. */
|
|
372
|
+
required?: boolean
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Return false to mark event as handled and stop it from propagating to parent
|
|
378
|
+
* schemas.
|
|
379
|
+
*/
|
|
380
|
+
export type ItemEventHandler<$Item = any> = (
|
|
381
|
+
itemParams: DitoContext<$Item>
|
|
382
|
+
) => void | false
|
|
383
|
+
|
|
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> {
|
|
429
|
+
/**
|
|
430
|
+
* The label of the component.
|
|
431
|
+
*
|
|
432
|
+
* @defaultValue The title-cased component name.
|
|
433
|
+
*/
|
|
434
|
+
label?: OrItemAccessor<$Item, {}, string | boolean>
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* The width of the component. The value can either be given in percent
|
|
438
|
+
* (e.g. '20%' or a value between 0 and 1), or as 'auto' to have the width
|
|
439
|
+
* depend on its contents or as 'fill' to fill left over space. A line will
|
|
440
|
+
* contain multiple components until their widths exceed 100%.
|
|
441
|
+
*/
|
|
442
|
+
width?: OrItemAccessor<
|
|
443
|
+
$Item,
|
|
444
|
+
{},
|
|
445
|
+
'auto' | 'fill' | `${number}%` | `${number}/${number}` | number
|
|
446
|
+
>
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Whether the component is visible.
|
|
450
|
+
*
|
|
451
|
+
* @defaultValue `true`
|
|
452
|
+
*/
|
|
453
|
+
visible?: OrItemAccessor<$Item, {}, boolean>
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Whether to exclude the field's value from the processed data
|
|
457
|
+
* sent to the server.
|
|
458
|
+
*
|
|
459
|
+
* @defaultValue `false`
|
|
460
|
+
*/
|
|
461
|
+
exclude?: OrItemAccessor<$Item, {}, boolean>
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Whether the field is required.
|
|
465
|
+
* @defaultValue `false`
|
|
466
|
+
*/
|
|
467
|
+
required?: OrItemAccessor<$Item, {}, boolean>
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Whether the value is read only.
|
|
471
|
+
*
|
|
472
|
+
* @defaultValue `false`
|
|
473
|
+
*/
|
|
474
|
+
readonly?: OrItemAccessor<$Item, {}, boolean>
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Whether to autofocus the field.
|
|
478
|
+
* @defaultValue `false`
|
|
479
|
+
*/
|
|
480
|
+
autofocus?: OrItemAccessor<$Item, {}, boolean>
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Whether the field can be cleared.
|
|
484
|
+
* @defaultValue `false`
|
|
485
|
+
*/
|
|
486
|
+
clearable?: OrItemAccessor<$Item, {}, boolean>
|
|
487
|
+
|
|
488
|
+
/**
|
|
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.
|
|
500
|
+
*/
|
|
501
|
+
info?: OrItemAccessor<$Item, {}, string>
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* The maximum allowed length of the input value.
|
|
505
|
+
*/
|
|
506
|
+
maxLength?: OrItemAccessor<$Item, {}, number>
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Whether the input field should have autocomplete enabled.
|
|
510
|
+
*/
|
|
511
|
+
autocomplete?: OrItemAccessor<$Item, {}, 'on' | 'off'>
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Specifies a function which transforms the stored
|
|
515
|
+
* value into a display format before it is passed
|
|
516
|
+
* to the component for rendering.
|
|
517
|
+
*/
|
|
518
|
+
format?: ItemAccessor<$Item, {}, any>
|
|
519
|
+
/**
|
|
520
|
+
* Whether the component is disabled.
|
|
521
|
+
*
|
|
522
|
+
* @defaultValue `false`
|
|
523
|
+
*/
|
|
524
|
+
disabled?: OrItemAccessor<$Item, {}, boolean>
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Specifies a function which parses the component
|
|
528
|
+
* value when it changes, transforming the raw
|
|
529
|
+
* input before it is stored.
|
|
530
|
+
*/
|
|
531
|
+
parse?: ItemAccessor<$Item, {}>
|
|
532
|
+
|
|
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, {}>
|
|
541
|
+
|
|
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
|
+
*/
|
|
546
|
+
name?: string
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Called when the input element receives focus.
|
|
550
|
+
*/
|
|
551
|
+
onFocus?: ItemEventHandler<$Item>
|
|
552
|
+
/**
|
|
553
|
+
* Called when the input element loses focus.
|
|
554
|
+
*/
|
|
555
|
+
onBlur?: ItemEventHandler<$Item>
|
|
556
|
+
/**
|
|
557
|
+
* Called on every keystroke or value modification. Unlike
|
|
558
|
+
* {@link BaseSchema.onChange}, fires synchronously.
|
|
559
|
+
*/
|
|
560
|
+
onInput?: ItemEventHandler<$Item>
|
|
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} */
|
|
570
|
+
focus?: ItemEventHandler<$Item>
|
|
571
|
+
/** @see {@link BaseSchema.onBlur} */
|
|
572
|
+
blur?: ItemEventHandler<$Item>
|
|
573
|
+
/** @see {@link BaseSchema.onInput} */
|
|
574
|
+
input?: ItemEventHandler<$Item>
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
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>
|
|
674
|
+
/**
|
|
675
|
+
* The number of items displayed per page. When not provided, all items are
|
|
676
|
+
* rendered.
|
|
677
|
+
*
|
|
678
|
+
* @defaultValue `false`
|
|
679
|
+
*/
|
|
680
|
+
paginate?: OrItemAccessor<$Item, {}, number>
|
|
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
|
+
*
|
|
690
|
+
* @defaultValue `false`
|
|
691
|
+
*/
|
|
692
|
+
inlined?: OrItemAccessor<$Item, {}, boolean>
|
|
693
|
+
/**
|
|
694
|
+
* Whether to add a button to create list items.
|
|
695
|
+
*
|
|
696
|
+
* @defaultValue `false`
|
|
697
|
+
*/
|
|
698
|
+
creatable?: OrItemAccessor<$Item, {}, boolean | { label: string }>
|
|
699
|
+
/**
|
|
700
|
+
* Whether to add edit buttons next to the list items.
|
|
701
|
+
*
|
|
702
|
+
* @defaultValue `false`
|
|
703
|
+
*/
|
|
704
|
+
editable?: OrItemAccessor<$Item, {}, boolean | { label: string }>
|
|
705
|
+
/**
|
|
706
|
+
* Whether to add delete buttons next to the list items.
|
|
707
|
+
*
|
|
708
|
+
* @defaultValue `false`
|
|
709
|
+
*/
|
|
710
|
+
deletable?: OrItemAccessor<$Item, {}, boolean | { label: string }>
|
|
711
|
+
/**
|
|
712
|
+
* The column used for the order resulting from dragging around list entries
|
|
713
|
+
* when the `draggable` property of the list schema is set to `true`.
|
|
714
|
+
*/
|
|
715
|
+
orderKey?: string
|
|
716
|
+
/**
|
|
717
|
+
* Whether the items can be reordered by the user. Set the `orderKey` property
|
|
718
|
+
* if you want the order to be persisted into a column.
|
|
719
|
+
* @defaultValue `false`
|
|
720
|
+
*/
|
|
721
|
+
draggable?: OrItemAccessor<$Item, {}, boolean>
|
|
722
|
+
/**
|
|
723
|
+
* Whether an inlined form is collapsible.
|
|
724
|
+
* @defaultValue `null`
|
|
725
|
+
*/
|
|
726
|
+
collapsible?: OrItemAccessor<$Item, {}, boolean | null>
|
|
727
|
+
/** Whether the inlined form is collapsed. */
|
|
728
|
+
collapsed?: OrItemAccessor<$Item, {}, boolean>
|
|
729
|
+
/**
|
|
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.
|
|
742
|
+
*/
|
|
743
|
+
resource?: Resource
|
|
744
|
+
/**
|
|
745
|
+
* The name of a view to reference for form schemas and
|
|
746
|
+
* editing navigation.
|
|
747
|
+
*/
|
|
748
|
+
view?: string
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
export type SchemaOptionsOption<$Value> =
|
|
752
|
+
| { label: string; value: $Value }
|
|
753
|
+
| $Value
|
|
754
|
+
export type SchemaOptions<$Item, $Option = any> =
|
|
755
|
+
| SchemaOptionsOption<$Option>[]
|
|
756
|
+
| {
|
|
757
|
+
/**
|
|
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.
|
|
763
|
+
*/
|
|
764
|
+
data?: OrItemAccessor<
|
|
765
|
+
$Item,
|
|
766
|
+
{},
|
|
767
|
+
OrItemAccessor<$Item, {}, OrPromiseOf<SchemaOptionsOption<$Option>[]>>
|
|
768
|
+
>
|
|
769
|
+
/**
|
|
770
|
+
* Either the key of the option property which should be treated as
|
|
771
|
+
* the option label or a function returning the option label.
|
|
772
|
+
*
|
|
773
|
+
* @defaultValue `'label'` when no label is supplied and the options are
|
|
774
|
+
* objects
|
|
775
|
+
*/
|
|
776
|
+
label?: keyof $Option | ItemAccessor<$Item, { option: $Option }, string>
|
|
777
|
+
/**
|
|
778
|
+
* Either the key of the option property which should be
|
|
779
|
+
* treated as the value or a function returning the option
|
|
780
|
+
* value.
|
|
781
|
+
*
|
|
782
|
+
* @defaultValue `'id'` when `relate` is set, otherwise
|
|
783
|
+
* `'value'` when the options are objects.
|
|
784
|
+
*/
|
|
785
|
+
value?: keyof $Option | ItemAccessor<$Item, { option: $Option }>
|
|
786
|
+
/**
|
|
787
|
+
* The key of the option property which should used to group the options.
|
|
788
|
+
*/
|
|
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
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
export interface SchemaOptionsMixin<$Item, $Option = any> {
|
|
827
|
+
/** The available options for selection. */
|
|
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
|
+
*/
|
|
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
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
export interface SchemaNumberMixin<$Item> {
|
|
887
|
+
/**
|
|
888
|
+
* The minimum value.
|
|
889
|
+
*/
|
|
890
|
+
min?: OrItemAccessor<$Item, {}, number>
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* The maximum value.
|
|
894
|
+
*/
|
|
895
|
+
max?: OrItemAccessor<$Item, {}, number>
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* The minimum and maximum value.
|
|
899
|
+
*/
|
|
900
|
+
range?: OrItemAccessor<$Item, {}, [number, number]>
|
|
901
|
+
/**
|
|
902
|
+
* When defined, buttons with up and down arrows are added next to the input
|
|
903
|
+
* field. Which when pressed will add or subtract `step` from the value.
|
|
904
|
+
*/
|
|
905
|
+
step?: OrItemAccessor<$Item, {}, number>
|
|
906
|
+
/**
|
|
907
|
+
* The amount of decimals to round to.
|
|
908
|
+
*/
|
|
909
|
+
decimals?: OrItemAccessor<$Item, {}, number>
|
|
910
|
+
/** Validation rules for numeric constraints. */
|
|
911
|
+
rules?: Omit<SchemaNumberMixin<$Item>, 'rules'> & {
|
|
912
|
+
/** Restrict the value to whole numbers. */
|
|
913
|
+
integer?: boolean
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
export interface SchemaTextMixin<$Item> {
|
|
918
|
+
/**
|
|
919
|
+
* Whether to trim whitespace from the value.
|
|
920
|
+
*/
|
|
921
|
+
trim?: OrItemAccessor<$Item, {}, boolean>
|
|
922
|
+
}
|
|
923
|
+
|
|
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> {
|
|
938
|
+
/**
|
|
939
|
+
* Prefix content displayed before the input.
|
|
940
|
+
*/
|
|
941
|
+
prefix?: OrArrayOf<SchemaAffix>
|
|
942
|
+
/**
|
|
943
|
+
* Suffix content displayed after the input.
|
|
944
|
+
*/
|
|
945
|
+
suffix?: OrArrayOf<SchemaAffix>
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
export interface SchemaDataMixin<$Item> {
|
|
949
|
+
/**
|
|
950
|
+
* Data source for the component.
|
|
951
|
+
*/
|
|
952
|
+
data?: OrItemAccessor<$Item, {}, any>
|
|
953
|
+
/**
|
|
954
|
+
* Path to retrieve data from parent context.
|
|
955
|
+
*/
|
|
956
|
+
dataPath?: string
|
|
957
|
+
}
|
|
958
|
+
|
|
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> {
|
|
965
|
+
/**
|
|
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.
|
|
970
|
+
*/
|
|
971
|
+
methods?: Record<string, (...args: any[]) => any> &
|
|
972
|
+
ThisType<DitoComponentInstance<$Item>>
|
|
973
|
+
|
|
974
|
+
/**
|
|
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.
|
|
981
|
+
*/
|
|
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>
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
export interface SwitchSchema<$Item = any> extends BaseSchema<$Item> {
|
|
1176
|
+
/**
|
|
1177
|
+
* The type of the component.
|
|
1178
|
+
*/
|
|
1179
|
+
type: 'switch'
|
|
1180
|
+
labels?: {
|
|
1181
|
+
/**
|
|
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'`
|
|
1191
|
+
*/
|
|
1192
|
+
unchecked?: string
|
|
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
|
+
}
|
|
1220
|
+
|
|
1221
|
+
export interface TextareaSchema<$Item = any>
|
|
1222
|
+
extends BaseSchema<$Item>,
|
|
1223
|
+
SchemaTextMixin<$Item> {
|
|
1224
|
+
/**
|
|
1225
|
+
* The type of the component.
|
|
1226
|
+
*/
|
|
1227
|
+
type: 'textarea'
|
|
1228
|
+
/**
|
|
1229
|
+
* Whether the input element is resizable.
|
|
1230
|
+
*/
|
|
1231
|
+
resizable?: OrItemAccessor<$Item, {}, boolean>
|
|
1232
|
+
/**
|
|
1233
|
+
* The amount of visible lines.
|
|
1234
|
+
*
|
|
1235
|
+
* @defaultValue `4`
|
|
1236
|
+
*/
|
|
1237
|
+
lines?: number
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
export interface CodeSchema<$Item = any> extends BaseSchema<$Item> {
|
|
1241
|
+
/**
|
|
1242
|
+
* The type of the component.
|
|
1243
|
+
*/
|
|
1244
|
+
type: 'code'
|
|
1245
|
+
/**
|
|
1246
|
+
* The code language.
|
|
1247
|
+
*
|
|
1248
|
+
* @defaultValue `js`
|
|
1249
|
+
*/
|
|
1250
|
+
language?: OrItemAccessor<$Item, {}, string>
|
|
1251
|
+
/**
|
|
1252
|
+
* The indent size.
|
|
1253
|
+
*
|
|
1254
|
+
* @defaultValue `2`
|
|
1255
|
+
*/
|
|
1256
|
+
indentSize?: OrItemAccessor<$Item, {}, number>
|
|
1257
|
+
/**
|
|
1258
|
+
* The amount of visible lines.
|
|
1259
|
+
*
|
|
1260
|
+
* @defaultValue `3`
|
|
1261
|
+
*/
|
|
1262
|
+
lines?: OrItemAccessor<$Item, {}, number>
|
|
1263
|
+
/**
|
|
1264
|
+
* Whether the input element is resizable.
|
|
1265
|
+
*/
|
|
1266
|
+
resizable?: OrItemAccessor<$Item, {}, boolean>
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
export interface MarkupSchema<$Item = any> extends BaseSchema<$Item> {
|
|
1270
|
+
/**
|
|
1271
|
+
* The type of the component.
|
|
1272
|
+
*/
|
|
1273
|
+
type: 'markup'
|
|
1274
|
+
/**
|
|
1275
|
+
* Whether the input element is resizable.
|
|
1276
|
+
*/
|
|
1277
|
+
resizable?: OrItemAccessor<$Item, {}, boolean>
|
|
1278
|
+
/**
|
|
1279
|
+
* @defaultValue `'collapse'`
|
|
1280
|
+
*/
|
|
1281
|
+
whitespace?: OrItemAccessor<
|
|
1282
|
+
$Item,
|
|
1283
|
+
{},
|
|
1284
|
+
'collapse' | 'preserve' | 'preserve-all'
|
|
1285
|
+
>
|
|
1286
|
+
/**
|
|
1287
|
+
* The amount of visible lines.
|
|
1288
|
+
*
|
|
1289
|
+
* @defaultValue `10`
|
|
1290
|
+
*/
|
|
1291
|
+
lines?: number
|
|
1292
|
+
|
|
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
|
+
*/
|
|
1300
|
+
enableRules?: OrItemAccessor<
|
|
1301
|
+
$Item,
|
|
1302
|
+
{},
|
|
1303
|
+
| boolean
|
|
1304
|
+
| {
|
|
1305
|
+
input: boolean
|
|
1306
|
+
paste: boolean
|
|
1307
|
+
}
|
|
1308
|
+
>
|
|
1309
|
+
/**
|
|
1310
|
+
* Whether Enter creates a hard break instead of a new
|
|
1311
|
+
* paragraph.
|
|
1312
|
+
*/
|
|
1313
|
+
hardBreak?: boolean
|
|
1314
|
+
marks?: {
|
|
1315
|
+
bold?: boolean
|
|
1316
|
+
italic?: boolean
|
|
1317
|
+
underline?: boolean
|
|
1318
|
+
strike?: boolean
|
|
1319
|
+
small?: boolean
|
|
1320
|
+
code?: boolean
|
|
1321
|
+
subscript?: boolean
|
|
1322
|
+
superscript?: boolean
|
|
1323
|
+
link?: boolean
|
|
1324
|
+
}
|
|
1325
|
+
nodes?: {
|
|
1326
|
+
blockquote?: boolean
|
|
1327
|
+
codeBlock?: boolean
|
|
1328
|
+
heading?: (1 | 2 | 3 | 4 | 5 | 6)[]
|
|
1329
|
+
horizontalRule?: boolean
|
|
1330
|
+
orderedList?: boolean
|
|
1331
|
+
bulletList?: boolean
|
|
1332
|
+
}
|
|
1333
|
+
tools?: {
|
|
1334
|
+
history?: boolean
|
|
1335
|
+
footnotes?: boolean
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
export interface LabelSchema<$Item = any> extends BaseSchema<$Item> {
|
|
1340
|
+
/**
|
|
1341
|
+
* The type of the component.
|
|
1342
|
+
*/
|
|
1343
|
+
type: 'label'
|
|
1344
|
+
}
|
|
1345
|
+
|
|
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> {
|
|
1353
|
+
/**
|
|
1354
|
+
* The type of the component.
|
|
1355
|
+
*/
|
|
1356
|
+
type: 'hidden'
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
export interface UploadSchema<$Item = any> extends BaseSchema<$Item> {
|
|
1360
|
+
/**
|
|
1361
|
+
* The type of the component.
|
|
1362
|
+
*/
|
|
1363
|
+
type: 'upload'
|
|
1364
|
+
/**
|
|
1365
|
+
* Whether multiple files can be uploaded.
|
|
1366
|
+
*
|
|
1367
|
+
* @default false
|
|
1368
|
+
*/
|
|
1369
|
+
multiple?: boolean
|
|
1370
|
+
/**
|
|
1371
|
+
* Allowed file extensions for upload.
|
|
1372
|
+
* @example 'zip' // Only files with zip extension
|
|
1373
|
+
* @example ['jpg', 'jpeg', 'gif', 'png']
|
|
1374
|
+
* @example /\.(gif|jpe?g|png)$/i
|
|
1375
|
+
*/
|
|
1376
|
+
extensions?: OrArrayOf<RegExp | string>
|
|
1377
|
+
/**
|
|
1378
|
+
* One or more unique file type specifiers that describe the type of file
|
|
1379
|
+
* that may be selected for upload by the user.
|
|
1380
|
+
*
|
|
1381
|
+
* @example 'audio/*' // Any type of audio file
|
|
1382
|
+
* @example ['image/png', 'image/gif', 'image/jpeg']
|
|
1383
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#Unique_file_type_specifiers }
|
|
1384
|
+
*/
|
|
1385
|
+
accept?: OrArrayOf<string>
|
|
1386
|
+
/**
|
|
1387
|
+
* The maximum size of the file expressed as number of bytes or as a string
|
|
1388
|
+
* like `'200kb'`, `'1mb'`, `'3.2gb'`, etc.
|
|
1389
|
+
*
|
|
1390
|
+
* @see {@link https://github.com/patrickkettner/filesize-parser/blob/master/test.js String Examples}
|
|
1391
|
+
*/
|
|
1392
|
+
maxSize?: string | number
|
|
1393
|
+
/**
|
|
1394
|
+
* Whether uploaded files can be reordered by dragging.
|
|
1395
|
+
*
|
|
1396
|
+
* @defaultValue `false`
|
|
1397
|
+
*/
|
|
1398
|
+
draggable?: OrItemAccessor<$Item, {}, boolean>
|
|
1399
|
+
/**
|
|
1400
|
+
* Whether files can be deleted.
|
|
1401
|
+
*/
|
|
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
|
+
>
|
|
1504
|
+
}
|
|
1505
|
+
|
|
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> & {
|
|
1565
|
+
/**
|
|
1566
|
+
* The type of the component.
|
|
1567
|
+
*/
|
|
1568
|
+
type: 'section'
|
|
1569
|
+
/**
|
|
1570
|
+
* Multiple form schemas keyed by item type, for
|
|
1571
|
+
* sections with polymorphic content.
|
|
1572
|
+
*/
|
|
1573
|
+
forms?: {
|
|
1574
|
+
[key: string]: ResolvableForm
|
|
1575
|
+
}
|
|
1576
|
+
/**
|
|
1577
|
+
* Renders the section with reduced spacing.
|
|
1578
|
+
*
|
|
1579
|
+
* @defaultValue `false`
|
|
1580
|
+
*/
|
|
1581
|
+
compact?: boolean
|
|
1582
|
+
/**
|
|
1583
|
+
* Enables copy/paste for the section's data.
|
|
1584
|
+
*/
|
|
1585
|
+
clipboard?: ClipboardConfig
|
|
1586
|
+
/**
|
|
1587
|
+
* Whether the section can be collapsed.
|
|
1588
|
+
*/
|
|
1589
|
+
collapsible?: OrItemAccessor<$Item, {}, boolean>
|
|
1590
|
+
/** Whether the section is collapsed. */
|
|
1591
|
+
collapsed?: OrItemAccessor<$Item, {}, boolean>
|
|
1592
|
+
/**
|
|
1593
|
+
* Grouped event handlers.
|
|
1594
|
+
*/
|
|
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
|
+
)
|
|
1628
|
+
|
|
1629
|
+
export interface CheckboxSchema<$Item = any> extends BaseSchema<$Item> {
|
|
1630
|
+
/**
|
|
1631
|
+
* The type of the component.
|
|
1632
|
+
*/
|
|
1633
|
+
type: 'checkbox'
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
export interface CheckboxesSchema<$Item = any>
|
|
1637
|
+
extends BaseSchema<$Item>,
|
|
1638
|
+
SchemaOptionsMixin<$Item> {
|
|
1639
|
+
/**
|
|
1640
|
+
* The type of the component.
|
|
1641
|
+
*/
|
|
1642
|
+
type: 'checkboxes'
|
|
1643
|
+
/**
|
|
1644
|
+
* @defaultValue `'vertical'`
|
|
1645
|
+
*/
|
|
1646
|
+
layout?: 'horizontal' | 'vertical'
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
export type ColorFormat =
|
|
1650
|
+
| 'rgb'
|
|
1651
|
+
| 'prgb'
|
|
1652
|
+
| 'hex'
|
|
1653
|
+
| 'hex6'
|
|
1654
|
+
| 'hex3'
|
|
1655
|
+
| 'hex4'
|
|
1656
|
+
| 'hex8'
|
|
1657
|
+
| 'name'
|
|
1658
|
+
| 'hsl'
|
|
1659
|
+
| 'hsv'
|
|
1660
|
+
export interface ColorSchema<$Item = any>
|
|
1661
|
+
extends BaseSchema<$Item>,
|
|
1662
|
+
SchemaAffixMixin<$Item> {
|
|
1663
|
+
/**
|
|
1664
|
+
* The type of the component.
|
|
1665
|
+
*/
|
|
1666
|
+
type: 'color'
|
|
1667
|
+
/**
|
|
1668
|
+
* The color format.
|
|
1669
|
+
*/
|
|
1670
|
+
format?: OrItemAccessor<$Item, {}, ColorFormat>
|
|
1671
|
+
/**
|
|
1672
|
+
* Whether the color may contain an alpha component.
|
|
1673
|
+
*
|
|
1674
|
+
* @defaultValue `false`
|
|
1675
|
+
*/
|
|
1676
|
+
alpha?: OrItemAccessor<$Item, {}, boolean>
|
|
1677
|
+
/**
|
|
1678
|
+
* Whether to display input fields for manual color value
|
|
1679
|
+
* entry (e.g. RGB, HSL) in the color picker.
|
|
1680
|
+
*
|
|
1681
|
+
* @defaultValue `true`
|
|
1682
|
+
*/
|
|
1683
|
+
inputs?: OrItemAccessor<$Item, {}, boolean>
|
|
1684
|
+
/**
|
|
1685
|
+
* Color presets as an array of color values as strings in any css
|
|
1686
|
+
* compatible format.
|
|
1687
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/color_value}
|
|
1688
|
+
*/
|
|
1689
|
+
presets?: OrItemAccessor<$Item, {}, string[]>
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
export type ColumnSchema<$Item = any, $Value = any> = {
|
|
1693
|
+
/**
|
|
1694
|
+
* The label of the column.
|
|
1695
|
+
* @defaultValue The labelized column key.
|
|
1696
|
+
*/
|
|
1697
|
+
label?: string
|
|
1698
|
+
/**
|
|
1699
|
+
* Use a Vue component to render the cell. The component is specified
|
|
1700
|
+
* like this: import(...).
|
|
1701
|
+
*/
|
|
1702
|
+
component?: Resolvable<VueComponent>
|
|
1703
|
+
/**
|
|
1704
|
+
* Whether the column should be sortable.
|
|
1705
|
+
*/
|
|
1706
|
+
sortable?: boolean
|
|
1707
|
+
/**
|
|
1708
|
+
* A function of the value and the item returning the displayed name.
|
|
1709
|
+
* If the column is sortable, the column is sorted by value and not by
|
|
1710
|
+
* rendered name.
|
|
1711
|
+
*/
|
|
1712
|
+
render?: ItemAccessor<$Item, { value: $Value }, string | null | undefined>
|
|
1713
|
+
/**
|
|
1714
|
+
* The provided string is applied to the class property of the column
|
|
1715
|
+
* cell html elements.
|
|
1716
|
+
*/
|
|
1717
|
+
class?: string
|
|
1718
|
+
/**
|
|
1719
|
+
* The provided string is applied to the style property of the column
|
|
1720
|
+
* cell html elements.
|
|
1721
|
+
*/
|
|
1722
|
+
style?: string | Partial<CSSStyleDeclaration>
|
|
1723
|
+
/**
|
|
1724
|
+
* Sort the colum in ascending or descending order. Columns are ordered by the
|
|
1725
|
+
* first column to specify `defaultSort`.
|
|
1726
|
+
*/
|
|
1727
|
+
defaultSort?: 'asc' | 'desc'
|
|
1728
|
+
/** Whether to display the column. */
|
|
1729
|
+
if?: OrItemAccessor<$Item, {}, boolean>
|
|
1730
|
+
}
|
|
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
|
+
*/
|
|
1737
|
+
export type ResolvableForm<$Item = any> = Resolvable<Form<$Item>>
|
|
1738
|
+
|
|
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'
|
|
1747
|
+
|
|
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
|
+
}
|
|
1791
|
+
|
|
1792
|
+
export type OrItemAccessor<
|
|
1793
|
+
$Item = any,
|
|
1794
|
+
$Params extends {} = {},
|
|
1795
|
+
$ReturnValue = any
|
|
1796
|
+
> = ItemAccessor<$Item, $Params, $ReturnValue> | $ReturnValue
|
|
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
|
+
|
|
1811
|
+
export type ItemAccessor<
|
|
1812
|
+
$Item = any,
|
|
1813
|
+
$Params extends {} = {},
|
|
1814
|
+
$ReturnValue = any
|
|
1815
|
+
> = (params: Merge<DitoContext<$Item>, $Params>) => $ReturnValue
|
|
1816
|
+
|
|
1817
|
+
export type DitoContext<$Item = any> = {
|
|
1818
|
+
/**
|
|
1819
|
+
* `true` when the data-path points to a value inside
|
|
1820
|
+
* an item, `false` when it points to the item itself.
|
|
1821
|
+
*/
|
|
1822
|
+
nested: boolean
|
|
1823
|
+
/** The current value of the component. */
|
|
1824
|
+
value: any
|
|
1825
|
+
/** Full dot-separated path to the current data. */
|
|
1826
|
+
dataPath: string
|
|
1827
|
+
/** The property name of the current component. */
|
|
1828
|
+
name: string
|
|
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.
|
|
1851
|
+
*/
|
|
1852
|
+
parentItem: any
|
|
1853
|
+
/** The top-level root data item. */
|
|
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
|
+
*/
|
|
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
|
+
*/
|
|
1870
|
+
clipboardItem: any
|
|
1871
|
+
/** The currently authenticated user. */
|
|
1872
|
+
user: {
|
|
1873
|
+
roles?: string[]
|
|
1874
|
+
hasRole(...roles: string[]): boolean
|
|
1875
|
+
}
|
|
1876
|
+
/** The admin API configuration. */
|
|
1877
|
+
api: ApiConfig
|
|
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. */
|
|
1885
|
+
itemLabel: string | null
|
|
1886
|
+
/** Display label of the current form. */
|
|
1887
|
+
formLabel: string | null
|
|
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. */
|
|
1911
|
+
option: any
|
|
1912
|
+
/** All available options in a select. */
|
|
1913
|
+
options: any
|
|
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
|
+
*/
|
|
1938
|
+
wasNotified: boolean
|
|
1939
|
+
|
|
1940
|
+
// Helper Methods
|
|
1941
|
+
|
|
1942
|
+
/** Performs an API request with optional caching. */
|
|
1943
|
+
request<T>(options: {
|
|
1944
|
+
/**
|
|
1945
|
+
* Allows caching of loaded data on two levels:
|
|
1946
|
+
* - 'global': cache globally, for the entire admin session
|
|
1947
|
+
* - 'local': cache locally within the closest route
|
|
1948
|
+
* component that is associated with a resource and loads
|
|
1949
|
+
* its own data.
|
|
1950
|
+
*/
|
|
1951
|
+
cache?: 'local' | 'global'
|
|
1952
|
+
url: string
|
|
1953
|
+
/**
|
|
1954
|
+
* @default 'get'
|
|
1955
|
+
*/
|
|
1956
|
+
method?: HTTPMethod
|
|
1957
|
+
query?:
|
|
1958
|
+
| Record<string, string | number | (string | number)[]>
|
|
1959
|
+
| [string, string | number][]
|
|
1960
|
+
data?: unknown
|
|
1961
|
+
resource?: Resource
|
|
1962
|
+
}): Promise<T>
|
|
1963
|
+
/** Formats values using locale-aware formatters. */
|
|
1964
|
+
format: typeof utilsFormat
|
|
1965
|
+
/** Navigates to a route programmatically. */
|
|
1966
|
+
navigate: VueRouter['push']
|
|
1967
|
+
/**
|
|
1968
|
+
* Triggers a file download from the given URL or
|
|
1969
|
+
* options.
|
|
1970
|
+
*/
|
|
1971
|
+
download: {
|
|
1972
|
+
(url: string): void
|
|
1973
|
+
(options: { url: string; filename: string }): void
|
|
1974
|
+
}
|
|
1975
|
+
/** Returns the full URL for a given resource. */
|
|
1976
|
+
getResourceUrl(resource: Resource): string
|
|
1977
|
+
/** Displays a notification to the user. */
|
|
1978
|
+
notify(options: {
|
|
1979
|
+
type?: LiteralUnion<'warning' | 'error' | 'info' | 'success'>
|
|
1980
|
+
title?: string
|
|
1981
|
+
text: OrArrayOf<string>
|
|
1982
|
+
}): void
|
|
1983
|
+
}
|
|
1984
|
+
|
|
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
|
|
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
|
|
2754
|
+
| {
|
|
2755
|
+
copy?: (context: DitoContext) => unknown
|
|
2756
|
+
paste?: (context: DitoContext) => unknown
|
|
2757
|
+
}
|
|
2758
|
+
|
|
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> =
|
|
2929
|
+
| InputSchema<$Item>
|
|
2930
|
+
| RadioSchema<$Item>
|
|
2931
|
+
| CheckboxSchema<$Item>
|
|
2932
|
+
| CheckboxesSchema<$Item>
|
|
2933
|
+
| ColorSchema<$Item>
|
|
2934
|
+
| SelectSchema<$Item>
|
|
2935
|
+
| MultiselectSchema<$Item>
|
|
2936
|
+
| ListSchema<$Item>
|
|
2937
|
+
| TextareaSchema<$Item>
|
|
2938
|
+
| CodeSchema<$Item>
|
|
2939
|
+
| NumberSchema<$Item>
|
|
2940
|
+
| SliderSchema<$Item>
|
|
2941
|
+
| UploadSchema<$Item>
|
|
2942
|
+
| MarkupSchema<$Item>
|
|
2943
|
+
| ButtonSchema<$Item>
|
|
2944
|
+
| SwitchSchema<$Item>
|
|
2945
|
+
| DateSchema<$Item>
|
|
2946
|
+
| ComponentSchema<$Item>
|
|
2947
|
+
| LabelSchema<$Item>
|
|
2948
|
+
| HiddenSchema<$Item>
|
|
2949
|
+
| ObjectSchema<$Item>
|
|
2950
|
+
| TreeListSchema<$Item>
|
|
2951
|
+
| TreeObjectSchema<$Item>
|
|
2952
|
+
| ComputedSchema<$Item>
|
|
2953
|
+
| DataSchema<$Item>
|
|
2954
|
+
| SpacerSchema<$Item>
|
|
2955
|
+
| ProgressSchema<$Item>
|
|
2956
|
+
|
|
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
|
|
3069
|
+
}
|
|
3070
|
+
|
|
3071
|
+
export type Buttons<$Item> = Record<
|
|
3072
|
+
string,
|
|
3073
|
+
SetOptional<ButtonSchema<$Item>, 'type'>
|
|
3074
|
+
>
|
|
3075
|
+
|
|
3076
|
+
export interface Form<$Item = any> extends SchemaRoute<$Item> {
|
|
3077
|
+
type: 'form'
|
|
3078
|
+
|
|
3079
|
+
/**
|
|
3080
|
+
* The name of the item model produced by the form.
|
|
3081
|
+
*/
|
|
3082
|
+
name?: OrItemAccessor<$Item, {}, string>
|
|
3083
|
+
/**
|
|
3084
|
+
* The label of the form.
|
|
3085
|
+
*/
|
|
3086
|
+
label?: OrItemAccessor<$Item, {}, string | boolean>
|
|
3087
|
+
/**
|
|
3088
|
+
* Whether the form directly mutates the parent data instead
|
|
3089
|
+
* of working on a copy.
|
|
3090
|
+
*
|
|
3091
|
+
* @defaultValue `false`
|
|
3092
|
+
*/
|
|
3093
|
+
mutate?: boolean
|
|
3094
|
+
/**
|
|
3095
|
+
* The property name used as the item's unique identifier.
|
|
3096
|
+
*
|
|
3097
|
+
* @defaultValue `'id'`
|
|
3098
|
+
*/
|
|
3099
|
+
idKey?: string
|
|
3100
|
+
/**
|
|
3101
|
+
* Display several forms in different tabs within the form.
|
|
3102
|
+
*/
|
|
3103
|
+
tabs?: Record<
|
|
3104
|
+
string,
|
|
3105
|
+
Omit<Form<$Item>, 'tabs' | 'type'> & {
|
|
3106
|
+
type: 'tab'
|
|
3107
|
+
/**
|
|
3108
|
+
* Whether this tab is selected by default.
|
|
3109
|
+
*/
|
|
3110
|
+
defaultTab?: OrItemAccessor<$Item, {}, boolean>
|
|
3111
|
+
}
|
|
3112
|
+
>
|
|
3113
|
+
/** The form's field components. */
|
|
3114
|
+
components?: Components<$Item>
|
|
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>
|
|
3163
|
+
}
|
|
3164
|
+
|
|
3165
|
+
export type Resource =
|
|
3166
|
+
| string
|
|
3167
|
+
| RequireAtLeastOne<{
|
|
3168
|
+
path?: string
|
|
3169
|
+
method?: HTTPMethod
|
|
3170
|
+
data?: unknown
|
|
3171
|
+
}>
|
|
3172
|
+
|
|
3173
|
+
export class DitoAdmin<
|
|
3174
|
+
$Views extends Record<string, OrPromiseOf<View>> = Record<
|
|
3175
|
+
string,
|
|
3176
|
+
OrPromiseOf<View>
|
|
3177
|
+
>
|
|
3178
|
+
> {
|
|
3179
|
+
/** The DOM element the admin is mounted to. */
|
|
3180
|
+
el: Element
|
|
3181
|
+
/** The resolved API configuration. */
|
|
3182
|
+
api: ApiConfig
|
|
3183
|
+
/** The Vue application instance. */
|
|
3184
|
+
app: import('vue').App
|
|
3185
|
+
/** Additional options passed at construction. */
|
|
3186
|
+
options: Record<string, any>
|
|
3187
|
+
|
|
3188
|
+
constructor(
|
|
3189
|
+
element: Element | string,
|
|
3190
|
+
options?: {
|
|
3191
|
+
// `dito` contains the base and api settings passed from
|
|
3192
|
+
// `AdminController`
|
|
3193
|
+
dito?: DitoGlobal
|
|
3194
|
+
api?: ApiConfig
|
|
3195
|
+
views: OrFunctionReturning<OrPromiseOf<$Views>>
|
|
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
|
|
3209
|
+
}
|
|
3210
|
+
)
|
|
3211
|
+
|
|
3212
|
+
/**
|
|
3213
|
+
* Registers a custom component type with the admin.
|
|
3214
|
+
*/
|
|
3215
|
+
register(
|
|
3216
|
+
type: OrArrayOf<string>,
|
|
3217
|
+
options: Record<string, unknown>
|
|
3218
|
+
): VueComponent
|
|
3219
|
+
}
|
|
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
|
|
3232
|
+
|
|
3233
|
+
export type SchemaByType<$Item = any> = {
|
|
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
|
|
3274
|
+
}
|
|
3275
|
+
|
|
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>>
|
|
3297
|
+
|
|
3298
|
+
type LiteralUnion<T extends U, U = string> = T | (U & Record<never, never>)
|