@ditojs/admin 3.1.1 → 3.1.2
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.es.js +1564 -1547
- package/dist/dito-admin.umd.js +5 -5
- package/package.json +5 -5
- package/src/utils/FormModel.js +5 -1
- package/src/utils/schema/data.js +15 -1
- package/src/utils/schema/lookup.js +52 -15
- package/types/index.d.ts +13 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ditojs/admin",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Dito.js Admin is a schema based admin interface for Dito.js Server, featuring auto-generated views and forms and built with Vue.js",
|
|
6
6
|
"repository": "https://github.com/ditojs/dito/tree/main/packages/admin",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"not ie_mob > 0"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@ditojs/ui": "^3.1.
|
|
45
|
-
"@ditojs/utils": "^3.1.
|
|
44
|
+
"@ditojs/ui": "^3.1.2",
|
|
45
|
+
"@ditojs/utils": "^3.1.2"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"@kyvg/vue3-notification": "^3.4.2",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"vue-upload-component": "^3.2.2"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
|
-
"@ditojs/build": "^3.1.
|
|
90
|
+
"@ditojs/build": "^3.1.2",
|
|
91
91
|
"@kyvg/vue3-notification": "^3.4.2",
|
|
92
92
|
"@tiptap/core": "^3.31.4",
|
|
93
93
|
"@tiptap/extension-blockquote": "^3.31.4",
|
|
@@ -131,5 +131,5 @@
|
|
|
131
131
|
"vue-router": "^5.3.1",
|
|
132
132
|
"vue-upload-component": "^3.2.2"
|
|
133
133
|
},
|
|
134
|
-
"gitHead": "
|
|
134
|
+
"gitHead": "a87ccff01f65386d9363366fb19bb993d38e8fbc"
|
|
135
135
|
}
|
package/src/utils/FormModel.js
CHANGED
|
@@ -584,7 +584,11 @@ function takeOverChangedValues(target, before, after) {
|
|
|
584
584
|
return target
|
|
585
585
|
}
|
|
586
586
|
const isSameShape = (
|
|
587
|
-
|
|
587
|
+
(
|
|
588
|
+
isPlainObject(before) &&
|
|
589
|
+
isPlainObject(after) &&
|
|
590
|
+
isPlainObject(target)
|
|
591
|
+
) || (
|
|
588
592
|
isArray(before) &&
|
|
589
593
|
isArray(after) &&
|
|
590
594
|
isArray(target) &&
|
package/src/utils/schema/data.js
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
hasFormSchema,
|
|
24
24
|
hasMultipleFormSchemas,
|
|
25
25
|
getFormSchemas,
|
|
26
|
+
getItemFormSchema,
|
|
26
27
|
getItemFormSchemaFromForms
|
|
27
28
|
} from './lookup.js'
|
|
28
29
|
|
|
@@ -605,7 +606,20 @@ export function processSchemaData(schema, data, {
|
|
|
605
606
|
}
|
|
606
607
|
}
|
|
607
608
|
|
|
608
|
-
|
|
609
|
+
const components = isFunction(schema.components)
|
|
610
|
+
? // Unnested components with `components()` callbacks, e.g. sections:
|
|
611
|
+
getItemFormSchema(
|
|
612
|
+
schema,
|
|
613
|
+
data,
|
|
614
|
+
new DitoContext(options.component, {
|
|
615
|
+
schema,
|
|
616
|
+
data,
|
|
617
|
+
dataPath,
|
|
618
|
+
rootData: options.rootData
|
|
619
|
+
})
|
|
620
|
+
).components
|
|
621
|
+
: schema.components
|
|
622
|
+
processComponents(components, componentPath)
|
|
609
623
|
processTabOrPanelSchemas(schema.tabs, componentPath)
|
|
610
624
|
processTabOrPanelSchemas(schema.panels, componentPath)
|
|
611
625
|
|
|
@@ -6,26 +6,32 @@ import {
|
|
|
6
6
|
isFunction,
|
|
7
7
|
camelize
|
|
8
8
|
} from '@ditojs/utils'
|
|
9
|
-
import { reactive } from 'vue'
|
|
9
|
+
import { reactive, computed } from 'vue'
|
|
10
10
|
import { getTypeOptions } from './types.js'
|
|
11
11
|
import {
|
|
12
12
|
findNestedSchemaComponent,
|
|
13
13
|
isSchema,
|
|
14
14
|
isSingleComponentView
|
|
15
15
|
} from './structure.js'
|
|
16
|
-
// TODO:
|
|
17
|
-
//
|
|
18
|
-
// modules. Move this out of the lookup, see the form model.
|
|
16
|
+
// TODO: Setting up the forms of `components()` callbacks causes the only
|
|
17
|
+
// circular import between these modules.
|
|
19
18
|
import { setupForm } from './setup.js'
|
|
20
19
|
|
|
21
20
|
const emptySchema = {}
|
|
22
21
|
|
|
22
|
+
// The forms with the components that `components()` callbacks create, by
|
|
23
|
+
// callback and by the data that they create them for, see
|
|
24
|
+
// `getFormWithCreatedComponents()`.
|
|
25
|
+
const formsByComponentsCallback = new WeakMap()
|
|
26
|
+
|
|
23
27
|
export function hasFormSchema(schema) {
|
|
24
28
|
// Support both single form and multiple forms notation, as well as inlined
|
|
25
|
-
// components.
|
|
29
|
+
// components, also created by `components()` callbacks.
|
|
26
30
|
return (
|
|
27
|
-
isSchema(schema) &&
|
|
28
|
-
|
|
31
|
+
isSchema(schema) && (
|
|
32
|
+
isObject(schema.form || schema.forms || schema.components) ||
|
|
33
|
+
isFunction(schema.components)
|
|
34
|
+
)
|
|
29
35
|
)
|
|
30
36
|
}
|
|
31
37
|
|
|
@@ -96,20 +102,51 @@ export function getFormSchemas(schema, context, modifyForm) {
|
|
|
96
102
|
Object.entries(forms).map(([type, form]) => {
|
|
97
103
|
// Support `schema.components` callbacks to create components on the fly.
|
|
98
104
|
if (context && isFunction(form.components)) {
|
|
99
|
-
|
|
100
|
-
// the setting of defaults will be picked up by downstream code.
|
|
101
|
-
form = reactive({
|
|
102
|
-
...form,
|
|
103
|
-
components: form.components(context)
|
|
104
|
-
})
|
|
105
|
-
// Process the form again, now that we have the components.
|
|
106
|
-
setupForm(context.api, form).catch(console.error)
|
|
105
|
+
form = getFormWithCreatedComponents(form, context)
|
|
107
106
|
}
|
|
108
107
|
return [type, modifyForm?.(form) ?? form]
|
|
109
108
|
})
|
|
110
109
|
)
|
|
111
110
|
}
|
|
112
111
|
|
|
112
|
+
// Returns the form with the components that its `components()` callback
|
|
113
|
+
// creates for the data of `context`. The forms are cached per data, and the
|
|
114
|
+
// callback only creates new components when the data that it reads changes,
|
|
115
|
+
// so that rendering and the walks of the form model, see `FormModel`, share
|
|
116
|
+
// the same component schemas. `components()` callbacks therefore derive the
|
|
117
|
+
// components from the data of their context, not from its components.
|
|
118
|
+
function getFormWithCreatedComponents(form, context) {
|
|
119
|
+
const { item } = context
|
|
120
|
+
if (!isObject(item)) {
|
|
121
|
+
return createFormWithComponents(form, context)
|
|
122
|
+
}
|
|
123
|
+
let formsByItem = formsByComponentsCallback.get(form.components)
|
|
124
|
+
if (!formsByItem) {
|
|
125
|
+
formsByItem = new WeakMap()
|
|
126
|
+
formsByComponentsCallback.set(form.components, formsByItem)
|
|
127
|
+
}
|
|
128
|
+
let formWithCreatedComponents = formsByItem.get(item)
|
|
129
|
+
if (!formWithCreatedComponents) {
|
|
130
|
+
formWithCreatedComponents = computed(() =>
|
|
131
|
+
createFormWithComponents(form, context)
|
|
132
|
+
)
|
|
133
|
+
formsByItem.set(item, formWithCreatedComponents)
|
|
134
|
+
}
|
|
135
|
+
return formWithCreatedComponents.value
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function createFormWithComponents(form, context) {
|
|
139
|
+
// Make the form schema reactive since `setupForm()` is async, so that the
|
|
140
|
+
// setting of defaults will be picked up by downstream code.
|
|
141
|
+
const formWithComponents = reactive({
|
|
142
|
+
...form,
|
|
143
|
+
components: form.components(context)
|
|
144
|
+
})
|
|
145
|
+
// Process the form again, now that it has its components.
|
|
146
|
+
setupForm(context.api, formWithComponents).catch(console.error)
|
|
147
|
+
return formWithComponents
|
|
148
|
+
}
|
|
149
|
+
|
|
113
150
|
export function getItemFormSchemaFromForms(forms, item) {
|
|
114
151
|
return forms[item?.type] || forms.default || null
|
|
115
152
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -1548,9 +1548,18 @@ export interface RadioSchema<$Item = any>
|
|
|
1548
1548
|
layout?: 'horizontal' | 'vertical'
|
|
1549
1549
|
}
|
|
1550
1550
|
|
|
1551
|
-
type SectionContent<$Data> = {
|
|
1552
|
-
/**
|
|
1553
|
-
|
|
1551
|
+
type SectionContent<$Data, $Item = $Data> = {
|
|
1552
|
+
/**
|
|
1553
|
+
* The section's field components, or a callback that
|
|
1554
|
+
* creates them from the data, e.g. fields that depend on
|
|
1555
|
+
* a selected template. The callback runs again when the
|
|
1556
|
+
* data that it reads changes, and receives the context of
|
|
1557
|
+
* the section, so that `item` is the item that contains
|
|
1558
|
+
* it, also for nested sections.
|
|
1559
|
+
*/
|
|
1560
|
+
components?:
|
|
1561
|
+
| Components<$Data>
|
|
1562
|
+
| ItemAccessor<$Item, {}, Components<$Data>>
|
|
1554
1563
|
/**
|
|
1555
1564
|
* A form schema for the section's content. Use this
|
|
1556
1565
|
* instead of `components` to get form-level options
|
|
@@ -1690,7 +1699,7 @@ export type SectionSchema<$Item = any, $Nested = $Item> = BaseSchema<$Item> &
|
|
|
1690
1699
|
* @defaultValue `false`
|
|
1691
1700
|
*/
|
|
1692
1701
|
nested: true
|
|
1693
|
-
} & SectionContent<$Nested>)
|
|
1702
|
+
} & SectionContent<$Nested, $Item>)
|
|
1694
1703
|
)
|
|
1695
1704
|
|
|
1696
1705
|
export interface CheckboxSchema<$Item = any> extends BaseSchema<$Item> {
|