@ditojs/admin 1.30.0 → 2.0.1
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 +5291 -6856
- package/dist/dito-admin.umd.js +5 -5
- package/dist/style.css +1 -1
- package/package.json +42 -27
- package/src/DitoAdmin.js +44 -58
- package/src/DitoComponent.js +18 -50
- package/src/DitoContext.js +7 -3
- package/src/TypeComponent.js +15 -13
- package/src/appState.js +4 -2
- package/src/components/DitoAccount.vue +14 -14
- package/src/components/DitoButtons.vue +18 -10
- package/src/components/DitoClipboard.vue +16 -16
- package/src/components/DitoContainer.vue +32 -32
- package/src/components/DitoCreateButton.vue +22 -23
- package/src/components/DitoDialog.vue +73 -18
- package/src/components/DitoEditButtons.vue +31 -31
- package/src/components/DitoElement.vue +6 -6
- package/src/components/DitoErrors.vue +6 -6
- package/src/components/DitoForm.vue +42 -43
- package/src/components/DitoFormNested.vue +7 -3
- package/src/components/DitoHeader.vue +19 -19
- package/src/components/DitoLabel.vue +25 -25
- package/src/components/DitoMenu.vue +9 -9
- package/src/components/DitoPagination.vue +5 -5
- package/src/components/DitoPane.vue +32 -32
- package/src/components/DitoPanel.vue +18 -18
- package/src/components/DitoPanels.vue +5 -3
- package/src/components/DitoRoot.vue +107 -30
- package/src/components/DitoSchema.vue +76 -74
- package/src/components/DitoSchemaInlined.vue +29 -29
- package/src/components/DitoScopes.vue +14 -13
- package/src/components/DitoSpinner.vue +101 -0
- package/src/components/DitoTableCell.vue +19 -25
- package/src/components/DitoTableHead.vue +10 -7
- package/src/components/DitoTabs.vue +7 -6
- package/src/components/DitoTreeItem.vue +89 -85
- package/src/components/DitoVNode.vue +9 -7
- package/src/components/DitoView.vue +25 -21
- package/src/mixins/DataMixin.js +2 -2
- package/src/mixins/DitoMixin.js +43 -46
- package/src/mixins/DomMixin.js +1 -1
- package/src/mixins/EmitterMixin.js +11 -11
- package/src/mixins/RouteMixin.js +20 -10
- package/src/mixins/SchemaParentMixin.js +2 -2
- package/src/mixins/SourceMixin.js +7 -9
- package/src/mixins/TypeMixin.js +29 -34
- package/src/mixins/ValidationMixin.js +4 -19
- package/src/types/TypeButton.vue +11 -15
- package/src/types/TypeCheckbox.vue +7 -8
- package/src/types/TypeCheckboxes.vue +14 -15
- package/src/types/TypeCode.vue +5 -5
- package/src/types/TypeColor.vue +9 -12
- package/src/types/TypeComponent.vue +12 -7
- package/src/types/TypeComputed.vue +13 -12
- package/src/types/TypeDate.vue +10 -11
- package/src/types/TypeLabel.vue +1 -1
- package/src/types/TypeList.vue +115 -92
- package/src/types/TypeMarkup.vue +166 -125
- package/src/types/TypeMultiselect.vue +37 -47
- package/src/types/TypeNumber.vue +10 -11
- package/src/types/TypeObject.vue +62 -46
- package/src/types/TypeProgress.vue +7 -8
- package/src/types/TypeRadio.vue +15 -14
- package/src/types/TypeSection.vue +10 -10
- package/src/types/TypeSelect.vue +32 -33
- package/src/types/TypeSlider.vue +20 -22
- package/src/types/TypeSwitch.vue +8 -9
- package/src/types/TypeText.vue +7 -8
- package/src/types/TypeTextarea.vue +8 -9
- package/src/types/TypeTreeList.vue +40 -34
- package/src/types/TypeUpload.vue +61 -61
- package/src/utils/accessor.js +1 -1
- package/src/utils/data.js +0 -4
- package/src/utils/options.js +48 -0
- package/src/utils/path.js +5 -0
- package/src/utils/schema.js +73 -56
- package/src/utils/vue.js +11 -0
- package/types/index.d.ts +1 -1
package/src/utils/data.js
CHANGED
|
@@ -83,10 +83,6 @@ export function isTemporaryId(id) {
|
|
|
83
83
|
return /^@/.test(id)
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
export function hasTemporaryId(data, idKey = 'id') {
|
|
87
|
-
return isTemporaryId(data?.[idKey])
|
|
88
|
-
}
|
|
89
|
-
|
|
90
86
|
export function isReference(data, idKey = 'id') {
|
|
91
87
|
// Returns true if value is an object that holds nothing more than an id.
|
|
92
88
|
return data?.[idKey] != null && Object.keys(data).length === 1
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// A mini-replication of vue's internal `resolveMergedOptions()` but only
|
|
2
|
+
// handling our own added options properties and merging them early instead
|
|
3
|
+
// of lazily.
|
|
4
|
+
|
|
5
|
+
export function resolveMergedOptions(options) {
|
|
6
|
+
const { mixins } = options
|
|
7
|
+
return mixins || options.extends
|
|
8
|
+
? mergeOptions(
|
|
9
|
+
{ ...options },
|
|
10
|
+
options
|
|
11
|
+
)
|
|
12
|
+
: options
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function mergeOptions(to, from) {
|
|
16
|
+
if (from.extends) {
|
|
17
|
+
mergeOptions(to, from.extends)
|
|
18
|
+
}
|
|
19
|
+
if (from.mixins) {
|
|
20
|
+
for (const mixin of from.mixins) {
|
|
21
|
+
mergeOptions(to, mixin)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
for (const key of ditoOptionKeys) {
|
|
25
|
+
if (key in from) {
|
|
26
|
+
to[key] = from[key]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return to
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const ditoOptionKeys = [
|
|
33
|
+
'defaultValue',
|
|
34
|
+
'defaultNested',
|
|
35
|
+
'defaultVisible',
|
|
36
|
+
'generateLabel',
|
|
37
|
+
'excludeValue',
|
|
38
|
+
'ignoreMissingValue',
|
|
39
|
+
'omitPadding',
|
|
40
|
+
'processValue',
|
|
41
|
+
'processSchema',
|
|
42
|
+
'getPanelSchema',
|
|
43
|
+
'getFormSchemasForProcessing',
|
|
44
|
+
// Vue 3 / Vue-router 4 forgets these.
|
|
45
|
+
// TODO: Create bug-report?
|
|
46
|
+
'beforeRouteUpdate',
|
|
47
|
+
'beforeRouteLeave'
|
|
48
|
+
]
|
package/src/utils/schema.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import Vue from 'vue'
|
|
2
1
|
import DitoContext from '../DitoContext.js'
|
|
2
|
+
import DitoMixin from '../mixins/DitoMixin.js'
|
|
3
|
+
import TypeMixin from '../mixins/TypeMixin.js'
|
|
3
4
|
import { getUid } from './uid.js'
|
|
4
5
|
import { SchemaGraph } from './SchemaGraph.js'
|
|
5
6
|
import { appendDataPath, isTemporaryId } from './data.js'
|
|
@@ -7,6 +8,7 @@ import {
|
|
|
7
8
|
isObject, isString, isArray, isFunction, isPromise, clone, camelize, isModule,
|
|
8
9
|
mapConcurrently
|
|
9
10
|
} from '@ditojs/utils'
|
|
11
|
+
import { markRaw } from 'vue'
|
|
10
12
|
|
|
11
13
|
const typeComponents = {}
|
|
12
14
|
const unknownTypeReported = {}
|
|
@@ -25,21 +27,6 @@ export function getTypeComponent(type, allowNull = false) {
|
|
|
25
27
|
return component
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
export function forEachSchema(schema, callback) {
|
|
29
|
-
const schemas = [
|
|
30
|
-
...Object.values(schema?.tabs || {}),
|
|
31
|
-
schema
|
|
32
|
-
]
|
|
33
|
-
for (const schema of schemas) {
|
|
34
|
-
if (schema) {
|
|
35
|
-
const res = callback(schema)
|
|
36
|
-
if (res !== undefined) {
|
|
37
|
-
return res
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
30
|
export function forEachSchemaComponent(schema, callback) {
|
|
44
31
|
if (isSingleComponentView(schema)) {
|
|
45
32
|
const res = callback(schema.component, schema.name)
|
|
@@ -47,14 +34,17 @@ export function forEachSchemaComponent(schema, callback) {
|
|
|
47
34
|
return res
|
|
48
35
|
}
|
|
49
36
|
} else {
|
|
50
|
-
|
|
37
|
+
const schemas = schema
|
|
38
|
+
? [...Object.values(schema.tabs || {}), schema]
|
|
39
|
+
: []
|
|
40
|
+
for (const schema of schemas) {
|
|
51
41
|
for (const [name, component] of Object.entries(schema.components || {})) {
|
|
52
42
|
const res = callback(component, name)
|
|
53
43
|
if (res !== undefined) {
|
|
54
44
|
return res
|
|
55
45
|
}
|
|
56
46
|
}
|
|
57
|
-
}
|
|
47
|
+
}
|
|
58
48
|
}
|
|
59
49
|
}
|
|
60
50
|
|
|
@@ -161,21 +151,45 @@ export async function resolvePanels(schema) {
|
|
|
161
151
|
}
|
|
162
152
|
}
|
|
163
153
|
|
|
164
|
-
export async function
|
|
154
|
+
export async function resolveSchemaComponent(schema) {
|
|
155
|
+
// Resolves async schema components and adds DitoMixin and TypeMixin to them.
|
|
156
|
+
let { component } = schema
|
|
157
|
+
if (component) {
|
|
158
|
+
component = await resolveSchema(component, true)
|
|
159
|
+
if (component) {
|
|
160
|
+
// Prevent warning: "Vue received a Component which was made a reactive
|
|
161
|
+
// object. This can lead to unnecessary performance overhead, and should
|
|
162
|
+
// be avoided by marking the component with `markRaw`":
|
|
163
|
+
schema.component = markRaw({
|
|
164
|
+
...component,
|
|
165
|
+
mixins: [DitoMixin, TypeMixin, ...(component.mixins || [])]
|
|
166
|
+
})
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export async function resolveSchemaComponents(schemas) {
|
|
172
|
+
// `schemas` are of the same possible forms as passed to `getNamedSchemas()`
|
|
173
|
+
await mapConcurrently(Object.values(schemas || {}), resolveSchemaComponent)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export async function processView(component, api, schema, name) {
|
|
165
177
|
const children = []
|
|
166
178
|
processRouteSchema(api, schema, name)
|
|
167
179
|
await resolvePanels(schema)
|
|
168
180
|
if (isView(schema)) {
|
|
181
|
+
let level = 0
|
|
169
182
|
if (isSingleComponentView(schema)) {
|
|
170
|
-
await processComponent(api, schema.component, name, children,
|
|
183
|
+
await processComponent(api, schema.component, name, children, level)
|
|
171
184
|
} else {
|
|
172
185
|
// A multi-component view, start at level 1
|
|
173
|
-
await processSchemaComponents(api, schema, children,
|
|
186
|
+
await processSchemaComponents(api, schema, children, ++level)
|
|
174
187
|
}
|
|
188
|
+
schema.level = level
|
|
175
189
|
} else {
|
|
176
190
|
throw new Error(`Invalid view schema: '${getSchemaIdentifier(schema)}'`)
|
|
177
191
|
}
|
|
178
|
-
|
|
192
|
+
return {
|
|
179
193
|
path: `/${schema.path}`,
|
|
180
194
|
children,
|
|
181
195
|
component,
|
|
@@ -183,13 +197,13 @@ export async function processView(component, api, schema, name, routes) {
|
|
|
183
197
|
api,
|
|
184
198
|
schema
|
|
185
199
|
}
|
|
186
|
-
}
|
|
200
|
+
}
|
|
187
201
|
}
|
|
188
202
|
|
|
189
|
-
export function processComponent(api, schema, name, routes, level) {
|
|
203
|
+
export async function processComponent(api, schema, name, routes, level) {
|
|
190
204
|
schema.level = level
|
|
191
205
|
// Delegate schema processing to the actual type components.
|
|
192
|
-
|
|
206
|
+
await getTypeOptions(schema)?.processSchema?.(
|
|
193
207
|
api, schema, name, routes, level
|
|
194
208
|
)
|
|
195
209
|
}
|
|
@@ -230,15 +244,15 @@ export async function processForms(api, schema, level) {
|
|
|
230
244
|
return children
|
|
231
245
|
}
|
|
232
246
|
|
|
233
|
-
export async function resolveForm(
|
|
234
|
-
|
|
235
|
-
if (!isForm(
|
|
236
|
-
throw new Error(`Invalid form schema: '${getSchemaIdentifier(
|
|
247
|
+
export async function resolveForm(schema) {
|
|
248
|
+
schema = await resolveSchema(schema, true)
|
|
249
|
+
if (!isForm(schema)) {
|
|
250
|
+
throw new Error(`Invalid form schema: '${getSchemaIdentifier(schema)}'`)
|
|
237
251
|
}
|
|
238
|
-
if (
|
|
239
|
-
await resolvePanels(
|
|
252
|
+
if (schema) {
|
|
253
|
+
await resolvePanels(schema)
|
|
240
254
|
}
|
|
241
|
-
return
|
|
255
|
+
return schema
|
|
242
256
|
}
|
|
243
257
|
|
|
244
258
|
export function hasFormSchema(schema) {
|
|
@@ -264,20 +278,23 @@ export function isSingleComponentView(schema) {
|
|
|
264
278
|
)
|
|
265
279
|
}
|
|
266
280
|
|
|
267
|
-
export function
|
|
281
|
+
export function getViewFormSchema(schema, context) {
|
|
268
282
|
const { view } = schema
|
|
269
283
|
const viewSchema = view && context.views[view]
|
|
270
284
|
return viewSchema
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
285
|
+
// NOTE: Views can have tabs, in which case the view component is nested
|
|
286
|
+
// in one of the tabs, go find it.
|
|
287
|
+
? forEachSchemaComponent(viewSchema, schema => {
|
|
288
|
+
if (hasFormSchema(schema)) {
|
|
289
|
+
return schema
|
|
290
|
+
}
|
|
291
|
+
}) || null
|
|
292
|
+
: null
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export function getViewSchema(schema, context) {
|
|
296
|
+
return getViewFormSchema(schema, context)
|
|
297
|
+
? context.views[schema.view]
|
|
281
298
|
: null
|
|
282
299
|
}
|
|
283
300
|
|
|
@@ -291,9 +308,9 @@ export function getViewEditPath(schema, context) {
|
|
|
291
308
|
}
|
|
292
309
|
|
|
293
310
|
export function getFormSchemas(schema, context, modifyForm) {
|
|
294
|
-
const
|
|
295
|
-
if (
|
|
296
|
-
schema =
|
|
311
|
+
const viewSchema = getViewFormSchema(schema, context)
|
|
312
|
+
if (viewSchema) {
|
|
313
|
+
schema = viewSchema
|
|
297
314
|
} else if (schema.view) {
|
|
298
315
|
throw new Error(`Unknown view: '${schema.view}'`)
|
|
299
316
|
}
|
|
@@ -419,17 +436,17 @@ export function computeValue(schema, data, name, dataPath, {
|
|
|
419
436
|
rootData
|
|
420
437
|
}))
|
|
421
438
|
if (value !== undefined) {
|
|
422
|
-
//
|
|
439
|
+
// Access `data[name]` directly instead of `this.value = …` to update the
|
|
423
440
|
// value without calling parse():
|
|
424
|
-
|
|
441
|
+
data[name] = value
|
|
425
442
|
}
|
|
426
443
|
}
|
|
427
444
|
// If the value is still missing after compute, set the default for it:
|
|
428
445
|
if (!(name in data) && !ignoreMissingValue(schema)) {
|
|
429
|
-
|
|
446
|
+
data[name] = getDefaultValue(schema)
|
|
430
447
|
}
|
|
431
448
|
// Now access the value. This is important for reactivity and needs to
|
|
432
|
-
// happen after all prior manipulation
|
|
449
|
+
// happen after all prior manipulation of `data[name]`, see above:
|
|
433
450
|
return data[name]
|
|
434
451
|
}
|
|
435
452
|
|
|
@@ -662,7 +679,7 @@ export function processSchemaData(
|
|
|
662
679
|
return processedData || data
|
|
663
680
|
}
|
|
664
681
|
|
|
665
|
-
export function getNamedSchemas(
|
|
682
|
+
export function getNamedSchemas(schemas, defaults) {
|
|
666
683
|
const toObject = (array, toSchema) => {
|
|
667
684
|
return array.length > 0
|
|
668
685
|
? array.reduce((object, value) => {
|
|
@@ -677,15 +694,15 @@ export function getNamedSchemas(descriptions, defaults) {
|
|
|
677
694
|
: null
|
|
678
695
|
}
|
|
679
696
|
|
|
680
|
-
return isArray(
|
|
681
|
-
? toObject(
|
|
697
|
+
return isArray(schemas)
|
|
698
|
+
? toObject(schemas, value => (
|
|
682
699
|
isObject(value) ? value : {
|
|
683
700
|
name: camelize(value, false)
|
|
684
701
|
}
|
|
685
702
|
))
|
|
686
|
-
: isObject(
|
|
703
|
+
: isObject(schemas)
|
|
687
704
|
? toObject(
|
|
688
|
-
Object.entries(
|
|
705
|
+
Object.entries(schemas),
|
|
689
706
|
([name, value]) =>
|
|
690
707
|
isObject(value) ? {
|
|
691
708
|
name,
|
|
@@ -712,7 +729,7 @@ function getType(schemaOrType) {
|
|
|
712
729
|
}
|
|
713
730
|
|
|
714
731
|
export function getTypeOptions(schemaOrType) {
|
|
715
|
-
return getTypeComponent(getType(schemaOrType), true)
|
|
732
|
+
return getTypeComponent(getType(schemaOrType), true) ?? null
|
|
716
733
|
}
|
|
717
734
|
|
|
718
735
|
export function getSourceType(schemaOrType) {
|
package/src/utils/vue.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useSlots, Comment } from 'vue'
|
|
2
|
+
import { isString, asArray } from '@ditojs/utils'
|
|
3
|
+
|
|
4
|
+
export function hasVNodeContent(vnode) {
|
|
5
|
+
return vnode && asArray(vnode).some(vnode => vnode.type !== Comment)
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function hasSlotContent(slot, props = {}) {
|
|
9
|
+
slot = isString(slot) ? useSlots()[slot] : slot
|
|
10
|
+
return hasVNodeContent(slot?.(props))
|
|
11
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -1093,7 +1093,7 @@ export type Component<$Item = any> =
|
|
|
1093
1093
|
| SectionSchema<$Item>
|
|
1094
1094
|
| HiddenSchema<$Item>
|
|
1095
1095
|
|
|
1096
|
-
export type Components<$Item = any> =
|
|
1096
|
+
export type Components<$Item = any> = Component<$Item>[] | {
|
|
1097
1097
|
[$name: string]: Component<$Item>
|
|
1098
1098
|
}
|
|
1099
1099
|
|