@ditojs/admin 1.29.0 → 2.0.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.
Files changed (79) hide show
  1. package/dist/dito-admin.es.js +5295 -6852
  2. package/dist/dito-admin.umd.js +5 -5
  3. package/dist/style.css +1 -1
  4. package/package.json +37 -22
  5. package/src/DitoAdmin.js +44 -58
  6. package/src/DitoComponent.js +18 -50
  7. package/src/DitoContext.js +7 -3
  8. package/src/TypeComponent.js +15 -13
  9. package/src/appState.js +4 -2
  10. package/src/components/DitoAccount.vue +14 -14
  11. package/src/components/DitoButtons.vue +18 -10
  12. package/src/components/DitoClipboard.vue +16 -16
  13. package/src/components/DitoContainer.vue +32 -32
  14. package/src/components/DitoCreateButton.vue +22 -23
  15. package/src/components/DitoDialog.vue +73 -18
  16. package/src/components/DitoEditButtons.vue +31 -31
  17. package/src/components/DitoElement.vue +6 -6
  18. package/src/components/DitoErrors.vue +6 -6
  19. package/src/components/DitoForm.vue +42 -43
  20. package/src/components/DitoFormNested.vue +7 -3
  21. package/src/components/DitoHeader.vue +19 -19
  22. package/src/components/DitoLabel.vue +25 -25
  23. package/src/components/DitoMenu.vue +9 -9
  24. package/src/components/DitoPagination.vue +5 -5
  25. package/src/components/DitoPane.vue +32 -32
  26. package/src/components/DitoPanel.vue +18 -18
  27. package/src/components/DitoPanels.vue +5 -3
  28. package/src/components/DitoRoot.vue +107 -30
  29. package/src/components/DitoSchema.vue +76 -74
  30. package/src/components/DitoSchemaInlined.vue +33 -30
  31. package/src/components/DitoScopes.vue +14 -13
  32. package/src/components/DitoSpinner.vue +101 -0
  33. package/src/components/DitoTableCell.vue +19 -25
  34. package/src/components/DitoTableHead.vue +10 -7
  35. package/src/components/DitoTabs.vue +7 -6
  36. package/src/components/DitoTreeItem.vue +89 -85
  37. package/src/components/DitoVNode.vue +9 -7
  38. package/src/components/DitoView.vue +25 -21
  39. package/src/mixins/DataMixin.js +2 -2
  40. package/src/mixins/DitoMixin.js +43 -46
  41. package/src/mixins/DomMixin.js +1 -1
  42. package/src/mixins/EmitterMixin.js +11 -11
  43. package/src/mixins/ItemMixin.js +7 -5
  44. package/src/mixins/RouteMixin.js +20 -10
  45. package/src/mixins/SchemaParentMixin.js +2 -2
  46. package/src/mixins/SourceMixin.js +7 -9
  47. package/src/mixins/TypeMixin.js +29 -34
  48. package/src/mixins/ValidationMixin.js +4 -19
  49. package/src/types/TypeButton.vue +11 -15
  50. package/src/types/TypeCheckbox.vue +7 -8
  51. package/src/types/TypeCheckboxes.vue +14 -15
  52. package/src/types/TypeCode.vue +5 -5
  53. package/src/types/TypeColor.vue +9 -12
  54. package/src/types/TypeComponent.vue +12 -7
  55. package/src/types/TypeComputed.vue +13 -12
  56. package/src/types/TypeDate.vue +10 -11
  57. package/src/types/TypeLabel.vue +1 -1
  58. package/src/types/TypeList.vue +115 -92
  59. package/src/types/TypeMarkup.vue +166 -125
  60. package/src/types/TypeMultiselect.vue +37 -47
  61. package/src/types/TypeNumber.vue +10 -11
  62. package/src/types/TypeObject.vue +72 -46
  63. package/src/types/TypeProgress.vue +7 -8
  64. package/src/types/TypeRadio.vue +15 -14
  65. package/src/types/TypeSection.vue +10 -10
  66. package/src/types/TypeSelect.vue +32 -33
  67. package/src/types/TypeSlider.vue +20 -22
  68. package/src/types/TypeSwitch.vue +8 -9
  69. package/src/types/TypeText.vue +7 -8
  70. package/src/types/TypeTextarea.vue +8 -9
  71. package/src/types/TypeTreeList.vue +40 -34
  72. package/src/types/TypeUpload.vue +61 -61
  73. package/src/utils/accessor.js +1 -1
  74. package/src/utils/data.js +0 -4
  75. package/src/utils/options.js +48 -0
  76. package/src/utils/path.js +5 -0
  77. package/src/utils/schema.js +73 -56
  78. package/src/utils/vue.js +11 -0
  79. package/types/index.d.ts +1 -1
@@ -1,36 +1,36 @@
1
1
  <template lang="pug">
2
- .dito-pane(
3
- v-if="isPopulated && componentSchemas.length > 0"
4
- v-show="visible"
2
+ .dito-pane(
3
+ v-if="isPopulated && componentSchemas.length > 0"
4
+ v-show="visible"
5
+ )
6
+ template(
7
+ v-for=`{
8
+ schema,
9
+ dataPath,
10
+ nestedDataPath,
11
+ nested,
12
+ store
13
+ } in componentSchemas`
5
14
  )
6
- template(
7
- v-for=`{
8
- schema,
9
- dataPath,
10
- nestedDataPath,
11
- nested,
12
- store
13
- } in componentSchemas`
15
+ .dito-break(
16
+ v-if="schema.break === 'before'"
17
+ )
18
+ dito-container(
19
+ v-if="shouldRender(schema)"
20
+ :key="nestedDataPath"
21
+ :schema="schema"
22
+ :dataPath="dataPath"
23
+ :data="data"
24
+ :meta="meta"
25
+ :store="store"
26
+ :single="isSingleComponent"
27
+ :nested="nested"
28
+ :disabled="disabled"
29
+ :generateLabels="generateLabels"
30
+ )
31
+ .dito-break(
32
+ v-if="schema.break === 'after'"
14
33
  )
15
- .dito-break(
16
- v-if="schema.break === 'before'"
17
- )
18
- dito-container(
19
- v-if="shouldRender(schema)"
20
- :key="nestedDataPath"
21
- :schema="schema"
22
- :dataPath="dataPath"
23
- :data="data"
24
- :meta="meta"
25
- :store="store"
26
- :single="isSingleComponent"
27
- :nested="nested"
28
- :disabled="disabled"
29
- :generateLabels="generateLabels"
30
- )
31
- .dito-break(
32
- v-if="schema.break === 'after'"
33
- )
34
34
  </template>
35
35
 
36
36
  <style lang="sass">
@@ -149,7 +149,7 @@ export default DitoComponent.component('dito-pane', {
149
149
  this._register(true)
150
150
  },
151
151
 
152
- beforeDestroy() {
152
+ beforeUnmount() {
153
153
  this._register(false)
154
154
  },
155
155
 
@@ -160,7 +160,7 @@ export default DitoComponent.component('dito-pane', {
160
160
 
161
161
  focus() {
162
162
  if (this.tab) {
163
- this.$router.push({ hash: this.tab })
163
+ this.$router.push({ hash: `#${this.tab}` })
164
164
  }
165
165
  }
166
166
  }
@@ -1,22 +1,22 @@
1
1
  <template lang="pug">
2
- // Only show panels in tabs when the tabs are also visible.
3
- component.dito-panel(
4
- :is="panelTag"
5
- v-show="visible && (!panelTabComponent || panelTabComponent.visible)"
6
- @submit.prevent
2
+ //- Only show panels in tabs when the tabs are also visible.
3
+ component.dito-panel(
4
+ :is="panelTag"
5
+ v-show="visible && (!panelTabComponent || panelTabComponent.visible)"
6
+ @submit.prevent
7
+ )
8
+ label.dito-panel-title {{ getLabel(schema) }}
9
+ dito-schema.dito-panel-schema(
10
+ :schema="panelSchema"
11
+ :dataPath="panelDataPath"
12
+ :data="panelData"
13
+ :meta="meta"
14
+ :store="store"
15
+ :disabled="disabled"
16
+ :hasOwnData="hasOwnData"
7
17
  )
8
- label.dito-panel-title {{ getLabel(schema) }}
9
- dito-schema.dito-panel-schema(
10
- :schema="panelSchema"
11
- :dataPath="panelDataPath"
12
- :data="panelData"
13
- :meta="meta"
14
- :store="store"
15
- :disabled="disabled"
16
- :hasOwnData="hasOwnData"
17
- )
18
+ template(#buttons)
18
19
  dito-buttons(
19
- slot="buttons"
20
20
  :buttons="buttonSchemas"
21
21
  :dataPath="panelDataPath"
22
22
  :data="panelData"
@@ -89,7 +89,7 @@ export default DitoComponent.component('dito-panel', {
89
89
  meta: { type: Object, required: true },
90
90
  store: { type: Object, required: true },
91
91
  disabled: { type: Boolean, required: true },
92
- panelTabComponent: { type: DitoComponent, default: null }
92
+ panelTabComponent: { type: Object, default: null }
93
93
  },
94
94
 
95
95
  data() {
@@ -164,7 +164,7 @@ export default DitoComponent.component('dito-panel', {
164
164
  }
165
165
  },
166
166
 
167
- beforeDestroy() {
167
+ beforeUnmount() {
168
168
  this._register(false)
169
169
  },
170
170
 
@@ -1,9 +1,11 @@
1
1
  <template lang="pug">
2
- .dito-panels(
3
- v-if="panels.length > 0"
2
+ .dito-panels(
3
+ v-if="panels.length > 0"
4
+ )
5
+ template(
6
+ v-for="{ schema, dataPath, tabComponent } in panels"
4
7
  )
5
8
  dito-panel(
6
- v-for="{ schema, dataPath, tabComponent } in panels"
7
9
  v-if="shouldRender(schema)"
8
10
  :key="getPanelKey(dataPath, tabComponent)"
9
11
  :schema="schema"
@@ -1,33 +1,48 @@
1
1
  <template lang="pug">
2
- .dito-root
3
- notifications.dito-notifications(
4
- ref="notifications"
5
- position="top right"
6
- classes="dito-notification"
2
+ .dito-root
3
+ vue-notifications.dito-notifications(
4
+ ref="notifications"
5
+ position="top right"
6
+ classes="dito-notification"
7
+ )
8
+ transition-group(name="dito-dialog")
9
+ dito-dialog(
10
+ v-for="(dialog, key) in dialogs"
11
+ :key="key"
12
+ :components="dialog.components"
13
+ :buttons="dialog.buttons"
14
+ :promise="dialog.promise"
15
+ :data="dialog.data"
16
+ :settings="dialog.settings"
17
+ @remove="removeDialog(key)"
18
+ )
19
+ dito-menu
20
+ main.dito-page.dito-scroll-parent
21
+ dito-header(
22
+ :spinner="options.spinner"
23
+ :isLoading="isLoading"
7
24
  )
8
- dito-menu
9
- main.dito-page.dito-scroll-parent
10
- dito-header(
11
- :spinner="options.spinner"
12
- :isLoading="isLoading"
25
+ dito-account(
26
+ v-if="user"
27
+ )
28
+ a.dito-login(
29
+ v-else-if="allowLogin"
30
+ @click="rootComponent.login()"
13
31
  )
14
- dito-account(
15
- v-if="user"
16
- )
17
- a.dito-login(
18
- v-else-if="allowLogin"
19
- @click="rootComponent.login()"
20
- )
21
- span Login
22
- router-view
32
+ span Login
33
+ router-view
23
34
  </template>
24
35
 
25
36
  <style lang="sass">
26
37
  @import '../styles/style'
27
38
 
39
+ .dito-app,
28
40
  .dito-root
41
+ width: 100%
29
42
  height: 100%
30
43
  display: flex
44
+
45
+ .dito-root
31
46
  .dito-page
32
47
  background: $content-color-background
33
48
  // The root-level views and forms may have a `.dito-schema-header` that
@@ -41,15 +56,19 @@
41
56
  </style>
42
57
 
43
58
  <script>
44
- import { asArray, stripTags } from '@ditojs/utils'
59
+ import { asArray, mapConcurrently, stripTags } from '@ditojs/utils'
45
60
  import DitoComponent from '../DitoComponent.js'
46
61
  import DitoUser from '../DitoUser.js'
47
62
  import DitoView from '../components/DitoView.vue'
63
+ import DitoDialog from './DitoDialog.vue'
48
64
  import DomMixin from '../mixins/DomMixin.js'
49
- import { processView, resolveSchemas } from '../utils/schema.js'
65
+ import {
66
+ processView, resolveSchemas, processSchemaComponents
67
+ } from '../utils/schema.js'
50
68
 
51
69
  // @vue/component
52
70
  export default DitoComponent.component('dito-root', {
71
+ components: { DitoDialog },
53
72
  mixins: [DomMixin],
54
73
 
55
74
  provide() {
@@ -66,6 +85,8 @@ export default DitoComponent.component('dito-root', {
66
85
  data() {
67
86
  return {
68
87
  resolvedViews: {},
88
+ removeRoutes: null,
89
+ dialogs: {},
69
90
  allowLogin: false,
70
91
  loadingCount: 0
71
92
  }
@@ -156,6 +177,37 @@ export default DitoComponent.component('dito-root', {
156
177
  this.loadingCount += isLoading ? 1 : -1
157
178
  },
158
179
 
180
+ showDialog({ components, buttons, data, settings }) {
181
+ // Shows a dito-dialog component and wraps it in a promise so that the
182
+ // buttons in the dialog can use `dialog.resolve()` and `dialog.reject()`
183
+ // to close the modal dialog and resolve / reject the promise at once.
184
+ return new Promise(
185
+ // eslint-disable-next-line no-async-promise-executor
186
+ async (resolve, reject) => {
187
+ // Process components to resolve async schemas.
188
+ const routes = []
189
+ await processSchemaComponents(this.api, { components }, routes, 0)
190
+ if (routes.length > 0) {
191
+ throw new Error(
192
+ `Dialog components cannot contain routes, only components with schemas.`
193
+ )
194
+ }
195
+ const key = `dialog-${++dialogId}`
196
+ this.dialogs[key] = {
197
+ components,
198
+ buttons,
199
+ data,
200
+ settings,
201
+ promise: { resolve, reject }
202
+ }
203
+ }
204
+ )
205
+ },
206
+
207
+ removeDialog(key) {
208
+ delete this.dialogs[key]
209
+ },
210
+
159
211
  async login() {
160
212
  this.allowLogin = true
161
213
  const {
@@ -272,16 +324,41 @@ export default DitoComponent.component('dito-root', {
272
324
  return this.login()
273
325
  }
274
326
  // Collect all routes from the root schema components
275
- const routes = []
276
- const promises = []
277
- for (const [name, schema] of Object.entries(this.resolvedViews)) {
278
- promises.push(processView(DitoView, this.api, schema, name, routes))
279
- }
280
- await Promise.all(promises)
281
- for (const route of routes) {
282
- this.$router.addRoute(route)
283
- }
327
+ const routes = await mapConcurrently(
328
+ Object.entries(this.resolvedViews),
329
+ ([name, schema]) => processView(DitoView, this.api, schema, name)
330
+ )
331
+ // Now that the routes are loaded, replace all existing routes with the
332
+ // new routes, and restore the current path.
333
+ const { fullPath } = this.$route
334
+ this.removeRoutes?.()
335
+ this.removeRoutes = addRoutes(this.$router, [
336
+ {
337
+ name: 'root',
338
+ path: '/',
339
+ components: {}
340
+ },
341
+ ...routes
342
+ ])
343
+ this.$router.replace(fullPath)
284
344
  }
285
345
  }
346
+
286
347
  })
348
+
349
+ let dialogId = 0
350
+
351
+ function addRoutes(router, routes) {
352
+ const removers = []
353
+ for (const route of routes) {
354
+ const removeRoute = router.addRoute(route)
355
+ removers.push(removeRoute)
356
+ }
357
+
358
+ return () => {
359
+ for (const remove of removers) {
360
+ remove()
361
+ }
362
+ }
363
+ }
287
364
  </script>
@@ -1,82 +1,82 @@
1
1
  <template lang="pug">
2
- .dito-schema
3
- .dito-schema-content
4
- .dito-schema-header(
5
- v-if="hasLabel || hasTabs || clipboard"
6
- :class="{ 'dito-schema-menu-header': menuHeader }"
7
- )
8
- dito-label(
9
- v-if="hasLabel"
10
- :label="label"
11
- :dataPath="dataPath"
12
- :collapsible="collapsible"
13
- :collapsed="!opened"
14
- @expand="onExpand"
15
- )
16
- // Pass edit-buttons through to dito-label's own edit-buttons slot:
17
- template(
18
- #edit-buttons
19
- v-if="inlined"
20
- )
21
- slot(name="edit-buttons")
22
- dito-tabs(
23
- v-if="tabs"
24
- :tabs="tabs"
25
- :selectedTab="selectedTab"
26
- )
27
- dito-clipboard(
28
- :clipboard="clipboard"
29
- :dataPath="dataPath"
30
- :data="data"
31
- )
32
- dito-pane.dito-pane-tab(
33
- v-if="hasTabs"
34
- v-for="(schema, tab) in tabs"
35
- ref="tabs"
36
- :key="tab"
37
- :visible="selectedTab === tab"
38
- :tab="tab"
39
- :schema="schema"
2
+ .dito-schema
3
+ .dito-schema-content
4
+ .dito-schema-header(
5
+ v-if="hasLabel || hasTabs || clipboard"
6
+ :class="{ 'dito-schema-menu-header': menuHeader }"
7
+ )
8
+ dito-label(
9
+ v-if="hasLabel"
10
+ :label="label"
40
11
  :dataPath="dataPath"
41
- :data="data"
42
- :meta="meta"
43
- :store="store"
44
- :single="!inlined && !hasMainPane"
45
- :disabled="disabled"
46
- :generateLabels="generateLabels"
12
+ :collapsible="collapsible"
13
+ :collapsed="!opened"
14
+ @expand="onExpand"
47
15
  )
48
- transition-height(
49
- :enabled="inlined"
50
- )
51
- dito-pane.dito-pane-main(
52
- v-if="hasMainPane && opened"
53
- ref="components"
54
- :schema="schema"
55
- :dataPath="dataPath"
56
- :data="data"
57
- :meta="meta"
58
- :store="store"
59
- :single="!inlined && !hasTabs"
60
- :disabled="disabled"
61
- :generateLabels="generateLabels"
16
+ //- Pass edit-buttons through to dito-label's own edit-buttons slot:
17
+ template(
18
+ #edit-buttons
19
+ v-if="inlined"
62
20
  )
63
- slot(
64
- name="buttons"
65
- v-if="!inlined && isPopulated"
21
+ slot(name="edit-buttons")
22
+ dito-tabs(
23
+ v-if="tabs"
24
+ :tabs="tabs"
25
+ :selectedTab="selectedTab"
66
26
  )
67
- template(v-if="inlined")
68
- slot(
69
- v-if="!hasLabel"
70
- name="edit-buttons"
27
+ dito-clipboard(
28
+ :clipboard="clipboard"
29
+ :dataPath="dataPath"
30
+ :data="data"
71
31
  )
72
- template(v-else-if="isPopulated")
73
- dito-panels(
74
- :panels="panelSchemas"
32
+ dito-pane.dito-pane-tab(
33
+ v-if="hasTabs"
34
+ v-for="(schema, tab) in tabs"
35
+ ref="tabs"
36
+ :key="tab"
37
+ :visible="selectedTab === tab"
38
+ :tab="tab"
39
+ :schema="schema"
40
+ :dataPath="dataPath"
41
+ :data="data"
42
+ :meta="meta"
43
+ :store="store"
44
+ :single="!inlined && !hasMainPane"
45
+ :disabled="disabled"
46
+ :generateLabels="generateLabels"
47
+ )
48
+ transition-height(
49
+ :enabled="inlined"
50
+ )
51
+ dito-pane.dito-pane-main(
52
+ v-if="hasMainPane && opened"
53
+ ref="components"
54
+ :schema="schema"
55
+ :dataPath="dataPath"
75
56
  :data="data"
76
57
  :meta="meta"
77
58
  :store="store"
59
+ :single="!inlined && !hasTabs"
78
60
  :disabled="disabled"
61
+ :generateLabels="generateLabels"
79
62
  )
63
+ slot(
64
+ v-if="!inlined && isPopulated"
65
+ name="buttons"
66
+ )
67
+ template(v-if="inlined")
68
+ slot(
69
+ v-if="!hasLabel"
70
+ name="edit-buttons"
71
+ )
72
+ template(v-else-if="isPopulated")
73
+ dito-panels(
74
+ :panels="panelSchemas"
75
+ :data="data"
76
+ :meta="meta"
77
+ :store="store"
78
+ :disabled="disabled"
79
+ )
80
80
  </template>
81
81
 
82
82
  <style lang="sass">
@@ -220,7 +220,7 @@ export default DitoComponent.component('dito-schema', {
220
220
  // Don't return the actual parent schema is this schema handles its own
221
221
  // data. This prevents delegating events to the parent, and registering
222
222
  // components with the parent that would cause it to set isDirty flags.
223
- return this.hasOwnData ? null : this.$parent.schemaComponent
223
+ return this.hasOwnData ? null : this.parentComponent.schemaComponent
224
224
  },
225
225
 
226
226
  panelSchemas() {
@@ -241,8 +241,9 @@ export default DitoComponent.component('dito-schema', {
241
241
  ? currentTab
242
242
  : this.defaultTab?.name || null
243
243
  if (tab !== currentTab) {
244
+ // TODO: Move this watcher!
244
245
  // Any tab change needs to be reflected in the router also.
245
- this.$router.replace({ hash: tab })
246
+ this.$router.replace({ hash: `#${tab}` })
246
247
  }
247
248
  return tab
248
249
  },
@@ -385,7 +386,7 @@ export default DitoComponent.component('dito-schema', {
385
386
  this.emitEvent('initialize') // Not `'create'`, since that's for data.
386
387
  },
387
388
 
388
- beforeDestroy() {
389
+ beforeUnmount() {
389
390
  this.emitEvent('destroy')
390
391
  this._register(false)
391
392
  },
@@ -616,7 +617,8 @@ export default DitoComponent.component('dito-schema', {
616
617
  setData(data) {
617
618
  for (const name in data) {
618
619
  if (name in this.data) {
619
- this.$set(this.data, name, data[name])
620
+ // eslint-disable-next-line vue/no-mutating-props
621
+ this.data[name] = data[name]
620
622
  for (const component of this.getComponentsByName(name)) {
621
623
  component.markDirty()
622
624
  }
@@ -679,9 +681,9 @@ export default DitoComponent.component('dito-schema', {
679
681
  _registerEntry(registry, entry, add) {
680
682
  const uid = entry.$uid
681
683
  if (add) {
682
- this.$set(registry, uid, entry)
684
+ registry[uid] = entry
683
685
  } else {
684
- this.$delete(registry, uid)
686
+ delete registry[uid]
685
687
  }
686
688
  },
687
689
 
@@ -1,33 +1,33 @@
1
1
  <template lang="pug">
2
- dito-schema.dito-schema-inlined(
3
- :schema="schema"
4
- :dataPath="dataPath"
5
- :data="data"
6
- :meta="meta"
7
- :store="store"
8
- :label="isCompact ? null : label"
9
- :inlined="true"
10
- :disabled="disabled"
11
- :collapsed="collapsed"
12
- :collapsible="collapsible"
13
- :class="{ 'dito-schema-compact': isCompact }"
14
- )
15
- // Render dito-edit-buttons for inlined schemas separately from all
16
- // others in `TypeList` as a scope, for better handling of layout.
17
- template(#edit-buttons)
18
- dito-edit-buttons(
19
- v-if="deletable || draggable || editable"
20
- :deletable="deletable"
21
- :draggable="draggable"
22
- :editable="editable"
23
- :editPath="editPath"
24
- :schema="schema"
25
- :dataPath="dataPath"
26
- :data="data"
27
- :meta="meta"
28
- :store="store"
29
- @delete="$emit('delete')"
30
- )
2
+ dito-schema.dito-schema-inlined(
3
+ :schema="schema"
4
+ :dataPath="dataPath"
5
+ :data="data"
6
+ :meta="meta"
7
+ :store="store"
8
+ :label="isCompact ? null : label"
9
+ :inlined="true"
10
+ :disabled="disabled"
11
+ :collapsed="collapsed"
12
+ :collapsible="collapsible"
13
+ :class="{ 'dito-schema-compact': isCompact }"
14
+ )
15
+ //- Render dito-edit-buttons for inlined schemas separately from all
16
+ //- others in `TypeList` as a scope, for better handling of layout.
17
+ template(#edit-buttons)
18
+ dito-edit-buttons(
19
+ v-if="deletable || draggable || editable"
20
+ :deletable="deletable"
21
+ :draggable="draggable"
22
+ :editable="editable"
23
+ :editPath="editPath"
24
+ :schema="schema"
25
+ :dataPath="dataPath"
26
+ :data="data"
27
+ :meta="meta"
28
+ :store="store"
29
+ @delete="$emit('delete')"
30
+ )
31
31
  </template>
32
32
 
33
33
  <style lang="sass">
@@ -44,9 +44,12 @@
44
44
  --label-padding: #{$form-spacing}
45
45
  margin: 0
46
46
  width: 100%
47
- box-sizing: border-box
47
+ box-sizing: content-box
48
48
  // Because tables have a funny way of allowing too much width growth:
49
49
  max-width: $content-width
50
+ // Prevent collapsing to min-height when alone in
51
+ // .dito-schema-content, due to grid-template-rows: min-content
52
+ min-height: 2em
50
53
  & +.dito-pane
51
54
  // Needed for transition-height in DitoSchema:
52
55
  min-height: $form-spacing
@@ -1,17 +1,18 @@
1
1
  <template lang="pug">
2
- .dito-scopes
3
- router-link(
4
- v-for="(scope, key) in scopes"
5
- :key="key"
6
- :to="getScopeLink(scope)"
7
- custom v-slot="{ navigate }"
8
- )
9
- button.dito-button(
10
- type="button"
11
- :class="{ 'dito-selected': scope.name === query.scope }"
12
- :title="scope.hint || getLabel(scope)"
13
- @click="navigate"
14
- ) {{ getLabel(scope) }}
2
+ .dito-scopes
3
+ router-link(
4
+ v-for="(scope, key) in scopes"
5
+ :key="key"
6
+ :to="getScopeLink(scope)"
7
+ custom
8
+ v-slot="{ navigate }"
9
+ )
10
+ button.dito-button(
11
+ type="button"
12
+ :class="{ 'dito-selected': scope.name === query.scope }"
13
+ :title="scope.hint || getLabel(scope)"
14
+ @click="navigate"
15
+ ) {{ getLabel(scope) }}
15
16
  </template>
16
17
 
17
18
  <style lang="sass">