@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ditojs/admin",
3
- "version": "2.26.2",
3
+ "version": "2.27.1",
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/master/packages/admin",
@@ -33,8 +33,8 @@
33
33
  "not ie_mob > 0"
34
34
  ],
35
35
  "dependencies": {
36
- "@ditojs/ui": "^2.26.1",
37
- "@ditojs/utils": "^2.26.1",
36
+ "@ditojs/ui": "^2.27.0",
37
+ "@ditojs/utils": "^2.27.0",
38
38
  "@kyvg/vue3-notification": "^3.2.1",
39
39
  "@lk77/vue3-color": "^3.0.6",
40
40
  "@tiptap/core": "^2.3.0",
@@ -74,7 +74,7 @@
74
74
  "vue-upload-component": "^3.1.15"
75
75
  },
76
76
  "devDependencies": {
77
- "@ditojs/build": "^2.26.1",
77
+ "@ditojs/build": "^2.27.0",
78
78
  "@vitejs/plugin-vue": "^5.0.4",
79
79
  "@vue/compiler-sfc": "3.4.21",
80
80
  "pug": "^3.0.2",
@@ -83,7 +83,7 @@
83
83
  "vite": "^5.2.8"
84
84
  },
85
85
  "types": "types",
86
- "gitHead": "7fd7a0b9a8727e1a27a8e78e7381f58c95017499",
86
+ "gitHead": "f8e8c86149487d9a7b991c9c4b8d9165974fb0a2",
87
87
  "scripts": {
88
88
  "build": "vite build",
89
89
  "watch": "yarn build --mode 'development' --watch",
package/src/DitoAdmin.js CHANGED
@@ -124,9 +124,7 @@ export default class DitoAdmin {
124
124
  },
125
125
 
126
126
  member(resource) {
127
- // NOTE: We assume that all members have root-level collection routes,
128
- // to avoid excessive nesting of (sub-)collection routes.
129
- return `${resource.path}/${resource.id}`
127
+ return `${this.default(resource)}/${resource.id}`
130
128
  },
131
129
 
132
130
  upload(resource) {
@@ -140,6 +140,10 @@ export default class DitoContext {
140
140
  return get(this, 'processedData', null)
141
141
  }
142
142
 
143
+ get processedRootItem() {
144
+ return get(this, 'processedRootData', null)
145
+ }
146
+
143
147
  get clipboardItem() {
144
148
  return get(this, 'clipboardData', null)
145
149
  }
@@ -255,6 +255,12 @@ export default DitoComponent.component('DitoContainer', {
255
255
  // percentages in flex-basis to work.
256
256
  padding: $form-spacing-half;
257
257
 
258
+ > .dito-label:only-child {
259
+ // Used e.g. when sources hide themselves due to maxDepth, but the label
260
+ // is rendered above it.
261
+ display: none;
262
+ }
263
+
258
264
  .dito-pane > & {
259
265
  .dito-page--width-80 & {
260
266
  flex-grow: 1;
@@ -7,13 +7,13 @@
7
7
  //- nested form route, which will appear elsewhere in its own view.
8
8
  RouterView(
9
9
  v-if="!isLastUnnestedRoute && !isNestedRoute"
10
- v-show="!isActive"
10
+ v-show="!isActiveRoute"
11
11
  )
12
12
  //- NOTE: Nested form components are kept alive by using `v-show` instead of
13
13
  //- `v-if` here, so event handling and other things still work with nested
14
14
  //- editing.
15
15
  DitoFormInner(
16
- v-show="isActive"
16
+ v-show="isActiveRoute"
17
17
  :nested="isNestedRoute"
18
18
  )
19
19
  //- Prevent implicit submission of the form, for example when typing enter
@@ -31,6 +31,7 @@
31
31
  :meta="meta"
32
32
  :store="store"
33
33
  :padding="isNestedRoute ? 'nested' : 'root'"
34
+ :active="isActiveRoute"
34
35
  :disabled="isLoading"
35
36
  :scrollable="!isNestedRoute"
36
37
  generateLabels
@@ -125,7 +126,7 @@ export default DitoComponent.component('DitoForm', {
125
126
  )
126
127
  },
127
128
 
128
- isActive() {
129
+ isActiveRoute() {
129
130
  return this.isLastRoute || this.isLastUnnestedRoute
130
131
  },
131
132
 
@@ -168,11 +169,6 @@ export default DitoComponent.component('DitoForm', {
168
169
  return this.isCreating ? 'post' : 'patch'
169
170
  },
170
171
 
171
- resource() {
172
- const resource = this.getResource()
173
- return getMemberResource(this.itemId, resource) || resource
174
- },
175
-
176
172
  breadcrumbPrefix() {
177
173
  return capitalize(this.isCreating ? this.verbs.create : this.verbs.edit)
178
174
  },
@@ -325,6 +321,12 @@ export default DitoComponent.component('DitoForm', {
325
321
  )
326
322
  },
327
323
 
324
+ // @override ResourceMixin.getResource()
325
+ getResource(defaults) {
326
+ const resource = ResourceMixin.methods.getResource.call(this, defaults)
327
+ return getMemberResource(this.itemId, resource) || resource
328
+ },
329
+
328
330
  // @override ResourceMixin.setupData()
329
331
  setupData() {
330
332
  if (this.isCreating) {
@@ -337,7 +339,8 @@ export default DitoComponent.component('DitoForm', {
337
339
  setSourceData(data) {
338
340
  if (this.sourceData && this.sourceKey !== null) {
339
341
  const { mainSchemaComponent } = this
340
- this.sourceData[this.sourceKey] = mainSchemaComponent.filterData(data)
342
+ this.sourceData[this.sourceKey] =
343
+ mainSchemaComponent.filterData(data).localData
341
344
  mainSchemaComponent.onChange()
342
345
  return true
343
346
  }
@@ -400,11 +403,13 @@ export default DitoComponent.component('DitoForm', {
400
403
  const getVerb = present => this.verbs[this.getSubmitVerb(present)]
401
404
 
402
405
  // Allow buttons to override both method and resource path to submit to:
406
+ let { method } = this
407
+ let resource = this.getResource({ method })
403
408
  const buttonResource = getResource(button.schema.resource, {
404
- parent: this.resource
409
+ parent: resource
405
410
  })
406
- const resource = buttonResource || this.resource
407
- const method = resource?.method || this.method
411
+ resource = buttonResource || resource
412
+ method = resource?.method || method
408
413
  const data = this.getPayloadData(button, method)
409
414
  let success
410
415
  if (!buttonResource && this.isTransient) {
@@ -9,6 +9,7 @@ slot(name="before")
9
9
  to=".dito-sidebar__teleport"
10
10
  )
11
11
  DitoPanels(
12
+ v-if="active"
12
13
  :panels="panelEntries"
13
14
  :data="data"
14
15
  :meta="meta"
@@ -20,7 +21,9 @@ slot(name="before")
20
21
  :to="headerTeleport"
21
22
  :disabled="!headerTeleport"
22
23
  )
23
- .dito-schema-header
24
+ .dito-schema-header(
25
+ v-if="active"
26
+ )
24
27
  DitoLabel(
25
28
  v-if="hasLabel"
26
29
  :label="label"
@@ -119,7 +122,8 @@ import {
119
122
  getPanelEntries,
120
123
  setDefaultValues,
121
124
  processData,
122
- isEmptySchema
125
+ isEmptySchema,
126
+ isNested
123
127
  } from '../utils/schema.js'
124
128
  import { getSchemaAccessor, getStoreAccessor } from '../utils/accessor.js'
125
129
 
@@ -147,6 +151,7 @@ export default DitoComponent.component('DitoSchema', {
147
151
  store: { type: Object, default: () => ({}) },
148
152
  label: { type: [String, Object], default: null },
149
153
  padding: { type: String, default: null },
154
+ active: { type: Boolean, default: true },
150
155
  inlined: { type: Boolean, default: false },
151
156
  disabled: { type: Boolean, default: false },
152
157
  collapsed: { type: Boolean, default: false },
@@ -223,7 +228,7 @@ export default DitoComponent.component('DitoSchema', {
223
228
  },
224
229
 
225
230
  headerTeleport() {
226
- return this.isRootSchema
231
+ return this.isTopLevelSchema
227
232
  ? '.dito-header__teleport'
228
233
  : this.labelNode
229
234
  },
@@ -283,9 +288,8 @@ export default DitoComponent.component('DitoSchema', {
283
288
  )
284
289
  },
285
290
 
286
- isRootSchema() {
287
- // Section schemas can share the root dataPath but they are inlined.
288
- return this.dataPath === '' && !this.inlined
291
+ isNested() {
292
+ return isNested(this.schema)
289
293
  },
290
294
 
291
295
  isDirty() {
@@ -320,8 +324,12 @@ export default DitoComponent.component('DitoSchema', {
320
324
  return !!this.tabs
321
325
  },
322
326
 
323
- hasRootTabs() {
324
- return this.hasTabs && this.isRootSchema
327
+ isTopLevelSchema() {
328
+ return !this.isNested && !this.inlined
329
+ },
330
+
331
+ hasTopLevelTabs() {
332
+ return this.hasTabs && this.isTopLevelSchema
325
333
  },
326
334
 
327
335
  hasMainPane() {
@@ -385,7 +393,7 @@ export default DitoComponent.component('DitoSchema', {
385
393
  // Remember the current path to know if tab changes should still be
386
394
  // handled, but remove the trailing `/create` or `/:id` from it so that
387
395
  // tabs informs that stay open after creation still work.
388
- if (this.hasRootTabs) {
396
+ if (this.hasTopLevelTabs) {
389
397
  this.selectedTab = routeTab
390
398
  }
391
399
  }
@@ -399,7 +407,7 @@ export default DitoComponent.component('DitoSchema', {
399
407
  content.scrollTop = this.scrollPositions[newTab] ?? 0
400
408
  })
401
409
  }
402
- if (this.hasRootTabs) {
410
+ if (this.hasTopLevelTabs) {
403
411
  const tab = this.shouldRenderSchema(this.tabs[newTab])
404
412
  ? newTab
405
413
  : this.defaultTab
@@ -687,20 +695,22 @@ export default DitoComponent.component('DitoSchema', {
687
695
  },
688
696
 
689
697
  filterData(data) {
690
- // Filters out arrays and objects that are back by data resources
691
- // themselves, as those are already taking care of through their own API
698
+ // Filters out arrays and objects that are backed by data resources
699
+ // themselves, as those are already taken care of through their own API
692
700
  // resource end-points and shouldn't be set.
693
- const copy = {}
701
+ const localData = {}
702
+ const foreignData = {}
694
703
  for (const [name, value] of Object.entries(data)) {
695
704
  if (isArray(value) || isObject(value)) {
696
705
  const components = this.getComponentsByName(name)
697
706
  if (components.some(component => component.providesData)) {
707
+ foreignData[name] = value
698
708
  continue
699
709
  }
700
710
  }
701
- copy[name] = value
711
+ localData[name] = value
702
712
  }
703
- return copy
713
+ return { localData, foreignData }
704
714
  },
705
715
 
706
716
  processData({ target = 'clipboard', schemaOnly = true } = {}) {
@@ -75,7 +75,7 @@ export default DitoComponent.component('DitoView', {
75
75
  },
76
76
 
77
77
  mainComponent() {
78
- return this.mainSchemaComponent.getComponentByDataPath(this.name)
78
+ return this.mainSchemaComponent?.getComponentByDataPath(this.name)
79
79
  },
80
80
 
81
81
  viewSchema() {
@@ -109,15 +109,22 @@ export default {
109
109
  async resolveData(load, loadingOptions = {}) {
110
110
  // Use a timeout to allow already resolved promises to return data without
111
111
  // showing a loading indicator.
112
- const timer = setTimeout(() => this.setLoading(true, loadingOptions), 0)
112
+ let clearLoading = false
113
+ const timer = setTimeout(() => {
114
+ this.setLoading(true, loadingOptions)
115
+ clearLoading = true
116
+ }, 0)
113
117
  let data = null
114
118
  try {
115
119
  data = await (isFunction(load) ? load() : load)
116
120
  } catch (error) {
117
121
  this.addError(error.message || error)
118
122
  }
119
- clearTimeout(timer)
120
- this.setLoading(false, loadingOptions)
123
+ if (clearLoading) {
124
+ this.setLoading(false, loadingOptions)
125
+ } else {
126
+ clearTimeout(timer)
127
+ }
121
128
  return data
122
129
  }
123
130
  }
@@ -155,15 +155,19 @@ export default {
155
155
  },
156
156
 
157
157
  parentSchemaComponent() {
158
- return this.schemaComponent?.parentComponent.schemaComponent
158
+ return getParentComponent(this, 'schemaComponent')
159
159
  },
160
160
 
161
161
  parentRouteComponent() {
162
- return this.routeComponent?.parentComponent.routeComponent
162
+ return getParentComponent(this, 'routeComponent')
163
163
  },
164
164
 
165
165
  parentFormComponent() {
166
- return this.formComponent?.parentComponent.formComponent
166
+ return getParentComponent(this, 'formComponent')
167
+ },
168
+
169
+ parentResourceComponent() {
170
+ return getParentComponent(this, 'resourceComponent')
167
171
  },
168
172
 
169
173
  // Returns the data of the first route component in the chain of parents
@@ -307,13 +311,12 @@ export default {
307
311
  },
308
312
 
309
313
  getResourcePath(resource) {
310
- resource = getResource(resource)
311
- // Resources without a parent inherit the one from `dataComponent`
312
- // automatically.
313
- if (resource.parent === undefined) {
314
- resource.parent = this.dataComponent?.resource
315
- }
316
- return this.api.resources.any(getResource(resource))
314
+ resource = getResource(resource, {
315
+ // Resources without a parent inherit the one from `dataComponent`
316
+ // automatically.
317
+ parent: this.dataComponent?.resource ?? null
318
+ })
319
+ return this.api.resources.any(resource)
317
320
  },
318
321
 
319
322
  getResourceUrl(resource) {
@@ -574,3 +577,12 @@ export default {
574
577
  }
575
578
 
576
579
  let nextUid = 0
580
+
581
+ function getParentComponent(component, key) {
582
+ const current = component[key]
583
+ let parent = component.parentComponent
584
+ while (parent && parent[key] === current) {
585
+ parent = parent.parentComponent
586
+ }
587
+ return parent?.[key] ?? null
588
+ }
@@ -260,7 +260,7 @@ export default {
260
260
  }
261
261
  },
262
262
 
263
- processValue(schema, value, dataPath, graph) {
263
+ processValue({ schema, value, dataPath }, graph) {
264
264
  if (schema.relate) {
265
265
  // For internally relating data (`schema.options.dataPath`), we need to
266
266
  // process both the options (for '#ref') and the value ('#id').
@@ -1,7 +1,7 @@
1
1
  import ItemMixin from './ItemMixin.js'
2
2
  import LoadingMixin from './LoadingMixin.js'
3
3
  import { setDefaultValues } from '../utils/schema.js'
4
- import { isObject, isString, labelize } from '@ditojs/utils'
4
+ import { assignDeeply, isObject, isString, labelize } from '@ditojs/utils'
5
5
  import { getResource } from '../utils/resource.js'
6
6
  import DitoContext from '../DitoContext.js'
7
7
 
@@ -31,8 +31,6 @@ export default {
31
31
  },
32
32
 
33
33
  resource() {
34
- // Returns the resource object representing the resource for the
35
- // associated source schema.
36
34
  return this.getResource()
37
35
  },
38
36
 
@@ -126,12 +124,13 @@ export default {
126
124
  },
127
125
 
128
126
  methods: {
129
- getResource() {
130
- // This is defined as a method so the computed `resource` getter can
131
- // be overridden and `super` functionality can still be accessed.
127
+ getResource(defaults = { method: 'get' }) {
128
+ // Returns the resource object representing the resource for the
129
+ // associated source schema.
132
130
  return getResource(this.sourceSchema?.resource, {
133
131
  type: 'collection',
134
- parent: this.parentFormComponent?.resource ?? null
132
+ parent: this.parentResourceComponent?.resource ?? null,
133
+ ...defaults
135
134
  })
136
135
  },
137
136
 
@@ -230,7 +229,7 @@ export default {
230
229
  async handleRequest(
231
230
  {
232
231
  method,
233
- resource = this.resource,
232
+ resource = this.getResource({ method }),
234
233
  query,
235
234
  data
236
235
  },
@@ -244,6 +243,7 @@ export default {
244
243
  const controller = new AbortController()
245
244
  this.abortController = controller
246
245
  const { signal } = controller
246
+ method = resource.method || method
247
247
  const request = { method, resource, query, data, signal }
248
248
  this.setLoading(true, loadingOptions)
249
249
  try {
@@ -340,7 +340,17 @@ export default {
340
340
  // Update the underlying data before calling `notify()` or
341
341
  // `this.itemLabel`, so id is set after creating new items.
342
342
  if (setData && data) {
343
- this.setData(data)
343
+ // Preserve the foreign data entries when updating the data.
344
+ const { foreignData } = this.mainSchemaComponent.filterData(
345
+ this.data
346
+ )
347
+ // Tell the parent route to reload its data, so that it can
348
+ // update its foreign data entries.
349
+ const parentMeta = this.parentRouteComponent?.routeRecord?.meta
350
+ if (parentMeta) {
351
+ parentMeta.reload = true
352
+ }
353
+ this.setData(assignDeeply({}, foreignData, data))
344
354
  }
345
355
  onSuccess?.()
346
356
  await this.emitButtonEvent(button, 'success', {
@@ -31,7 +31,7 @@ export default {
31
31
  routeLevel() {
32
32
  let level = 0
33
33
  let routeComponent = this
34
- while ((routeComponent = routeComponent.parentComponent.routeComponent)) {
34
+ while ((routeComponent = routeComponent.parentRouteComponent)) {
35
35
  level++
36
36
  }
37
37
  return level
@@ -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 {
@@ -68,10 +68,17 @@ export default {
68
68
  return !!this.value
69
69
  },
70
70
 
71
+ shouldRender() {
72
+ return this.sourceDepth < this.maxDepth
73
+ },
74
+
71
75
  isReady() {
72
76
  // Lists that have no data and no associated resource should still render,
73
77
  // as they may be getting their data elsewhere, e.g. `compute()`.
74
- return this.hasData || !this.providesData
78
+ return (
79
+ this.shouldRender &&
80
+ (this.hasData || !this.providesData)
81
+ )
75
82
  },
76
83
 
77
84
  isInView() {
@@ -147,6 +154,15 @@ export default {
147
154
  return this.schema
148
155
  },
149
156
 
157
+ sourceDepth() {
158
+ return this.$route.matched.reduce(
159
+ (depth, record) => (
160
+ depth + (record.meta.schema === this.sourceSchema ? 1 : 0)
161
+ ),
162
+ 0
163
+ )
164
+ },
165
+
150
166
  path() {
151
167
  // This is used in TypeList for DitoFormChooser.
152
168
  return this.routeComponent.getChildPath(this.schema.path)
@@ -313,6 +329,11 @@ export default {
313
329
  collapsed: getSchemaAccessor('collapsed', {
314
330
  type: Boolean,
315
331
  default: null
332
+ }),
333
+
334
+ maxDepth: getSchemaAccessor('maxDepth', {
335
+ type: Number,
336
+ default: 1
316
337
  })
317
338
  },
318
339
 
@@ -321,15 +342,25 @@ export default {
321
342
  // https://github.com/vuejs/vue-router/issues/3393#issuecomment-1158470149
322
343
  flush: 'post',
323
344
  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)
345
+ if (this.providesData) {
346
+ if (
347
+ from.path === to.path &&
348
+ from.hash === to.hash
349
+ ) {
350
+ // Paths and hashes remain the same, so only queries have changed.
351
+ // Update filter and reload data without clearing.
352
+ this.query = to.query
353
+ this.loadData(false)
354
+ } else if (
355
+ this.meta.reload &&
356
+ from.path !== to.path &&
357
+ from.path.startsWith(to.path)
358
+ ) {
359
+ // Reload the source when navigating back to a parent-route after
360
+ // changing data in a child-route.
361
+ this.meta.reload = false
362
+ this.loadData(false)
363
+ }
333
364
  }
334
365
  }
335
366
  },
@@ -464,9 +495,13 @@ export default {
464
495
  notify()
465
496
  } else {
466
497
  const itemId = this.getItemId(this.schema, item, index)
467
- const resource = getMemberResource(itemId, this.resource)
498
+ const method = 'delete'
499
+ const resource = getMemberResource(
500
+ itemId,
501
+ this.getResource({ method })
502
+ )
468
503
  if (resource) {
469
- this.handleRequest({ method: 'delete', resource }, err => {
504
+ this.handleRequest({ method, resource }, err => {
470
505
  if (!err) {
471
506
  this.removeItem(item, index)
472
507
  notify()
@@ -666,7 +701,7 @@ export default {
666
701
  }
667
702
  },
668
703
 
669
- processValue(schema, value, dataPath, graph) {
704
+ processValue({ schema, value, dataPath }, graph) {
670
705
  graph.addSource(dataPath, schema)
671
706
  return value
672
707
  }
@@ -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
  }
@@ -77,16 +77,11 @@ export default {
77
77
  },
78
78
 
79
79
  processedData() {
80
- // We can only get the processed data through the schemaComponent, but
81
- // that's not necessarily the item represented by this component.
82
- // Solution: Find the relative path and the processed sub-item from there:
83
- const { schemaComponent } = this
84
- return getItem(
85
- schemaComponent.processedData,
86
- // Get the dataPath relative to the schemaComponent's data:
87
- this.dataPath.slice(schemaComponent.dataPath.length),
88
- this.nested
89
- )
80
+ return getProcessedParentData(this, this.dataPath, this.nested)
81
+ },
82
+
83
+ processedRootData() {
84
+ return getProcessedParentData(this, '', false)
90
85
  },
91
86
 
92
87
  // The following computed properties are similar to `DitoContext`
@@ -107,6 +102,10 @@ export default {
107
102
  return this.processedData
108
103
  },
109
104
 
105
+ processedRootItem() {
106
+ return this.processedRootData
107
+ },
108
+
110
109
  labelNode() {
111
110
  const node = this.isMounted ? this.$el.previousElementSibling : null
112
111
  return node?.matches('.dito-label') ? node : null
@@ -327,3 +326,20 @@ export default {
327
326
  }
328
327
  }
329
328
  }
329
+
330
+ function getProcessedParentData(component, dataPath, nested = false) {
331
+ // We can only get the processed data through the schemaComponent, but
332
+ // that's not necessarily the item represented by this component.
333
+ // Solution: Find the relative path and the processed sub-item from there:
334
+ let { schemaComponent } = component
335
+ // Find the schema component that contains the desired data-path:
336
+ while (schemaComponent.dataPath.length > dataPath.length) {
337
+ schemaComponent = schemaComponent.parentSchemaComponent
338
+ }
339
+ return getItem(
340
+ schemaComponent.processedData,
341
+ // Get the dataPath relative to the schemaComponent's data:
342
+ dataPath.slice(schemaComponent.dataPath.length),
343
+ nested
344
+ )
345
+ }
@@ -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
  }