@ditojs/admin 2.0.2 → 2.0.4

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.0.2",
3
+ "version": "2.0.4",
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,38 +33,39 @@
33
33
  "not ie_mob > 0"
34
34
  ],
35
35
  "dependencies": {
36
- "@ditojs/ui": "^2.0.1",
36
+ "@ditojs/ui": "^2.0.4",
37
37
  "@ditojs/utils": "^2.0.1",
38
38
  "@kyvg/vue3-notification": "^2.9.0",
39
39
  "@lk77/vue3-color": "^3.0.6",
40
- "@tiptap/core": "^2.0.1",
41
- "@tiptap/extension-blockquote": "^2.0.1",
42
- "@tiptap/extension-bold": "^2.0.1",
43
- "@tiptap/extension-bullet-list": "^2.0.1",
44
- "@tiptap/extension-code": "^2.0.1",
45
- "@tiptap/extension-code-block": "^2.0.1",
46
- "@tiptap/extension-document": "^2.0.1",
47
- "@tiptap/extension-hard-break": "^2.0.1",
48
- "@tiptap/extension-heading": "^2.0.1",
49
- "@tiptap/extension-history": "^2.0.1",
50
- "@tiptap/extension-horizontal-rule": "^2.0.1",
51
- "@tiptap/extension-italic": "^2.0.1",
52
- "@tiptap/extension-link": "^2.0.1",
53
- "@tiptap/extension-list-item": "^2.0.1",
54
- "@tiptap/extension-ordered-list": "^2.0.1",
55
- "@tiptap/extension-paragraph": "^2.0.1",
56
- "@tiptap/extension-strike": "^2.0.1",
57
- "@tiptap/extension-text": "^2.0.1",
58
- "@tiptap/extension-underline": "^2.0.1",
59
- "@tiptap/pm": "^2.0.1",
60
- "@tiptap/vue-3": "^2.0.1",
40
+ "@tiptap/core": "^2.0.2",
41
+ "@tiptap/extension-blockquote": "^2.0.2",
42
+ "@tiptap/extension-bold": "^2.0.2",
43
+ "@tiptap/extension-bullet-list": "^2.0.2",
44
+ "@tiptap/extension-code": "^2.0.2",
45
+ "@tiptap/extension-code-block": "^2.0.2",
46
+ "@tiptap/extension-document": "^2.0.2",
47
+ "@tiptap/extension-hard-break": "^2.0.2",
48
+ "@tiptap/extension-heading": "^2.0.2",
49
+ "@tiptap/extension-history": "^2.0.2",
50
+ "@tiptap/extension-horizontal-rule": "^2.0.2",
51
+ "@tiptap/extension-italic": "^2.0.2",
52
+ "@tiptap/extension-link": "^2.0.2",
53
+ "@tiptap/extension-list-item": "^2.0.2",
54
+ "@tiptap/extension-ordered-list": "^2.0.2",
55
+ "@tiptap/extension-paragraph": "^2.0.2",
56
+ "@tiptap/extension-strike": "^2.0.2",
57
+ "@tiptap/extension-text": "^2.0.2",
58
+ "@tiptap/extension-underline": "^2.0.2",
59
+ "@tiptap/pm": "^2.0.2",
60
+ "@tiptap/vue-3": "^2.0.2",
61
+ "@vueuse/integrations": "^10.0.0-beta.2",
61
62
  "codeflask": "^1.4.1",
62
63
  "filesize": "^10.0.7",
63
64
  "filesize-parser": "^1.5.0",
64
65
  "nanoid": "^4.0.2",
66
+ "sortablejs": "^1.15.0",
65
67
  "tinycolor2": "^1.6.0",
66
68
  "vue": "^3.2.47",
67
- "vue-draggable-plus": "^0.1.1",
68
69
  "vue-multiselect": "^3.0.0-beta.1",
69
70
  "vue-router": "^4.1.6",
70
71
  "vue-upload-component": "^3.1.8"
@@ -80,7 +81,7 @@
80
81
  "vite": "^4.2.1"
81
82
  },
82
83
  "types": "types",
83
- "gitHead": "3e7213fbe25c5697f4f11dada830037934e396c8",
84
+ "gitHead": "e2236a6758c7716a20f8e9fc7c7787521782d6d4",
84
85
  "scripts": {
85
86
  "build": "vite build",
86
87
  "watch": "yarn build --mode 'development' --watch",
@@ -52,7 +52,7 @@ component.dito-label(
52
52
  // so that buttons always appear right-aligned:
53
53
  flex: 1 1 auto
54
54
  &::after
55
- content: '\a0' // &nbps;
55
+ content: '\a0' //  
56
56
 
57
57
  .dito-label-prefix,
58
58
  .dito-label-suffix
@@ -94,8 +94,9 @@ component.dito-label(
94
94
  > .dito-schema-content
95
95
  > .dito-pane
96
96
  > .dito-container
97
- > .dito-label:not(.dito-label-component)
98
- display: inline-block
97
+ display: flex
98
+ flex-flow: row wrap
99
+ align-items: baseline
99
100
  </style>
100
101
 
101
102
  <script>
@@ -130,11 +131,7 @@ export default DitoComponent.component('dito-label', {
130
131
  },
131
132
 
132
133
  attributes() {
133
- return {
134
- ...(this.collapsible && {
135
- onClick: this.onClick
136
- })
137
- }
134
+ return this.collapsible ? { onClick: this.onClick } : {}
138
135
  },
139
136
 
140
137
  isActive() {
@@ -60,14 +60,12 @@
60
60
  :store="store"
61
61
  :disabled="disabled"
62
62
  )
63
- vue-draggable(
63
+ use-sortable(
64
64
  v-if="childrenSchema"
65
65
  v-show="opened"
66
66
  :modelValue="updateOrder(childrenSchema, childrenList)"
67
67
  @update:modelValue="value => childrenList = value"
68
- @start="onStartDrag"
69
- @end="onEndDrag($event, childrenSchema)"
70
- v-bind="getDragOptions(childrenDraggable, true)"
68
+ :options="getSortableOptions(childrenDraggable, true)"
71
69
  )
72
70
  dito-tree-item(
73
71
  v-for="(item, index) in childrenItems"
@@ -152,17 +150,15 @@
152
150
  </style>
153
151
 
154
152
  <script>
155
- import { VueDraggable } from 'vue-draggable-plus'
156
153
  import DitoComponent from '../DitoComponent.js'
157
- import OrderedMixin from '../mixins/OrderedMixin.js'
154
+ import SortableMixin from '../mixins/SortableMixin.js'
158
155
  import { appendDataPath } from '../utils/data.js'
159
156
  import { getSchemaAccessor } from '../utils/accessor.js'
160
157
  import { getNamedSchemas, hasFormSchema } from '../utils/schema.js'
161
158
 
162
159
  // @vue/component
163
160
  export default DitoComponent.component('dito-tree-item', {
164
- components: { VueDraggable },
165
- mixins: [OrderedMixin],
161
+ mixins: [SortableMixin],
166
162
  inject: ['container'],
167
163
 
168
164
  props: {
@@ -245,19 +245,6 @@ export default {
245
245
  }
246
246
  },
247
247
 
248
- getDragOptions(draggable, fallback = false) {
249
- return {
250
- animation: 150,
251
- disabled: !draggable,
252
- handle: '.dito-button-drag',
253
- dragClass: 'dito-drag-active',
254
- chosenClass: 'dito-drag-chosen',
255
- ghostClass: 'dito-drag-ghost',
256
- fallbackClass: 'dito-drag-fallback',
257
- forceFallback: fallback
258
- }
259
- },
260
-
261
248
  // TODO: Rename *Link() to *Route().
262
249
  getQueryLink(query) {
263
250
  return {
@@ -1,7 +1,9 @@
1
- import ItemMixin from '../mixins/ItemMixin.js'
1
+ import ItemMixin from './ItemMixin.js'
2
+ import { UseSortable } from '@vueuse/integrations/useSortable/component'
2
3
 
3
4
  // @vue/component
4
5
  export default {
6
+ components: { UseSortable },
5
7
  mixins: [ItemMixin],
6
8
 
7
9
  data() {
@@ -11,6 +13,21 @@ export default {
11
13
  },
12
14
 
13
15
  methods: {
16
+ getSortableOptions(draggable, fallback = false) {
17
+ return {
18
+ animation: 150,
19
+ disabled: !draggable,
20
+ handle: '.dito-button-drag',
21
+ dragClass: 'dito-sortable-active',
22
+ chosenClass: 'dito-sortable-chosen',
23
+ ghostClass: 'dito-sortable-ghost',
24
+ fallbackClass: 'dito-sortable-fallback',
25
+ forceFallback: fallback,
26
+ onStart: this.onStartDrag,
27
+ onEnd: this.onEndDrag
28
+ }
29
+ },
30
+
14
31
  onStartDrag() {
15
32
  this.dragging = true
16
33
  },
@@ -3,7 +3,7 @@ import ValidationMixin from './ValidationMixin.js'
3
3
  import { getSchemaAccessor } from '../utils/accessor.js'
4
4
  import { computeValue } from '../utils/schema.js'
5
5
  import { getItem, getParentItem } from '../utils/data.js'
6
- import { isString, asArray, camelize } from '@ditojs/utils'
6
+ import { isString, asArray } from '@ditojs/utils'
7
7
 
8
8
  // @vue/component
9
9
  export default {
@@ -156,10 +156,17 @@ export default {
156
156
  type: String
157
157
  }),
158
158
 
159
+ // @overridable
160
+ events() {
161
+ const { onFocus, onBlur, onInput, onChange } = this
162
+ return { onFocus, onBlur, onInput, onChange }
163
+ },
164
+
159
165
  attributes() {
160
166
  const { nativeField, textField } = this.$options
161
167
 
162
168
  const attributes = {
169
+ ...this.events,
163
170
  disabled: this.disabled
164
171
  }
165
172
 
@@ -176,25 +183,7 @@ export default {
176
183
  }
177
184
  }
178
185
 
179
- return {
180
- ...Object.fromEntries(
181
- Object.entries(this.$attrs).filter(([key]) => key.startsWith('on'))
182
- ),
183
- ...this.events,
184
- ...attributes
185
- }
186
- },
187
-
188
- events() {
189
- const events = this.getEvents()
190
- // Register callbacks for all provides non-recognized events,
191
- // assuming they are native events.
192
- // TODO: Move to vue3-style `on[A-Z]` event handlers naming that aren't
193
- // namespaced in `schema.events` once the transition is complete.
194
- for (const event of Object.keys(this.schema.events || {})) {
195
- events[`on${camelize(event, true)}`] ||= () => this.emitEvent(event)
196
- }
197
- return events
186
+ return attributes
198
187
  },
199
188
 
200
189
  validations() {
@@ -235,12 +224,6 @@ export default {
235
224
  }
236
225
  },
237
226
 
238
- // @overridable
239
- getEvents() {
240
- const { onFocus, onBlur, onInput, onChange } = this
241
- return { onFocus, onBlur, onInput, onChange }
242
- },
243
-
244
227
  // @overridable
245
228
  getValidations() {
246
229
  return null
@@ -1,4 +1,4 @@
1
- .dito-drag-fallback
1
+ .dito-sortable-fallback
2
2
  filter: drop-shadow(0 2px 4px $color-shadow)
3
3
 
4
4
  // Nested <td> need to also switch to `display: block` style during dragging
@@ -5,6 +5,6 @@
5
5
  @import '_pulldown'
6
6
  @import '_layout'
7
7
  @import '_scroll'
8
- @import '_drag'
8
+ @import '_sortable'
9
9
  @import '_table'
10
10
  @import '_notifications'
@@ -41,16 +41,17 @@ export default TypeComponent.register([
41
41
  closeForm: getSchemaAccessor('closeForm', {
42
42
  type: Boolean,
43
43
  default: false
44
- })
45
- },
44
+ }),
46
45
 
47
- methods: {
48
46
  // @override
49
- getEvents() {
47
+ events() {
50
48
  const { onFocus, onBlur, onClick } = this
51
49
  return { onFocus, onBlur, onClick }
52
- },
50
+ }
51
+
52
+ },
53
53
 
54
+ methods: {
54
55
  async submit(options) {
55
56
  return this.resourceComponent?.submit(this, options)
56
57
  },
@@ -38,13 +38,11 @@
38
38
  :columns="columns"
39
39
  :hasEditButtons="hasEditButtons"
40
40
  )
41
- vue-draggable(
41
+ use-sortable(
42
42
  tag="tbody"
43
43
  :modelValue="updateOrder(sourceSchema, listData, paginationRange)"
44
44
  @update:modelValue="value => listData = value"
45
- @start="onStartDrag"
46
- @end="onEndDrag"
47
- :v-bind="getDragOptions(draggable)"
45
+ :options="getSortableOptions(draggable)"
48
46
  )
49
47
  tr(
50
48
  v-for="item, index in listData"
@@ -176,11 +174,10 @@
176
174
  </style>
177
175
 
178
176
  <script>
179
- import { VueDraggable } from 'vue-draggable-plus'
180
177
  import TypeComponent from '../TypeComponent.js'
181
178
  import DitoContext from '../DitoContext.js'
182
179
  import SourceMixin from '../mixins/SourceMixin.js'
183
- import OrderedMixin from '../mixins/OrderedMixin.js'
180
+ import SortableMixin from '../mixins/SortableMixin.js'
184
181
  import {
185
182
  getNamedSchemas, getViewEditPath,
186
183
  resolveSchemaComponent, resolveSchemaComponents
@@ -191,8 +188,7 @@ import { pickBy, equals, hyphenate } from '@ditojs/utils'
191
188
 
192
189
  // @vue/component
193
190
  export default TypeComponent.register('list', {
194
- components: { VueDraggable },
195
- mixins: [SourceMixin, OrderedMixin],
191
+ mixins: [SourceMixin, SortableMixin],
196
192
 
197
193
  getSourceType(type) {
198
194
  // No need for transformation here. See TypeTreeList for details.
@@ -7,8 +7,6 @@
7
7
  )
8
8
  vue-multiselect(
9
9
  ref="element"
10
- v-model="selectedOptions"
11
- v-bind="attributes"
12
10
  :show-labels="false"
13
11
  :placeholder="placeholder"
14
12
  tag-placeholder="Press enter to add new tag",
@@ -25,9 +23,12 @@
25
23
  :clear-on-select="!searchFilter"
26
24
  :close-on-select="!stayOpen"
27
25
  :loading="isLoading"
28
- @open="populate = true"
26
+ @open="onOpen"
27
+ @close="onClose"
29
28
  @tag="onAddTag"
30
29
  @search-change="onSearchChange"
30
+ v-model="selectedOptions"
31
+ v-bind="attributes"
31
32
  )
32
33
  button.dito-button-clear.dito-button-overlay(
33
34
  type="button"
@@ -224,6 +225,7 @@
224
225
  <script>
225
226
  import TypeComponent from '../TypeComponent.js'
226
227
  import DitoContext from '../DitoContext.js'
228
+ import TypeMixin from '../mixins/TypeMixin.js'
227
229
  import OptionsMixin from '../mixins/OptionsMixin.js'
228
230
  import VueMultiselect from 'vue-multiselect'
229
231
  import { getSchemaAccessor } from '../utils/accessor.js'
@@ -329,6 +331,24 @@ export default TypeComponent.register('multiselect', {
329
331
  this.$refs.element.activate()
330
332
  },
331
333
 
334
+ onOpen() {
335
+ this.populate = true
336
+ },
337
+
338
+ onClose() {
339
+ // Since we don't fire blur events while the multiselect is open (see
340
+ // below), we need to do it here, when it's actually closed.
341
+ if (this.focused) {
342
+ this.onBlur()
343
+ }
344
+ },
345
+
346
+ onBlur() {
347
+ if (!this.$refs.element.isOpen) {
348
+ TypeMixin.methods.onBlur.call(this)
349
+ }
350
+ },
351
+
332
352
  onAddTag(tag) {
333
353
  const option = this.addTagOption(tag)
334
354
  if (option) {
@@ -2,7 +2,6 @@
2
2
  switch-button.dito-switch(
3
3
  ref="element"
4
4
  :id="dataPath"
5
- :sync="true"
6
5
  :labels="labels"
7
6
  v-model="value"
8
7
  v-bind="attributes"
@@ -12,12 +12,10 @@
12
12
  span Status
13
13
  th
14
14
  span
15
- vue-draggable(
15
+ use-sortable(
16
16
  tag="tbody"
17
- @start="onStartDrag"
18
- @end="onEndDrag"
19
17
  v-model="files"
20
- v-bind="getDragOptions(draggable)"
18
+ :options="getSortableOptions(draggable)"
21
19
  )
22
20
  tr(
23
21
  v-for="(file, index) in files"
@@ -107,21 +105,20 @@
107
105
  </style>
108
106
 
109
107
  <script>
110
- import VueUpload from 'vue-upload-component'
111
- import { VueDraggable } from 'vue-draggable-plus'
112
108
  import TypeComponent from '../TypeComponent.js'
113
109
  import DitoContext from '../DitoContext.js'
114
- import OrderedMixin from '../mixins/OrderedMixin.js'
110
+ import SortableMixin from '../mixins/SortableMixin.js'
115
111
  import parseFileSize from 'filesize-parser'
116
112
  import { getSchemaAccessor } from '../utils/accessor.js'
117
113
  import { formatFileSize } from '../utils/units.js'
118
114
  import { appendDataPath } from '../utils/data.js'
119
115
  import { isArray, asArray, escapeHtml } from '@ditojs/utils'
116
+ import VueUpload from 'vue-upload-component'
120
117
 
121
118
  // @vue/component
122
119
  export default TypeComponent.register('upload', {
123
- components: { VueUpload, VueDraggable },
124
- mixins: [OrderedMixin],
120
+ components: { VueUpload },
121
+ mixins: [SortableMixin],
125
122
 
126
123
  data() {
127
124
  return {