@ditojs/admin 2.25.0 → 2.26.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ditojs/admin",
3
- "version": "2.25.0",
3
+ "version": "2.26.0",
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,57 +33,57 @@
33
33
  "not ie_mob > 0"
34
34
  ],
35
35
  "dependencies": {
36
- "@ditojs/ui": "^2.25.0",
37
- "@ditojs/utils": "^2.25.0",
38
- "@kyvg/vue3-notification": "^3.1.4",
36
+ "@ditojs/ui": "^2.26.0",
37
+ "@ditojs/utils": "^2.26.0",
38
+ "@kyvg/vue3-notification": "^3.2.1",
39
39
  "@lk77/vue3-color": "^3.0.6",
40
- "@tiptap/core": "^2.2.2",
41
- "@tiptap/extension-blockquote": "^2.2.2",
42
- "@tiptap/extension-bold": "^2.2.2",
43
- "@tiptap/extension-bullet-list": "^2.2.2",
44
- "@tiptap/extension-code": "^2.2.2",
45
- "@tiptap/extension-code-block": "^2.2.2",
46
- "@tiptap/extension-document": "^2.2.2",
47
- "@tiptap/extension-hard-break": "^2.2.2",
48
- "@tiptap/extension-heading": "^2.2.2",
49
- "@tiptap/extension-history": "^2.2.2",
50
- "@tiptap/extension-horizontal-rule": "^2.2.2",
51
- "@tiptap/extension-italic": "^2.2.2",
52
- "@tiptap/extension-link": "^2.2.2",
53
- "@tiptap/extension-list-item": "^2.2.2",
54
- "@tiptap/extension-ordered-list": "^2.2.2",
55
- "@tiptap/extension-paragraph": "^2.2.2",
56
- "@tiptap/extension-strike": "^2.2.2",
57
- "@tiptap/extension-text": "^2.2.2",
58
- "@tiptap/extension-underline": "^2.2.2",
59
- "@tiptap/pm": "^2.2.2",
60
- "@tiptap/vue-3": "^2.2.2",
61
- "@vueuse/integrations": "^10.7.2",
40
+ "@tiptap/core": "^2.2.6",
41
+ "@tiptap/extension-blockquote": "^2.2.6",
42
+ "@tiptap/extension-bold": "^2.2.6",
43
+ "@tiptap/extension-bullet-list": "^2.2.6",
44
+ "@tiptap/extension-code": "^2.2.6",
45
+ "@tiptap/extension-code-block": "^2.2.6",
46
+ "@tiptap/extension-document": "^2.2.6",
47
+ "@tiptap/extension-hard-break": "^2.2.6",
48
+ "@tiptap/extension-heading": "^2.2.6",
49
+ "@tiptap/extension-history": "^2.2.6",
50
+ "@tiptap/extension-horizontal-rule": "^2.2.6",
51
+ "@tiptap/extension-italic": "^2.2.6",
52
+ "@tiptap/extension-link": "^2.2.6",
53
+ "@tiptap/extension-list-item": "^2.2.6",
54
+ "@tiptap/extension-ordered-list": "^2.2.6",
55
+ "@tiptap/extension-paragraph": "^2.2.6",
56
+ "@tiptap/extension-strike": "^2.2.6",
57
+ "@tiptap/extension-text": "^2.2.6",
58
+ "@tiptap/extension-underline": "^2.2.6",
59
+ "@tiptap/pm": "^2.2.6",
60
+ "@tiptap/vue-3": "^2.2.6",
61
+ "@vueuse/integrations": "^10.9.0",
62
62
  "codeflask": "^1.4.1",
63
- "filesize": "^10.1.0",
63
+ "filesize": "^10.1.1",
64
64
  "filesize-parser": "^1.5.0",
65
65
  "focus-trap": "^7.5.4",
66
- "nanoid": "^5.0.5",
66
+ "nanoid": "^5.0.7",
67
67
  "sortablejs": "^1.15.2",
68
68
  "tinycolor2": "^1.6.0",
69
69
  "tippy.js": "^6.3.7",
70
- "type-fest": "^4.10.2",
70
+ "type-fest": "^4.15.0",
71
71
  "vue": "3.4.10",
72
72
  "vue-multiselect": "^3.0.0-beta.3",
73
- "vue-router": "^4.2.5",
74
- "vue-upload-component": "^3.1.8"
73
+ "vue-router": "^4.3.0",
74
+ "vue-upload-component": "^3.1.15"
75
75
  },
76
76
  "devDependencies": {
77
- "@ditojs/build": "^2.25.0",
77
+ "@ditojs/build": "^2.26.0",
78
78
  "@vitejs/plugin-vue": "^5.0.4",
79
- "@vue/compiler-sfc": "3.4.10",
79
+ "@vue/compiler-sfc": "3.4.21",
80
80
  "pug": "^3.0.2",
81
- "sass": "1.70.0",
82
- "typescript": "^5.3.3",
83
- "vite": "^5.1.1"
81
+ "sass": "1.74.1",
82
+ "typescript": "^5.4.4",
83
+ "vite": "^5.2.8"
84
84
  },
85
85
  "types": "types",
86
- "gitHead": "888c84b30ad53c2a44ce50174f7ffb851454cec2",
86
+ "gitHead": "da47b5b8b9fca80193a7e93344bdc14cdaada329",
87
87
  "scripts": {
88
88
  "build": "vite build",
89
89
  "watch": "yarn build --mode 'development' --watch",
@@ -88,15 +88,18 @@ export default DitoComponent.component('DitoForm', {
88
88
  },
89
89
 
90
90
  schema() {
91
- return (
92
- this.getItemFormSchema(
93
- this.sourceSchema,
94
- // If there is no data yet, provide an empty object with just the
95
- // right type set, so the form can always be determined.
96
- this.data || { type: this.type },
97
- this.context
98
- ) || {}
99
- ) // Always return a schema object so we don't need to check for it.
91
+ return this.getItemFormSchema(
92
+ this.sourceSchema,
93
+ this.data || (
94
+ this.creationType
95
+ ? // If there is no data yet but the type to create a new item is
96
+ // is specified, provide a temporary empty object with just the
97
+ // type set, so `getItemFormSchema()` can determine the form.
98
+ { type: this.creationType }
99
+ : null
100
+ ),
101
+ this.context
102
+ )
100
103
  },
101
104
 
102
105
  buttonSchemas() {
@@ -156,7 +159,7 @@ export default DitoComponent.component('DitoForm', {
156
159
  return this.mainSchemaComponent?.selectedTab || null
157
160
  },
158
161
 
159
- type() {
162
+ creationType() {
160
163
  // The type of form to create, if there are multiple forms to choose from.
161
164
  return this.$route.query.type
162
165
  },
@@ -235,7 +238,8 @@ export default DitoComponent.component('DitoForm', {
235
238
  // parent data so we can replace the entry at `sourceKey` on it.
236
239
  if (i === l - 1) {
237
240
  // TODO: Fix side-effects
238
- // eslint-disable-next-line
241
+ // eslint-disable-next-line max-len
242
+ // eslint-disable-next-line vue/no-side-effects-in-computed-properties
239
243
  this.sourceKey = key
240
244
  } else {
241
245
  data = data[key]
@@ -330,7 +334,7 @@ export default DitoComponent.component('DitoForm', {
330
334
  // @override ResourceMixin.setupData()
331
335
  setupData() {
332
336
  if (this.isCreating) {
333
- this.createdData ||= this.createData(this.schema, this.type)
337
+ this.createdData ||= this.createData(this.schema, this.creationType)
334
338
  } else {
335
339
  this.ensureData()
336
340
  }
@@ -17,7 +17,7 @@
17
17
  // -Use <span> for .dito-break so we can use `.dito-container:first-of-type`
18
18
  // selector.
19
19
  span.dito-break(
20
- v-if="schema.break === 'before'"
20
+ v-if="['before', 'both'].includes(schema.break)"
21
21
  )
22
22
  DitoContainer(
23
23
  v-if="shouldRenderSchema(schema)"
@@ -37,7 +37,7 @@
37
37
  :accumulatedBasis="accumulatedBasis"
38
38
  )
39
39
  span.dito-break(
40
- v-if="schema.break === 'after'"
40
+ v-if="['after', 'both'].includes(schema.break)"
41
41
  )
42
42
  </template>
43
43
 
@@ -118,7 +118,8 @@ import {
118
118
  getNamedSchemas,
119
119
  getPanelEntries,
120
120
  setDefaultValues,
121
- processData
121
+ processData,
122
+ isEmptySchema
122
123
  } from '../utils/schema.js'
123
124
  import { getSchemaAccessor, getStoreAccessor } from '../utils/accessor.js'
124
125
 
@@ -233,11 +234,15 @@ export default DitoComponent.component('DitoSchema', {
233
234
  },
234
235
 
235
236
  processedData() {
237
+ // TODO: Fix side-effects
238
+ // eslint-disable-next-line vue/no-side-effects-in-computed-properties
236
239
  return this.processData({ target: 'server', schemaOnly: true })
237
240
  },
238
241
 
239
242
  clipboardData: {
240
243
  get() {
244
+ // TODO: Fix side-effects
245
+ // eslint-disable-next-line vue/no-side-effects-in-computed-properties
241
246
  return this.processData({ target: 'clipboard', schemaOnly: true })
242
247
  },
243
248
 
@@ -361,6 +366,17 @@ export default DitoComponent.component('DitoSchema', {
361
366
  },
362
367
 
363
368
  watch: {
369
+ schema: {
370
+ immediate: true,
371
+ handler(schema) {
372
+ // For forms with type depending on loaded data, we need to wait for the
373
+ // actual schema to become ready before setting up schema related things
374
+ if (!isEmptySchema(schema)) {
375
+ this.setupSchema()
376
+ }
377
+ }
378
+ },
379
+
364
380
  routeTab: {
365
381
  immediate: true,
366
382
  // https://github.com/vuejs/vue-router/issues/3393#issuecomment-1158470149
@@ -397,10 +413,6 @@ export default DitoComponent.component('DitoSchema', {
397
413
 
398
414
  created() {
399
415
  this._register(true)
400
- this.setupSchemaFields()
401
- // Delegate change events through to parent schema:
402
- this.delegate('change', this.parentSchemaComponent)
403
- this.emitEvent('initialize') // Not `'create'`, since that's for data.
404
416
  if (this.scrollable && this.wide) {
405
417
  this.appState.pageClass = 'dito-page--wide'
406
418
  }
@@ -419,6 +431,13 @@ export default DitoComponent.component('DitoSchema', {
419
431
  },
420
432
 
421
433
  methods: {
434
+ setupSchema() {
435
+ this.setupSchemaFields()
436
+ // Delegate change events through to parent schema:
437
+ this.delegate('change', this.parentSchemaComponent)
438
+ this.emitEvent('initialize') // Not `'create'`, since that's for data.
439
+ },
440
+
422
441
  getComponentsByDataPath(dataPath) {
423
442
  return this._getEntriesByDataPath(this.componentsByDataPath, dataPath)
424
443
  },
@@ -186,6 +186,9 @@ export default {
186
186
  // we're currently editing.
187
187
  for (const option of options) {
188
188
  if (!('id' in option)) {
189
+ // TODO: Fix side-effects
190
+ // eslint-disable-next-line max-len
191
+ // eslint-disable-next-line vue/no-side-effects-in-computed-properties
189
192
  setTemporaryId(option, 'id')
190
193
  }
191
194
  }
@@ -203,7 +206,7 @@ export default {
203
206
  }
204
207
  results.push(entry)
205
208
  }
206
- entry.options.push(option)
209
+ entry[this.groupByOptions].push(option)
207
210
  return results
208
211
  },
209
212
  []
@@ -87,7 +87,8 @@ export default DitoTypeComponent.register('color', {
87
87
  const color = tinycolor(this.value)
88
88
  if (color.isValid()) {
89
89
  // TODO: Fix side-effects
90
- // eslint-disable-next-line
90
+ // eslint-disable-next-line max-len
91
+ // eslint-disable-next-line vue/no-side-effects-in-computed-properties
91
92
  this.convertedHexValue = color
92
93
  .toString(color.getAlpha() < 1 ? 'hex8' : 'hex6')
93
94
  .slice(1)
@@ -33,7 +33,8 @@ export default DitoTypeComponent.register(
33
33
  if (schema.data || schema.dataPath) {
34
34
  const value = this.handleDataSchema(schema, 'schema')
35
35
  // TODO: Fix side-effects
36
- // eslint-disable-next-line
36
+ // eslint-disable-next-line max-len
37
+ // eslint-disable-next-line vue/no-side-effects-in-computed-properties
37
38
  this.data[this.name] = value
38
39
  }
39
40
  return TypeMixin.computed.value.get.call(this)
@@ -23,6 +23,7 @@ import { markRaw } from 'vue'
23
23
 
24
24
  const typeComponents = {}
25
25
  const unknownTypeReported = {}
26
+ const emptySchema = {}
26
27
 
27
28
  export function registerTypeComponent(type, component) {
28
29
  typeComponents[type] = component
@@ -324,7 +325,7 @@ export function processSchemaDefaults(api, schema) {
324
325
  if (schema[key] === undefined) {
325
326
  schema[key] = value
326
327
  } else {
327
- schema[key] = assignDeeply(value, schema[key])
328
+ schema[key] = assignDeeply(schema[key], value)
328
329
  }
329
330
  }
330
331
  }
@@ -518,7 +519,15 @@ export function getItemFormSchemaFromForms(forms, item) {
518
519
  }
519
520
 
520
521
  export function getItemFormSchema(schema, item, context) {
521
- return getItemFormSchemaFromForms(getFormSchemas(schema, context), item)
522
+ return (
523
+ getItemFormSchemaFromForms(getFormSchemas(schema, context), item) ||
524
+ // Always return a schema object so we don't need to check for it.
525
+ emptySchema
526
+ )
527
+ }
528
+
529
+ export function isEmptySchema(schema) {
530
+ return schema === emptySchema
522
531
  }
523
532
 
524
533
  export function isCompact(schema) {
@@ -672,11 +681,15 @@ export function computeValue(schema, data, name, dataPath, {
672
681
  if (value !== undefined) {
673
682
  // Access `data[name]` directly to update the value without calling
674
683
  // parse():
684
+ // TODO: Fix side-effects
685
+ // eslint-disable-next-line vue/no-side-effects-in-computed-properties
675
686
  data[name] = value
676
687
  }
677
688
  }
678
689
  // If the value is still missing after compute, set the default for it:
679
690
  if (!(name in data) && !ignoreMissingValue(schema)) {
691
+ // TODO: Fix side-effects
692
+ // eslint-disable-next-line vue/no-side-effects-in-computed-properties
680
693
  data[name] = getDefaultValue(schema)
681
694
  }
682
695
  // Now access the value. This is important for reactivity and needs to