@ditojs/admin 2.100.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dito-admin.css +1 -1
- package/dist/dito-admin.es.js +3421 -2662
- package/dist/dito-admin.umd.js +6 -6
- package/package.json +81 -45
- package/src/DitoComponent.js +1 -1
- package/src/DitoContext.js +51 -0
- package/src/DitoTypeComponent.js +6 -1
- package/src/components/DitoAffixes.vue +6 -3
- package/src/components/DitoContainer.vue +19 -10
- package/src/components/DitoCreateButton.vue +11 -2
- package/src/components/DitoDialog.vue +21 -2
- package/src/components/DitoForm.vue +156 -83
- package/src/components/DitoLabel.vue +3 -2
- package/src/components/DitoPane.vue +55 -11
- package/src/components/DitoPanel.vue +33 -5
- package/src/components/DitoPanels.vue +2 -1
- package/src/components/DitoRoot.vue +13 -6
- package/src/components/DitoSchema.vue +278 -145
- package/src/components/DitoSchemaInlined.vue +1 -1
- package/src/components/DitoTabs.vue +16 -18
- package/src/components/DitoTrail.vue +5 -4
- package/src/components/DitoTreeItem.vue +17 -6
- package/src/components/DitoView.vue +25 -2
- package/src/mixins/DitoMixin.js +42 -7
- package/src/mixins/ItemMixin.js +3 -6
- package/src/mixins/NumberMixin.js +47 -31
- package/src/mixins/OptionsMixin.js +122 -71
- package/src/mixins/ResourceMixin.js +5 -2
- package/src/mixins/RouteMixin.js +39 -1
- package/src/mixins/SortableMixin.js +0 -13
- package/src/mixins/SourceMixin.js +142 -95
- package/src/mixins/TextMixin.js +1 -1
- package/src/mixins/TypeMixin.js +37 -22
- package/src/mixins/ValidationMixin.js +9 -27
- package/src/mixins/ValidatorMixin.js +5 -7
- package/src/mixins/ValueMixin.js +5 -2
- package/src/types/DitoTypeButton.vue +1 -1
- package/src/types/DitoTypeCheckbox.vue +1 -1
- package/src/types/DitoTypeCheckboxes.vue +1 -1
- package/src/types/DitoTypeCode.vue +8 -1
- package/src/types/DitoTypeColor.vue +20 -34
- package/src/types/DitoTypeComponent.vue +1 -1
- package/src/types/DitoTypeComputed.vue +4 -27
- package/src/types/DitoTypeDate.vue +16 -5
- package/src/types/DitoTypeLabel.vue +1 -4
- package/src/types/DitoTypeList.vue +9 -5
- package/src/types/DitoTypeMarkup.vue +25 -13
- package/src/types/DitoTypeMultiselect.vue +26 -6
- package/src/types/DitoTypeNumber.vue +1 -1
- package/src/types/DitoTypeObject.vue +10 -7
- package/src/types/DitoTypePanel.vue +19 -6
- package/src/types/DitoTypeProgress.vue +1 -1
- package/src/types/DitoTypeRadio.vue +1 -1
- package/src/types/DitoTypeSection.vue +32 -4
- package/src/types/DitoTypeSelect.vue +1 -1
- package/src/types/DitoTypeSlider.vue +1 -1
- package/src/types/DitoTypeSwitch.vue +1 -1
- package/src/types/DitoTypeText.vue +13 -15
- package/src/types/DitoTypeTextarea.vue +1 -1
- package/src/types/DitoTypeTreeList.vue +12 -7
- package/src/types/DitoTypeUpload.vue +1 -2
- package/src/utils/DataSchemaResolver.js +141 -0
- package/src/utils/DataSchemaResolver.test.js +132 -0
- package/src/utils/FormModel.js +556 -0
- package/src/utils/FormModel.test.js +808 -0
- package/src/utils/data.js +20 -0
- package/src/utils/data.test.js +28 -0
- package/src/utils/filter.js +3 -2
- package/src/utils/options.js +3 -0
- package/src/utils/schema/data.js +617 -0
- package/src/utils/schema/data.test.js +471 -0
- package/src/utils/schema/lookup.js +266 -0
- package/src/utils/schema/lookup.test.js +61 -0
- package/src/utils/schema/setup.js +354 -0
- package/src/utils/schema/structure.js +172 -0
- package/src/utils/schema/structure.test.js +57 -0
- package/src/utils/schema/types.js +34 -0
- package/src/utils/schema/validation.js +142 -0
- package/src/utils/schema/validation.test.js +395 -0
- package/src/utils/units.js +70 -3
- package/src/utils/units.test.js +71 -0
- package/types/index.d.ts +149 -59
- package/src/mixins/DataMixin.js +0 -131
- package/src/utils/schema.js +0 -1121
package/types/index.d.ts
CHANGED
|
@@ -326,9 +326,10 @@ export interface BaseSchema<$Item>
|
|
|
326
326
|
*/
|
|
327
327
|
default?: OrItemAccessor<$Item>
|
|
328
328
|
/**
|
|
329
|
-
* Computes and sets the field value reactively
|
|
330
|
-
* the
|
|
331
|
-
*
|
|
329
|
+
* Computes and sets the field value reactively, also
|
|
330
|
+
* when the field isn't rendered, unless its `if`
|
|
331
|
+
* evaluates to `false`. If the callback returns
|
|
332
|
+
* `undefined`, the current value is preserved.
|
|
332
333
|
*/
|
|
333
334
|
compute?: ItemAccessor<$Item>
|
|
334
335
|
/**
|
|
@@ -367,19 +368,26 @@ export interface SchemaDitoMixin<$Item> {
|
|
|
367
368
|
* change before value validation occurs. Rule changes do not influence how
|
|
368
369
|
* the component is rendered.
|
|
369
370
|
*/
|
|
370
|
-
rules?:
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
371
|
+
rules?: SchemaRules
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Validation rules shared by all schemas, extended by the individual types.
|
|
376
|
+
*/
|
|
377
|
+
export interface SchemaRules {
|
|
378
|
+
/** Override whether the field is required. */
|
|
379
|
+
required?: boolean
|
|
374
380
|
}
|
|
375
381
|
|
|
376
382
|
/**
|
|
377
383
|
* Return false to mark event as handled and stop it from propagating to parent
|
|
378
384
|
* schemas.
|
|
379
385
|
*/
|
|
386
|
+
// Handlers can be async, as events are awaited, e.g. by buttons that show
|
|
387
|
+
// their progress while their `click` handler runs.
|
|
380
388
|
export type ItemEventHandler<$Item = any> = (
|
|
381
389
|
itemParams: DitoContext<$Item>
|
|
382
|
-
) => void | false
|
|
390
|
+
) => void | false | Promise<void | false>
|
|
383
391
|
|
|
384
392
|
export type OpenEventHandler<$Item = any> = (
|
|
385
393
|
itemParams: DitoContext<$Item> & { open: boolean }
|
|
@@ -565,14 +573,20 @@ export interface SchemaTypeMixin<$Item> extends SchemaFields<$Item> {
|
|
|
565
573
|
* @see {@link SchemaFields.onInitialize} and other `on`-
|
|
566
574
|
* prefixed properties for per-event documentation.
|
|
567
575
|
*/
|
|
568
|
-
events?:
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
+
events?: BaseSchemaEvents<$Item>
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Grouped event handlers shared by all schemas, extended by the individual
|
|
581
|
+
* types.
|
|
582
|
+
*/
|
|
583
|
+
export interface BaseSchemaEvents<$Item> extends SchemaEvents<$Item> {
|
|
584
|
+
/** @see {@link BaseSchema.onFocus} */
|
|
585
|
+
focus?: ItemEventHandler<$Item>
|
|
586
|
+
/** @see {@link BaseSchema.onBlur} */
|
|
587
|
+
blur?: ItemEventHandler<$Item>
|
|
588
|
+
/** @see {@link BaseSchema.onInput} */
|
|
589
|
+
input?: ItemEventHandler<$Item>
|
|
576
590
|
}
|
|
577
591
|
|
|
578
592
|
export interface SchemaSourceMixin<$Item> {
|
|
@@ -643,9 +657,18 @@ export interface SchemaSourceMixin<$Item> {
|
|
|
643
657
|
/** Buttons for the source. */
|
|
644
658
|
buttons?: Buttons<$Item>
|
|
645
659
|
/**
|
|
646
|
-
*
|
|
660
|
+
* The key under which primitive values are wrapped in objects, so that the
|
|
661
|
+
* source's forms can edit them, e.g. `'value'` for a list of strings.
|
|
662
|
+
*/
|
|
663
|
+
wrapPrimitives?: string
|
|
664
|
+
/**
|
|
665
|
+
* Whether the forms of the source's items directly mutate the source's data
|
|
666
|
+
* instead of editing a copy that is applied when submitting. Forms that
|
|
667
|
+
* mutate data are never dirty.
|
|
668
|
+
*
|
|
669
|
+
* @defaultValue `false`
|
|
647
670
|
*/
|
|
648
|
-
|
|
671
|
+
mutate?: boolean
|
|
649
672
|
/**
|
|
650
673
|
* URL path for the source items.
|
|
651
674
|
*/
|
|
@@ -722,7 +745,9 @@ export interface SchemaSourceMixin<$Item> {
|
|
|
722
745
|
deletable?: OrItemAccessor<$Item, {}, boolean | { label: string }>
|
|
723
746
|
/**
|
|
724
747
|
* The column used for the order resulting from dragging around list entries
|
|
725
|
-
* when the `draggable` property of the list schema is set to `true`.
|
|
748
|
+
* when the `draggable` property of the list schema is set to `true`. Items
|
|
749
|
+
* are numbered when the data is loaded, and when they are added, removed or
|
|
750
|
+
* reordered.
|
|
726
751
|
*/
|
|
727
752
|
orderKey?: string
|
|
728
753
|
/**
|
|
@@ -919,14 +944,15 @@ export interface SchemaNumberMixin<$Item> {
|
|
|
919
944
|
*/
|
|
920
945
|
step?: OrItemAccessor<$Item, {}, number>
|
|
921
946
|
/**
|
|
922
|
-
* The amount of decimals
|
|
947
|
+
* The maximum amount of decimals allowed, validated on input.
|
|
923
948
|
*/
|
|
924
949
|
decimals?: OrItemAccessor<$Item, {}, number>
|
|
925
950
|
/** Validation rules for numeric constraints. */
|
|
926
|
-
rules?:
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
951
|
+
rules?: SchemaRules &
|
|
952
|
+
Omit<SchemaNumberMixin<$Item>, 'rules'> & {
|
|
953
|
+
/** Restrict the value to whole numbers. */
|
|
954
|
+
integer?: boolean
|
|
955
|
+
}
|
|
930
956
|
}
|
|
931
957
|
|
|
932
958
|
export interface SchemaTextMixin<$Item> {
|
|
@@ -964,7 +990,7 @@ export interface SchemaDataMixin<$Item> {
|
|
|
964
990
|
/**
|
|
965
991
|
* Data source for the component.
|
|
966
992
|
*/
|
|
967
|
-
data?: OrItemAccessor<$Item, {}, any
|
|
993
|
+
data?: OrItemAccessor<$Item, {}, Record<string, any>>
|
|
968
994
|
/**
|
|
969
995
|
* Path to retrieve data from parent context.
|
|
970
996
|
*/
|
|
@@ -1128,7 +1154,7 @@ export interface InputSchema<$Item = any>
|
|
|
1128
1154
|
| 'tel'
|
|
1129
1155
|
| 'password'
|
|
1130
1156
|
| 'creditcard'
|
|
1131
|
-
rules?: {
|
|
1157
|
+
rules?: SchemaRules & {
|
|
1132
1158
|
text?: boolean
|
|
1133
1159
|
email?: boolean
|
|
1134
1160
|
url?: boolean
|
|
@@ -1180,7 +1206,7 @@ export interface ButtonSchema<$Item = any>
|
|
|
1180
1206
|
onClick?: ItemEventHandler<$Item>
|
|
1181
1207
|
onSuccess?: ItemEventHandler<$Item>
|
|
1182
1208
|
onError?: ErrorEventHandler<$Item>
|
|
1183
|
-
events?: {
|
|
1209
|
+
events?: BaseSchemaEvents<$Item> & {
|
|
1184
1210
|
click?: ItemEventHandler<$Item>
|
|
1185
1211
|
success?: ItemEventHandler<$Item>
|
|
1186
1212
|
error?: ErrorEventHandler<$Item>
|
|
@@ -1209,8 +1235,9 @@ export interface SwitchSchema<$Item = any> extends BaseSchema<$Item> {
|
|
|
1209
1235
|
}
|
|
1210
1236
|
|
|
1211
1237
|
export interface NumberSchema<$Item = any>
|
|
1238
|
+
// `rules` comes from `SchemaNumberMixin`, which extends `SchemaRules`.
|
|
1212
1239
|
extends SchemaNumberMixin<$Item>,
|
|
1213
|
-
BaseSchema<$Item>,
|
|
1240
|
+
Omit<BaseSchema<$Item>, 'rules'>,
|
|
1214
1241
|
SchemaAffixMixin<$Item> {
|
|
1215
1242
|
/**
|
|
1216
1243
|
* The type of the component.
|
|
@@ -1219,8 +1246,9 @@ export interface NumberSchema<$Item = any>
|
|
|
1219
1246
|
}
|
|
1220
1247
|
|
|
1221
1248
|
export interface SliderSchema<$Item = any>
|
|
1249
|
+
// `rules` comes from `SchemaNumberMixin`, which extends `SchemaRules`.
|
|
1222
1250
|
extends SchemaNumberMixin<$Item>,
|
|
1223
|
-
BaseSchema<$Item> {
|
|
1251
|
+
Omit<BaseSchema<$Item>, 'rules'> {
|
|
1224
1252
|
/**
|
|
1225
1253
|
* The type of the component.
|
|
1226
1254
|
*/
|
|
@@ -1400,9 +1428,8 @@ export interface UploadSchema<$Item = any> extends BaseSchema<$Item> {
|
|
|
1400
1428
|
accept?: OrArrayOf<string>
|
|
1401
1429
|
/**
|
|
1402
1430
|
* The maximum size of the file expressed as number of bytes or as a string
|
|
1403
|
-
* like `'
|
|
1404
|
-
*
|
|
1405
|
-
* @see {@link https://github.com/patrickkettner/filesize-parser/blob/master/test.js String Examples}
|
|
1431
|
+
* like `'200kB'`, `'1MB'`, `'3.2GB'`, etc., using base 10 (1 kB = 1000
|
|
1432
|
+
* bytes). IEC units like `'1MiB'` use base 2 (1 KiB = 1024 bytes).
|
|
1406
1433
|
*/
|
|
1407
1434
|
maxSize?: string | number
|
|
1408
1435
|
/**
|
|
@@ -1502,7 +1529,7 @@ type SectionContent<$Data> = {
|
|
|
1502
1529
|
/**
|
|
1503
1530
|
* A form schema for the section's content. Use this
|
|
1504
1531
|
* instead of `components` to get form-level options
|
|
1505
|
-
* like `label
|
|
1532
|
+
* like `label` and `tabs`.
|
|
1506
1533
|
*/
|
|
1507
1534
|
form?: ResolvableForm<$Data>
|
|
1508
1535
|
/**
|
|
@@ -1679,7 +1706,9 @@ export type ColorFormat =
|
|
|
1679
1706
|
| 'hsl'
|
|
1680
1707
|
| 'hsv'
|
|
1681
1708
|
export interface ColorSchema<$Item = any>
|
|
1682
|
-
|
|
1709
|
+
// `format` is the color format here, not the formatting function of
|
|
1710
|
+
// `BaseSchema`.
|
|
1711
|
+
extends Omit<BaseSchema<$Item>, 'format'>,
|
|
1683
1712
|
SchemaAffixMixin<$Item> {
|
|
1684
1713
|
/**
|
|
1685
1714
|
* The type of the component.
|
|
@@ -1801,7 +1830,7 @@ export interface ListSchema<$Item = { [key: string]: any }>
|
|
|
1801
1830
|
/**
|
|
1802
1831
|
* Grouped event handlers.
|
|
1803
1832
|
*/
|
|
1804
|
-
events?: {
|
|
1833
|
+
events?: BaseSchemaEvents<$Item> & {
|
|
1805
1834
|
/**
|
|
1806
1835
|
* Called when a collapsible inlined list is
|
|
1807
1836
|
* toggled open or closed.
|
|
@@ -1930,7 +1959,12 @@ export type DitoContext<$Item = any> = {
|
|
|
1930
1959
|
sourceComponent: DitoSourceInstance | null
|
|
1931
1960
|
/** The currently focused option in a select. */
|
|
1932
1961
|
option: any
|
|
1933
|
-
/**
|
|
1962
|
+
/**
|
|
1963
|
+
* All available options in a select. In `compute()`, they are
|
|
1964
|
+
* loaded when first read, also when the field isn't rendered,
|
|
1965
|
+
* and are `undefined` while loading; the callback runs again
|
|
1966
|
+
* once they are loaded.
|
|
1967
|
+
*/
|
|
1934
1968
|
options: any
|
|
1935
1969
|
/**
|
|
1936
1970
|
* Whether a pulldown/select is currently open.
|
|
@@ -2062,6 +2096,14 @@ export interface DitoComponentInstanceBase<$Item = any>
|
|
|
2062
2096
|
name: string
|
|
2063
2097
|
/** Full dot-separated path to the current data. */
|
|
2064
2098
|
dataPath: string
|
|
2099
|
+
/**
|
|
2100
|
+
* The path of component names through views, tabs,
|
|
2101
|
+
* panels and forms, with item indices from the data
|
|
2102
|
+
* path, e.g. `main/chapters/0/title`. Unlike
|
|
2103
|
+
* `dataPath`, it tells apart components that display
|
|
2104
|
+
* the same data. Used as the component's DOM id.
|
|
2105
|
+
*/
|
|
2106
|
+
componentPath: string
|
|
2065
2107
|
/** The schema definition for the current component. */
|
|
2066
2108
|
schema: Component
|
|
2067
2109
|
/** The component type from the schema. */
|
|
@@ -2409,6 +2451,36 @@ export interface DitoFormInstance<$Item = any>
|
|
|
2409
2451
|
*/
|
|
2410
2452
|
isCreating: boolean
|
|
2411
2453
|
|
|
2454
|
+
/**
|
|
2455
|
+
* Whether the form's processed data differs from
|
|
2456
|
+
* the data it was loaded, saved or applied with.
|
|
2457
|
+
* Values that are derived when the data is set up,
|
|
2458
|
+
* e.g. defaults and computed values, don't count.
|
|
2459
|
+
* Forms with `mutate: true` aren't dirty
|
|
2460
|
+
* themselves, their changes make the form that
|
|
2461
|
+
* owns the data dirty.
|
|
2462
|
+
*/
|
|
2463
|
+
isDirty: boolean
|
|
2464
|
+
|
|
2465
|
+
/**
|
|
2466
|
+
* Makes clean changes to the data, which don't
|
|
2467
|
+
* make the form dirty, while other changes still
|
|
2468
|
+
* do, e.g. to apply what an action on the server
|
|
2469
|
+
* already saved. `makeChanges()` is called
|
|
2470
|
+
* synchronously, the returned promise resolves
|
|
2471
|
+
* once the values derived from the changes are
|
|
2472
|
+
* clean too.
|
|
2473
|
+
*
|
|
2474
|
+
* @example
|
|
2475
|
+
* ```js
|
|
2476
|
+
* const shopOrder = await request({ method: 'post', url })
|
|
2477
|
+
* formComponent.applyCleanChanges(() => {
|
|
2478
|
+
* item.templateShopOrder = shopOrder
|
|
2479
|
+
* })
|
|
2480
|
+
* ```
|
|
2481
|
+
*/
|
|
2482
|
+
applyCleanChanges(makeChanges: () => void): Promise<void>
|
|
2483
|
+
|
|
2412
2484
|
/**
|
|
2413
2485
|
* Submits the form data to the API. Returns
|
|
2414
2486
|
* `true` on success, `false` if validation
|
|
@@ -2435,7 +2507,9 @@ export interface DitoFormInstance<$Item = any>
|
|
|
2435
2507
|
close(): Promise<void>
|
|
2436
2508
|
|
|
2437
2509
|
/**
|
|
2438
|
-
* Validates all fields in the form
|
|
2510
|
+
* Validates all fields in the form's data, including
|
|
2511
|
+
* fields that aren't rendered, e.g. in collapsed
|
|
2512
|
+
* sections or closed nested forms. Optionally
|
|
2439
2513
|
* filter fields with a match pattern. Returns
|
|
2440
2514
|
* `true` if all matched fields are valid.
|
|
2441
2515
|
*/
|
|
@@ -2497,8 +2571,12 @@ export interface DitoFormInstance<$Item = any>
|
|
|
2497
2571
|
ensureData(): void
|
|
2498
2572
|
/** Clears the loaded data. */
|
|
2499
2573
|
clearData(): void
|
|
2500
|
-
/**
|
|
2501
|
-
|
|
2574
|
+
/**
|
|
2575
|
+
* Sets the component's loaded data directly, and
|
|
2576
|
+
* returns it as the component's reactive data,
|
|
2577
|
+
* which can be modified to update it.
|
|
2578
|
+
*/
|
|
2579
|
+
setData(data: any): any
|
|
2502
2580
|
/**
|
|
2503
2581
|
* Creates a new data object with default values
|
|
2504
2582
|
* from the schema. Optionally sets a `type`
|
|
@@ -2576,13 +2654,17 @@ export interface DitoViewInstance<$Item = any>
|
|
|
2576
2654
|
* a resource.
|
|
2577
2655
|
*/
|
|
2578
2656
|
providesData: boolean
|
|
2579
|
-
/**
|
|
2580
|
-
|
|
2657
|
+
/**
|
|
2658
|
+
* Sets the view's data directly, and returns it
|
|
2659
|
+
* as the view's reactive data.
|
|
2660
|
+
*/
|
|
2661
|
+
setData(data: any): any
|
|
2581
2662
|
|
|
2582
2663
|
// -- Validation (ValidatorMixin) --
|
|
2583
2664
|
|
|
2584
2665
|
/**
|
|
2585
|
-
* Validates all fields in the view
|
|
2666
|
+
* Validates all fields in the view's data,
|
|
2667
|
+
* including fields that aren't rendered.
|
|
2586
2668
|
* Optionally filter fields with a match pattern.
|
|
2587
2669
|
* Returns `true` if all matched fields are valid.
|
|
2588
2670
|
*/
|
|
@@ -2611,9 +2693,12 @@ export interface DitoViewInstance<$Item = any>
|
|
|
2611
2693
|
export interface DitoSchemaInstance<$Item = any>
|
|
2612
2694
|
extends DitoComponentInstanceBase<$Item> {
|
|
2613
2695
|
/**
|
|
2614
|
-
* Validates all fields in the schema
|
|
2696
|
+
* Validates all fields in the schema's data,
|
|
2697
|
+
* including fields that aren't rendered, e.g. in
|
|
2698
|
+
* collapsed sections or closed nested forms.
|
|
2615
2699
|
* Optionally filter fields with a match pattern
|
|
2616
|
-
* (string, string[], RegExp, or function)
|
|
2700
|
+
* (string, string[], RegExp, or function) over
|
|
2701
|
+
* their data paths.
|
|
2617
2702
|
* Returns `true` if all matched fields are
|
|
2618
2703
|
* valid.
|
|
2619
2704
|
*/
|
|
@@ -2717,11 +2802,14 @@ export interface DitoSourceInstance<$Item = any>
|
|
|
2717
2802
|
deleteItem(item: any, index: number): void
|
|
2718
2803
|
/**
|
|
2719
2804
|
* Navigates to a component identified by its
|
|
2720
|
-
* data path.
|
|
2805
|
+
* data path. With `shouldRevealInlinedOnly`, only
|
|
2806
|
+
* components in inlined schemas are revealed,
|
|
2807
|
+
* without navigating to nested forms.
|
|
2721
2808
|
*/
|
|
2722
2809
|
navigateToComponent(
|
|
2723
2810
|
dataPath: string,
|
|
2724
|
-
onComplete?: Function
|
|
2811
|
+
onComplete?: Function,
|
|
2812
|
+
options?: { shouldRevealInlinedOnly?: boolean }
|
|
2725
2813
|
): Promise<boolean>
|
|
2726
2814
|
/**
|
|
2727
2815
|
* Navigates to the route component associated
|
|
@@ -2756,8 +2844,12 @@ export interface DitoSourceInstance<$Item = any>
|
|
|
2756
2844
|
ensureData(): void
|
|
2757
2845
|
/** Clears the loaded data. */
|
|
2758
2846
|
clearData(): void
|
|
2759
|
-
/**
|
|
2760
|
-
|
|
2847
|
+
/**
|
|
2848
|
+
* Sets the component's loaded data directly, and
|
|
2849
|
+
* returns it as the component's reactive data,
|
|
2850
|
+
* which can be modified to update it.
|
|
2851
|
+
*/
|
|
2852
|
+
setData(data: any): any
|
|
2761
2853
|
/**
|
|
2762
2854
|
* Creates a new data object with default values
|
|
2763
2855
|
* from the schema. Optionally sets a `type`
|
|
@@ -2883,7 +2975,7 @@ export interface ObjectSchema<$Item = { [key: string]: any }>
|
|
|
2883
2975
|
/**
|
|
2884
2976
|
* Grouped event handlers.
|
|
2885
2977
|
*/
|
|
2886
|
-
events?: {
|
|
2978
|
+
events?: BaseSchemaEvents<$Item> & {
|
|
2887
2979
|
/**
|
|
2888
2980
|
* Called when a collapsible inlined object is
|
|
2889
2981
|
* toggled open or closed.
|
|
@@ -2953,8 +3045,9 @@ export interface SpacerSchema<$Item = any> extends BaseSchema<$Item> {
|
|
|
2953
3045
|
}
|
|
2954
3046
|
|
|
2955
3047
|
export interface ProgressSchema<$Item = any>
|
|
3048
|
+
// `rules` comes from `SchemaNumberMixin`, which extends `SchemaRules`.
|
|
2956
3049
|
extends SchemaNumberMixin<$Item>,
|
|
2957
|
-
BaseSchema<$Item> {
|
|
3050
|
+
Omit<BaseSchema<$Item>, 'rules'> {
|
|
2958
3051
|
/**
|
|
2959
3052
|
* The type of the component.
|
|
2960
3053
|
*/
|
|
@@ -2993,6 +3086,7 @@ type NonSectionComponent<$Item = any> =
|
|
|
2993
3086
|
export type Component<$Item = any> =
|
|
2994
3087
|
| NonSectionComponent<$Item>
|
|
2995
3088
|
| SectionSchema<$Item>
|
|
3089
|
+
| PanelSchema<$Item>
|
|
2996
3090
|
|
|
2997
3091
|
/**
|
|
2998
3092
|
* Source components (list, object, tree) that contain nested
|
|
@@ -3107,11 +3201,14 @@ export type Components<$Item = any> = 0 extends 1 & $Item
|
|
|
3107
3201
|
? Record<string, Component>
|
|
3108
3202
|
: {
|
|
3109
3203
|
[K in keyof $Item]?: [$Item[K]] extends [never]
|
|
3110
|
-
?
|
|
3204
|
+
? // Sections and panels that share the data of their schema.
|
|
3205
|
+
NonSectionComponent<$Item> | SectionSchema<$Item> | PanelSchema<$Item>
|
|
3111
3206
|
: NonNullable<$Item[K]> extends (infer E)[]
|
|
3112
3207
|
? E extends Record<string, any>
|
|
3113
3208
|
? NonSectionComponent<E>
|
|
3114
|
-
:
|
|
3209
|
+
: // Lists of primitive values edit them wrapped in objects under
|
|
3210
|
+
// the key given by `wrapPrimitives`, see `SchemaSourceMixin`.
|
|
3211
|
+
NonSectionComponent<Record<string, E>>
|
|
3115
3212
|
: NonNullable<$Item[K]> extends Record<string, any>
|
|
3116
3213
|
?
|
|
3117
3214
|
| NonOptionFieldComponent<$Item>
|
|
@@ -3147,13 +3244,6 @@ export interface Form<$Item = any> extends SchemaRoute<$Item> {
|
|
|
3147
3244
|
* The label of the form.
|
|
3148
3245
|
*/
|
|
3149
3246
|
label?: OrItemAccessor<$Item, {}, string | boolean>
|
|
3150
|
-
/**
|
|
3151
|
-
* Whether the form directly mutates the parent data instead
|
|
3152
|
-
* of working on a copy.
|
|
3153
|
-
*
|
|
3154
|
-
* @defaultValue `false`
|
|
3155
|
-
*/
|
|
3156
|
-
mutate?: boolean
|
|
3157
3247
|
/**
|
|
3158
3248
|
* The property name used as the item's unique identifier.
|
|
3159
3249
|
*
|
package/src/mixins/DataMixin.js
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isObject,
|
|
3
|
-
isFunction,
|
|
4
|
-
isPromise,
|
|
5
|
-
normalizeDataPath,
|
|
6
|
-
getValueAtDataPath
|
|
7
|
-
} from '@ditojs/utils'
|
|
8
|
-
import { markRaw, ref } from 'vue'
|
|
9
|
-
import LoadingMixin from './LoadingMixin.js'
|
|
10
|
-
|
|
11
|
-
// @vue/component
|
|
12
|
-
export default {
|
|
13
|
-
mixins: [LoadingMixin],
|
|
14
|
-
|
|
15
|
-
data() {
|
|
16
|
-
return {
|
|
17
|
-
isLoading: false,
|
|
18
|
-
asyncDataEntries: markRaw({})
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
methods: {
|
|
23
|
-
handleDataSchema(schema, name, loadingOptions) {
|
|
24
|
-
if (!isObject(schema)) {
|
|
25
|
-
schema = { data: schema }
|
|
26
|
-
}
|
|
27
|
-
let { data = undefined, dataPath = null } = schema
|
|
28
|
-
// Create a reactive entry for the async data, if it doesn't exist yet.
|
|
29
|
-
// NOTE: `markRaw()` is used to avoid reactivity on `asyncDataEntries`
|
|
30
|
-
// itself, as reactivity is only desired on `reactiveVersion`, which is
|
|
31
|
-
// used to trigger controlled reevaluation of the computed getter.
|
|
32
|
-
const asyncEntry = (this.asyncDataEntries[name] ??= {
|
|
33
|
-
reactiveVersion: ref(1),
|
|
34
|
-
dependencyFunction: null,
|
|
35
|
-
resolvedData: undefined,
|
|
36
|
-
resolving: false,
|
|
37
|
-
resolved: false
|
|
38
|
-
})
|
|
39
|
-
// If the data callback provided a dependency function when it was called,
|
|
40
|
-
// cal it in every call of `handleDataSchema()` to force Vue to keep track
|
|
41
|
-
// of the async dependencies. Also access `reactiveVersion.value` right
|
|
42
|
-
// away, to ensure that the reactive property is tracked as a dependency:
|
|
43
|
-
asyncEntry.reactiveVersion.value &&
|
|
44
|
-
asyncEntry.dependencyFunction?.(this.context)
|
|
45
|
-
|
|
46
|
-
if (asyncEntry.resolved) {
|
|
47
|
-
// If the data was resolved already, return it and clear the resolved
|
|
48
|
-
// value. This works because Vue caches the result of computed getters
|
|
49
|
-
// and only reevaluates if one of the dependencies changed. This is to
|
|
50
|
-
// ensure that a cached value here doesn't block / override
|
|
51
|
-
// reevaluation when a dependency changes:
|
|
52
|
-
const { resolvedData } = asyncEntry
|
|
53
|
-
asyncEntry.resolvedData = undefined
|
|
54
|
-
asyncEntry.resolved = false
|
|
55
|
-
return resolvedData
|
|
56
|
-
}
|
|
57
|
-
// Avoid calling the data function twice:
|
|
58
|
-
if (asyncEntry.resolving) {
|
|
59
|
-
data = null
|
|
60
|
-
} else if (data) {
|
|
61
|
-
if (isFunction(data)) {
|
|
62
|
-
const result = data(this.context)
|
|
63
|
-
// If the result of the data function is another function, then the
|
|
64
|
-
// first data function is there to track dependencies and the real
|
|
65
|
-
// data loading happens in the function that it returned. Keep track
|
|
66
|
-
// it in `dependencyFunction` so it can be called on each call of
|
|
67
|
-
// `handleDataSchema()` to keep the dependencies intact, and call
|
|
68
|
-
// the function that it returned once to get the actual data:
|
|
69
|
-
if (isFunction(result)) {
|
|
70
|
-
asyncEntry.dependencyFunction = data
|
|
71
|
-
data = result(this.context)
|
|
72
|
-
} else {
|
|
73
|
-
data = result
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
// NOTE: If the data is not a promise, it is resolved already.
|
|
77
|
-
if (isPromise(data)) {
|
|
78
|
-
// If the data is asynchronous, it can't be returned straight away.
|
|
79
|
-
// But we can cheat using computed properties and `resolvedData`,
|
|
80
|
-
// which is going to receive the loaded data asynchronously,
|
|
81
|
-
// triggering a recompute of the computed property that calls
|
|
82
|
-
// `handleDataSchema()`.
|
|
83
|
-
asyncEntry.resolving = true
|
|
84
|
-
this.resolveData(data, loadingOptions)
|
|
85
|
-
.then(data => {
|
|
86
|
-
asyncEntry.resolvedData = data
|
|
87
|
-
asyncEntry.resolving = false
|
|
88
|
-
asyncEntry.resolved = true
|
|
89
|
-
// Trigger reevaluation of the computed getter by increasing the
|
|
90
|
-
// `reactiveVersion` value.
|
|
91
|
-
asyncEntry.reactiveVersion.value++
|
|
92
|
-
})
|
|
93
|
-
.catch(error => {
|
|
94
|
-
console.error(error)
|
|
95
|
-
asyncEntry.resolving = false
|
|
96
|
-
})
|
|
97
|
-
// Clear data until promise is resolved and `resolvedData` is set
|
|
98
|
-
data = null
|
|
99
|
-
}
|
|
100
|
-
} else if (dataPath) {
|
|
101
|
-
data = getValueAtDataPath(
|
|
102
|
-
this.rootData,
|
|
103
|
-
normalizeDataPath(`${this.dataPath}/${dataPath}`)
|
|
104
|
-
)
|
|
105
|
-
}
|
|
106
|
-
return data
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
async resolveData(load, loadingOptions = {}) {
|
|
110
|
-
// Use a timeout to allow already resolved promises to return data without
|
|
111
|
-
// showing a loading indicator.
|
|
112
|
-
let clearLoading = false
|
|
113
|
-
const timer = setTimeout(() => {
|
|
114
|
-
this.setLoading(true, loadingOptions)
|
|
115
|
-
clearLoading = true
|
|
116
|
-
}, 0)
|
|
117
|
-
let data = null
|
|
118
|
-
try {
|
|
119
|
-
data = await (isFunction(load) ? load() : load)
|
|
120
|
-
} catch (error) {
|
|
121
|
-
this.addError(error.message || error)
|
|
122
|
-
}
|
|
123
|
-
if (clearLoading) {
|
|
124
|
-
this.setLoading(false, loadingOptions)
|
|
125
|
-
} else {
|
|
126
|
-
clearTimeout(timer)
|
|
127
|
-
}
|
|
128
|
-
return data
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|