@ditojs/admin 2.26.2 → 2.27.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 +1779 -1690
- package/dist/dito-admin.umd.js +5 -5
- package/dist/style.css +1 -1
- package/package.json +5 -5
- package/src/DitoAdmin.js +1 -3
- package/src/DitoContext.js +4 -0
- package/src/components/DitoContainer.vue +6 -0
- package/src/components/DitoForm.vue +17 -12
- package/src/components/DitoSchema.vue +25 -15
- package/src/components/DitoView.vue +1 -1
- package/src/mixins/DataMixin.js +10 -3
- package/src/mixins/DitoMixin.js +22 -10
- package/src/mixins/OptionsMixin.js +1 -1
- package/src/mixins/ResourceMixin.js +19 -9
- package/src/mixins/RouteMixin.js +1 -1
- package/src/mixins/SourceMixin.js +51 -16
- package/src/mixins/TextMixin.js +3 -2
- package/src/mixins/TypeMixin.js +26 -10
- package/src/types/DitoTypeComponent.vue +1 -1
- package/src/types/DitoTypeDate.vue +1 -1
- package/src/types/DitoTypeSection.vue +1 -1
- package/src/types/DitoTypeText.vue +1 -1
- package/src/types/DitoTypeUpload.vue +1 -1
- package/src/utils/resource.js +4 -1
- package/src/utils/schema.js +78 -66
|
@@ -23,7 +23,7 @@ import { getItemFormSchema, processSchemaComponents } from '../utils/schema.js'
|
|
|
23
23
|
// @vue/component
|
|
24
24
|
export default DitoTypeComponent.register('section', {
|
|
25
25
|
defaultValue: () => undefined, // Callback to override `defaultValue: null`
|
|
26
|
-
ignoreMissingValue: schema => !schema.nested && !('default' in schema),
|
|
26
|
+
ignoreMissingValue: ({ schema }) => !schema.nested && !('default' in schema),
|
|
27
27
|
defaultNested: false,
|
|
28
28
|
generateLabel: false,
|
|
29
29
|
|
|
@@ -38,7 +38,7 @@ export default DitoTypeComponent.register(
|
|
|
38
38
|
components: { InputField },
|
|
39
39
|
nativeField: true,
|
|
40
40
|
textField: true,
|
|
41
|
-
ignoreMissingValue: schema => schema.type === 'password',
|
|
41
|
+
ignoreMissingValue: ({ schema }) => schema.type === 'password',
|
|
42
42
|
|
|
43
43
|
computed: {
|
|
44
44
|
inputType() {
|
|
@@ -452,7 +452,7 @@ export default DitoTypeComponent.register('upload', {
|
|
|
452
452
|
}
|
|
453
453
|
},
|
|
454
454
|
|
|
455
|
-
processValue(schema, value) {
|
|
455
|
+
processValue({ schema, value }) {
|
|
456
456
|
// Filter out all newly added files that weren't actually uploaded.
|
|
457
457
|
const files = asFiles(value)
|
|
458
458
|
.map(({ upload, ...file }) => (!upload || upload.success ? file : null))
|
package/src/utils/resource.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isObject, isString, pickBy } from '@ditojs/utils'
|
|
1
|
+
import { isFunction, isObject, isString, pickBy } from '@ditojs/utils'
|
|
2
2
|
|
|
3
3
|
export function hasResource(schema) {
|
|
4
4
|
return !!getResource(schema.resource)
|
|
@@ -6,6 +6,9 @@ export function hasResource(schema) {
|
|
|
6
6
|
|
|
7
7
|
export function getResource(resource, defaults = {}) {
|
|
8
8
|
const { parent, ...defs } = defaults
|
|
9
|
+
if (isFunction(resource)) {
|
|
10
|
+
resource = resource(defaults)
|
|
11
|
+
}
|
|
9
12
|
resource = isObject(resource)
|
|
10
13
|
? { ...defs, ...resource }
|
|
11
14
|
: isString(resource)
|
package/src/utils/schema.js
CHANGED
|
@@ -242,33 +242,36 @@ export async function resolveSchemaComponents(schemas) {
|
|
|
242
242
|
await mapConcurrently(Object.values(schemas || {}), resolveSchemaComponent)
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
-
const
|
|
245
|
+
const processedSchemaDepths = new WeakMap()
|
|
246
246
|
export async function processSchemaComponents(
|
|
247
247
|
api,
|
|
248
248
|
schema,
|
|
249
249
|
routes = null,
|
|
250
|
-
level = 0
|
|
250
|
+
level = 0,
|
|
251
|
+
maxDepth = 1
|
|
251
252
|
) {
|
|
252
|
-
if (schema
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
253
|
+
if (schema) {
|
|
254
|
+
const depth = processedSchemaDepths.get(schema) ?? 0
|
|
255
|
+
if (depth < maxDepth) {
|
|
256
|
+
processedSchemaDepths.set(schema, depth + 1)
|
|
257
|
+
const promises = []
|
|
258
|
+
const process = (component, name, relativeLevel) => {
|
|
259
|
+
promises.push(
|
|
260
|
+
processSchemaComponent(
|
|
261
|
+
api,
|
|
262
|
+
component,
|
|
263
|
+
name,
|
|
264
|
+
routes,
|
|
265
|
+
level + relativeLevel
|
|
266
|
+
)
|
|
264
267
|
)
|
|
265
|
-
|
|
266
|
-
}
|
|
268
|
+
}
|
|
267
269
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
+
iterateNestedSchemaComponents(schema, process)
|
|
271
|
+
iterateSchemaComponents(getPanelSchemas(schema), process)
|
|
270
272
|
|
|
271
|
-
|
|
273
|
+
await Promise.all(promises)
|
|
274
|
+
}
|
|
272
275
|
}
|
|
273
276
|
}
|
|
274
277
|
|
|
@@ -368,7 +371,7 @@ export function processRouteSchema(api, schema, name, fullPath = null) {
|
|
|
368
371
|
|
|
369
372
|
export async function processForms(api, schema, level) {
|
|
370
373
|
// First resolve the forms and store the results back on the schema.
|
|
371
|
-
let { form, forms, components } = schema
|
|
374
|
+
let { form, forms, components, maxDepth = 1 } = schema
|
|
372
375
|
if (forms) {
|
|
373
376
|
forms = schema.forms = await resolveSchemas(forms, form =>
|
|
374
377
|
processForm(api, form)
|
|
@@ -387,7 +390,7 @@ export async function processForms(api, schema, level) {
|
|
|
387
390
|
forms ||= { default: form } // Only used for process loop below.
|
|
388
391
|
const children = []
|
|
389
392
|
for (const form of Object.values(forms)) {
|
|
390
|
-
await processSchemaComponents(api, form, children, level)
|
|
393
|
+
await processSchemaComponents(api, form, children, level, maxDepth)
|
|
391
394
|
}
|
|
392
395
|
return children
|
|
393
396
|
}
|
|
@@ -624,37 +627,53 @@ export function shouldRenderSchema(schema, context) {
|
|
|
624
627
|
)
|
|
625
628
|
}
|
|
626
629
|
|
|
627
|
-
|
|
630
|
+
function getContext(context) {
|
|
631
|
+
return isFunction(context) ? context() : context
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
export function getDefaultValue(schema, context) {
|
|
628
635
|
// Support default values both on schema and on component level.
|
|
629
636
|
// NOTE: At the time of creation, components may not be instantiated, (e.g. if
|
|
630
637
|
// entries are created through nested forms, the parent form isn't mounted) so
|
|
631
638
|
// we can't use `dataPath` to get to components, and the `defaultValue` from
|
|
632
639
|
// there. That's why `defaultValue` is defined statically in the components:
|
|
633
|
-
const defaultValue =
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
? defaultValue
|
|
640
|
+
const defaultValue =
|
|
641
|
+
schema.default !== undefined
|
|
642
|
+
? schema.default
|
|
637
643
|
: getTypeOptions(schema)?.defaultValue
|
|
638
|
-
return isFunction(
|
|
639
|
-
?
|
|
640
|
-
|
|
641
|
-
value(schema)
|
|
642
|
-
: clone(value)
|
|
644
|
+
return isFunction(defaultValue)
|
|
645
|
+
? defaultValue(getContext(context))
|
|
646
|
+
: clone(defaultValue)
|
|
643
647
|
}
|
|
644
648
|
|
|
645
|
-
export function
|
|
646
|
-
const
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
649
|
+
export function shouldExcludeValue(schema, context) {
|
|
650
|
+
const excludeValue =
|
|
651
|
+
schema.exclude !== undefined
|
|
652
|
+
? schema.exclude
|
|
653
|
+
: getTypeOptions(schema)?.excludeValue
|
|
654
|
+
return isFunction(excludeValue)
|
|
655
|
+
? excludeValue(getContext(context))
|
|
656
|
+
: !!excludeValue
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
export function shouldIgnoreMissingValue(schema, context) {
|
|
660
|
+
return !!getTypeOptions(schema)?.ignoreMissingValue?.(getContext(context))
|
|
650
661
|
}
|
|
651
662
|
|
|
652
663
|
export function setDefaultValues(schema, data = {}, component) {
|
|
653
664
|
const options = { component, rootData: data }
|
|
654
665
|
|
|
655
|
-
const processBefore = (schema, data, name) => {
|
|
656
|
-
|
|
657
|
-
|
|
666
|
+
const processBefore = (schema, data, name, dataPath) => {
|
|
667
|
+
const context = () =>
|
|
668
|
+
new DitoContext(component, {
|
|
669
|
+
schema,
|
|
670
|
+
name,
|
|
671
|
+
data,
|
|
672
|
+
dataPath,
|
|
673
|
+
rootData: options.rootData
|
|
674
|
+
})
|
|
675
|
+
if (!(name in data) && !shouldIgnoreMissingValue(schema, context)) {
|
|
676
|
+
data[name] = getDefaultValue(schema, context)
|
|
658
677
|
}
|
|
659
678
|
}
|
|
660
679
|
|
|
@@ -675,20 +694,20 @@ export function computeValue(schema, data, name, dataPath, {
|
|
|
675
694
|
component = null,
|
|
676
695
|
rootData = component?.rootData
|
|
677
696
|
} = {}) {
|
|
697
|
+
const context = () =>
|
|
698
|
+
new DitoContext(component, {
|
|
699
|
+
schema,
|
|
700
|
+
// Override value to prevent endless recursion through calling the
|
|
701
|
+
// getter for `this.value` in `DitoContext`:
|
|
702
|
+
value: data[name],
|
|
703
|
+
name,
|
|
704
|
+
data,
|
|
705
|
+
dataPath,
|
|
706
|
+
rootData
|
|
707
|
+
})
|
|
678
708
|
const { compute } = schema
|
|
679
709
|
if (compute) {
|
|
680
|
-
const value = compute(
|
|
681
|
-
new DitoContext(component, {
|
|
682
|
-
schema,
|
|
683
|
-
// Override value to prevent endless recursion through calling the
|
|
684
|
-
// getter for `this.value` in `DitoContext`:
|
|
685
|
-
value: data[name],
|
|
686
|
-
name,
|
|
687
|
-
data,
|
|
688
|
-
dataPath,
|
|
689
|
-
rootData
|
|
690
|
-
})
|
|
691
|
-
)
|
|
710
|
+
const value = compute(getContext(context))
|
|
692
711
|
if (value !== undefined) {
|
|
693
712
|
// Access `data[name]` directly to update the value without calling
|
|
694
713
|
// parse():
|
|
@@ -698,10 +717,10 @@ export function computeValue(schema, data, name, dataPath, {
|
|
|
698
717
|
}
|
|
699
718
|
}
|
|
700
719
|
// If the value is still missing after compute, set the default for it:
|
|
701
|
-
if (!(name in data) && !
|
|
720
|
+
if (!(name in data) && !shouldIgnoreMissingValue(schema, context)) {
|
|
702
721
|
// TODO: Fix side-effects
|
|
703
722
|
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
|
|
704
|
-
data[name] = getDefaultValue(schema)
|
|
723
|
+
data[name] = getDefaultValue(schema, context)
|
|
705
724
|
}
|
|
706
725
|
// Now access the value. This is important for reactivity and needs to
|
|
707
726
|
// happen after all prior manipulation of `data[name]`, see above:
|
|
@@ -772,13 +791,11 @@ export function processData(schema, sourceSchema, data, dataPath, {
|
|
|
772
791
|
}
|
|
773
792
|
|
|
774
793
|
const processAfter = (schema, data, name, dataPath, processedData) => {
|
|
775
|
-
const { wrapPrimitives,
|
|
794
|
+
const { wrapPrimitives, process } = schema
|
|
776
795
|
let value = processedData[name]
|
|
777
796
|
|
|
778
|
-
const typeOptions = getTypeOptions(schema)
|
|
779
|
-
|
|
780
797
|
// NOTE: We don't cache this context, since `value` is changing.
|
|
781
|
-
const
|
|
798
|
+
const context = () =>
|
|
782
799
|
new DitoContext(component, {
|
|
783
800
|
schema,
|
|
784
801
|
value,
|
|
@@ -799,23 +816,18 @@ export function processData(schema, sourceSchema, data, dataPath, {
|
|
|
799
816
|
|
|
800
817
|
// Each component type can provide its own static `processValue()` method
|
|
801
818
|
// to convert the data for storage.
|
|
802
|
-
const processValue =
|
|
819
|
+
const processValue = getTypeOptions(schema)?.processValue
|
|
803
820
|
if (processValue) {
|
|
804
|
-
value = processValue(
|
|
821
|
+
value = processValue(getContext(context), graph)
|
|
805
822
|
}
|
|
806
823
|
|
|
807
824
|
// Handle the user's `process()` callback next, if one is provided, so that
|
|
808
825
|
// it can modify data in `processedData` even if it provides `exclude: true`
|
|
809
826
|
if (process) {
|
|
810
|
-
value = process(getContext())
|
|
827
|
+
value = process(getContext(context))
|
|
811
828
|
}
|
|
812
829
|
|
|
813
|
-
if (
|
|
814
|
-
typeOptions?.excludeValue ||
|
|
815
|
-
// Support functions next to booleans for `schema.exclude`:
|
|
816
|
-
exclude === true ||
|
|
817
|
-
isFunction(exclude) && exclude(getContext())
|
|
818
|
-
) {
|
|
830
|
+
if (shouldExcludeValue(schema, context)) {
|
|
819
831
|
delete processedData[name]
|
|
820
832
|
} else {
|
|
821
833
|
processedData[name] = value
|