@ditojs/admin 2.26.1 → 2.27.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.
@@ -33,9 +33,9 @@ import { raw } from '@ditojs/ui'
33
33
  export default {
34
34
  mixins: [ItemMixin, ResourceMixin, SchemaParentMixin],
35
35
 
36
- defaultValue(schema) {
37
- return isListSource(schema) ? [] : null
38
- },
36
+ defaultValue: context => (isListSource(context.schema) ? [] : null),
37
+ // Exclude all sources that have their own resource handling the data.
38
+ excludeValue: context => !!context.schema.resource,
39
39
 
40
40
  provide() {
41
41
  return {
@@ -321,15 +321,25 @@ export default {
321
321
  // https://github.com/vuejs/vue-router/issues/3393#issuecomment-1158470149
322
322
  flush: 'post',
323
323
  handler(to, from) {
324
- if (
325
- this.providesData &&
326
- from.path === to.path &&
327
- from.hash === to.hash
328
- ) {
329
- // Paths and hashes remain the same, so only queries have changed.
330
- // Update filter and reload data without clearing.
331
- this.query = to.query
332
- this.loadData(false)
324
+ if (this.providesData) {
325
+ if (
326
+ from.path === to.path &&
327
+ from.hash === to.hash
328
+ ) {
329
+ // Paths and hashes remain the same, so only queries have changed.
330
+ // Update filter and reload data without clearing.
331
+ this.query = to.query
332
+ this.loadData(false)
333
+ } else if (
334
+ this.meta.reload &&
335
+ from.path !== to.path &&
336
+ from.path.startsWith(to.path)
337
+ ) {
338
+ // Reload the source when navigating back to a parent-route after
339
+ // changing data in a child-route.
340
+ this.meta.reload = false
341
+ this.loadData(false)
342
+ }
333
343
  }
334
344
  }
335
345
  },
@@ -464,9 +474,13 @@ export default {
464
474
  notify()
465
475
  } else {
466
476
  const itemId = this.getItemId(this.schema, item, index)
467
- const resource = getMemberResource(itemId, this.resource)
477
+ const method = 'delete'
478
+ const resource = getMemberResource(
479
+ itemId,
480
+ this.getResource({ method })
481
+ )
468
482
  if (resource) {
469
- this.handleRequest({ method: 'delete', resource }, err => {
483
+ this.handleRequest({ method, resource }, err => {
470
484
  if (!err) {
471
485
  this.removeItem(item, index)
472
486
  notify()
@@ -617,7 +631,7 @@ export default {
617
631
  isListSource(schema) ? param : null
618
632
  ),
619
633
  component: DitoComponent.component(
620
- nested ? 'DitoFormInlined' : 'DitoForm'
634
+ nested ? 'DitoFormNested' : 'DitoForm'
621
635
  ),
622
636
  meta: formMeta
623
637
  }
@@ -666,7 +680,7 @@ export default {
666
680
  }
667
681
  },
668
682
 
669
- processValue(schema, value, dataPath, graph) {
683
+ processValue({ schema, value, dataPath }, graph) {
670
684
  graph.addSource(dataPath, schema)
671
685
  return value
672
686
  }
@@ -11,14 +11,15 @@ export default {
11
11
  })
12
12
  },
13
13
 
14
- processValue(schema, value) {
14
+ processValue(context) {
15
+ let { schema, value } = context
15
16
  if (schema.trim && value != null && isString(value)) {
16
17
  // Text fields don't necessarily have a `String` value when `format()`
17
18
  // without `parse()` is used.
18
19
  value = value.trim()
19
20
  }
20
21
  if (value === '') {
21
- value = getDefaultValue(schema)
22
+ value = getDefaultValue(schema, context)
22
23
  }
23
24
  return value
24
25
  }
@@ -219,6 +219,6 @@ table.dito-table {
219
219
  }
220
220
 
221
221
  table.dito-table table.dito-table,
222
- .dito-form-inlined table.dito-table {
222
+ .dito-form-nested table.dito-table {
223
223
  margin: 0;
224
224
  }
@@ -22,7 +22,7 @@ export default DitoTypeComponent.register('component', {
22
22
  // Override the standard `defaultValue: null` to not set any data for custom
23
23
  // components, unless they provide a default value.
24
24
  defaultValue: () => undefined, // Callback to override `defaultValue: null`
25
- ignoreMissingValue: schema => !('default' in schema),
25
+ ignoreMissingValue: ({ schema }) => !('default' in schema),
26
26
 
27
27
  async processSchema(api, schema) {
28
28
  await resolveSchemaComponent(schema)
@@ -72,7 +72,7 @@ export default DitoTypeComponent.register(
72
72
  }
73
73
  },
74
74
 
75
- processValue(schema, value) {
75
+ processValue({ value }) {
76
76
  return isDate(value) ? value.toISOString() : value
77
77
  }
78
78
  }
@@ -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))
@@ -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)
@@ -624,37 +624,53 @@ export function shouldRenderSchema(schema, context) {
624
624
  )
625
625
  }
626
626
 
627
- export function getDefaultValue(schema) {
627
+ function getContext(context) {
628
+ return isFunction(context) ? context() : context
629
+ }
630
+
631
+ export function getDefaultValue(schema, context) {
628
632
  // Support default values both on schema and on component level.
629
633
  // NOTE: At the time of creation, components may not be instantiated, (e.g. if
630
634
  // entries are created through nested forms, the parent form isn't mounted) so
631
635
  // we can't use `dataPath` to get to components, and the `defaultValue` from
632
636
  // there. That's why `defaultValue` is defined statically in the components:
633
- const defaultValue = schema.default
634
- const value =
635
- defaultValue !== undefined
636
- ? defaultValue
637
+ const defaultValue =
638
+ schema.default !== undefined
639
+ ? schema.default
637
640
  : getTypeOptions(schema)?.defaultValue
638
- return isFunction(value)
639
- ? // TODO: Pass `DitoContext` here too, with the (incomplete) item and al
640
- // the other bits!
641
- value(schema)
642
- : clone(value)
641
+ return isFunction(defaultValue)
642
+ ? defaultValue(getContext(context))
643
+ : clone(defaultValue)
643
644
  }
644
645
 
645
- export function ignoreMissingValue(schema) {
646
- const typeOptions = getTypeOptions(schema)
647
- return !!(
648
- typeOptions?.excludeValue || typeOptions?.ignoreMissingValue?.(schema)
649
- )
646
+ export function shouldExcludeValue(schema, context) {
647
+ const excludeValue =
648
+ schema.exclude !== undefined
649
+ ? schema.exclude
650
+ : getTypeOptions(schema)?.excludeValue
651
+ return isFunction(excludeValue)
652
+ ? excludeValue(getContext(context))
653
+ : !!excludeValue
654
+ }
655
+
656
+ export function shouldIgnoreMissingValue(schema, context) {
657
+ return !!getTypeOptions(schema)?.ignoreMissingValue?.(getContext(context))
650
658
  }
651
659
 
652
660
  export function setDefaultValues(schema, data = {}, component) {
653
661
  const options = { component, rootData: data }
654
662
 
655
- const processBefore = (schema, data, name) => {
656
- if (!(name in data) && !ignoreMissingValue(schema)) {
657
- data[name] = getDefaultValue(schema)
663
+ const processBefore = (schema, data, name, dataPath) => {
664
+ const context = () =>
665
+ new DitoContext(component, {
666
+ schema,
667
+ name,
668
+ data,
669
+ dataPath,
670
+ rootData: options.rootData
671
+ })
672
+ if (!(name in data) && !shouldIgnoreMissingValue(schema, context)) {
673
+ data[name] = getDefaultValue(schema, context)
658
674
  }
659
675
  }
660
676
 
@@ -675,20 +691,20 @@ export function computeValue(schema, data, name, dataPath, {
675
691
  component = null,
676
692
  rootData = component?.rootData
677
693
  } = {}) {
694
+ const context = () =>
695
+ new DitoContext(component, {
696
+ schema,
697
+ // Override value to prevent endless recursion through calling the
698
+ // getter for `this.value` in `DitoContext`:
699
+ value: data[name],
700
+ name,
701
+ data,
702
+ dataPath,
703
+ rootData
704
+ })
678
705
  const { compute } = schema
679
706
  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
- )
707
+ const value = compute(getContext(context))
692
708
  if (value !== undefined) {
693
709
  // Access `data[name]` directly to update the value without calling
694
710
  // parse():
@@ -698,10 +714,10 @@ export function computeValue(schema, data, name, dataPath, {
698
714
  }
699
715
  }
700
716
  // If the value is still missing after compute, set the default for it:
701
- if (!(name in data) && !ignoreMissingValue(schema)) {
717
+ if (!(name in data) && !shouldIgnoreMissingValue(schema, context)) {
702
718
  // TODO: Fix side-effects
703
719
  // eslint-disable-next-line vue/no-side-effects-in-computed-properties
704
- data[name] = getDefaultValue(schema)
720
+ data[name] = getDefaultValue(schema, context)
705
721
  }
706
722
  // Now access the value. This is important for reactivity and needs to
707
723
  // happen after all prior manipulation of `data[name]`, see above:
@@ -772,13 +788,11 @@ export function processData(schema, sourceSchema, data, dataPath, {
772
788
  }
773
789
 
774
790
  const processAfter = (schema, data, name, dataPath, processedData) => {
775
- const { wrapPrimitives, exclude, process } = schema
791
+ const { wrapPrimitives, process } = schema
776
792
  let value = processedData[name]
777
793
 
778
- const typeOptions = getTypeOptions(schema)
779
-
780
794
  // NOTE: We don't cache this context, since `value` is changing.
781
- const getContext = () =>
795
+ const context = () =>
782
796
  new DitoContext(component, {
783
797
  schema,
784
798
  value,
@@ -799,23 +813,18 @@ export function processData(schema, sourceSchema, data, dataPath, {
799
813
 
800
814
  // Each component type can provide its own static `processValue()` method
801
815
  // to convert the data for storage.
802
- const processValue = typeOptions?.processValue
816
+ const processValue = getTypeOptions(schema)?.processValue
803
817
  if (processValue) {
804
- value = processValue(schema, value, dataPath, graph)
818
+ value = processValue(getContext(context), graph)
805
819
  }
806
820
 
807
821
  // Handle the user's `process()` callback next, if one is provided, so that
808
822
  // it can modify data in `processedData` even if it provides `exclude: true`
809
823
  if (process) {
810
- value = process(getContext())
824
+ value = process(getContext(context))
811
825
  }
812
826
 
813
- if (
814
- typeOptions?.excludeValue ||
815
- // Support functions next to booleans for `schema.exclude`:
816
- exclude === true ||
817
- isFunction(exclude) && exclude(getContext())
818
- ) {
827
+ if (shouldExcludeValue(schema, context)) {
819
828
  delete processedData[name]
820
829
  } else {
821
830
  processedData[name] = value