@radio-garden/ditojs-admin 2.85.2-0.5067ad799

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 (153) hide show
  1. package/README.md +180 -0
  2. package/dist/dito-admin.css +1 -0
  3. package/dist/dito-admin.es.js +12106 -0
  4. package/dist/dito-admin.umd.js +7 -0
  5. package/package.json +96 -0
  6. package/src/DitoAdmin.js +293 -0
  7. package/src/DitoComponent.js +34 -0
  8. package/src/DitoContext.js +318 -0
  9. package/src/DitoTypeComponent.js +42 -0
  10. package/src/DitoUser.js +12 -0
  11. package/src/appState.js +12 -0
  12. package/src/components/DitoAccount.vue +60 -0
  13. package/src/components/DitoAffix.vue +68 -0
  14. package/src/components/DitoAffixes.vue +200 -0
  15. package/src/components/DitoButtons.vue +80 -0
  16. package/src/components/DitoClipboard.vue +186 -0
  17. package/src/components/DitoContainer.vue +374 -0
  18. package/src/components/DitoCreateButton.vue +146 -0
  19. package/src/components/DitoDialog.vue +242 -0
  20. package/src/components/DitoDraggable.vue +117 -0
  21. package/src/components/DitoEditButtons.vue +135 -0
  22. package/src/components/DitoErrors.vue +83 -0
  23. package/src/components/DitoForm.vue +521 -0
  24. package/src/components/DitoFormInner.vue +26 -0
  25. package/src/components/DitoFormNested.vue +17 -0
  26. package/src/components/DitoHeader.vue +84 -0
  27. package/src/components/DitoLabel.vue +200 -0
  28. package/src/components/DitoMenu.vue +186 -0
  29. package/src/components/DitoNavigation.vue +40 -0
  30. package/src/components/DitoNotifications.vue +170 -0
  31. package/src/components/DitoPagination.vue +42 -0
  32. package/src/components/DitoPane.vue +334 -0
  33. package/src/components/DitoPanel.vue +256 -0
  34. package/src/components/DitoPanels.vue +61 -0
  35. package/src/components/DitoRoot.vue +524 -0
  36. package/src/components/DitoSchema.vue +846 -0
  37. package/src/components/DitoSchemaInlined.vue +97 -0
  38. package/src/components/DitoScopes.vue +76 -0
  39. package/src/components/DitoSidebar.vue +50 -0
  40. package/src/components/DitoSpinner.vue +95 -0
  41. package/src/components/DitoTableCell.vue +64 -0
  42. package/src/components/DitoTableHead.vue +121 -0
  43. package/src/components/DitoTabs.vue +103 -0
  44. package/src/components/DitoTrail.vue +124 -0
  45. package/src/components/DitoTreeItem.vue +420 -0
  46. package/src/components/DitoUploadFile.vue +199 -0
  47. package/src/components/DitoVNode.vue +14 -0
  48. package/src/components/DitoView.vue +143 -0
  49. package/src/components/index.js +42 -0
  50. package/src/directives/resize.js +83 -0
  51. package/src/index.js +1 -0
  52. package/src/mixins/ContextMixin.js +68 -0
  53. package/src/mixins/DataMixin.js +131 -0
  54. package/src/mixins/DitoMixin.js +591 -0
  55. package/src/mixins/DomMixin.js +29 -0
  56. package/src/mixins/EmitterMixin.js +158 -0
  57. package/src/mixins/ItemMixin.js +144 -0
  58. package/src/mixins/LoadingMixin.js +23 -0
  59. package/src/mixins/NumberMixin.js +118 -0
  60. package/src/mixins/OptionsMixin.js +304 -0
  61. package/src/mixins/PulldownMixin.js +63 -0
  62. package/src/mixins/ResourceMixin.js +398 -0
  63. package/src/mixins/RouteMixin.js +190 -0
  64. package/src/mixins/SchemaParentMixin.js +33 -0
  65. package/src/mixins/SortableMixin.js +49 -0
  66. package/src/mixins/SourceMixin.js +734 -0
  67. package/src/mixins/TextMixin.js +26 -0
  68. package/src/mixins/TypeMixin.js +280 -0
  69. package/src/mixins/ValidationMixin.js +119 -0
  70. package/src/mixins/ValidatorMixin.js +57 -0
  71. package/src/mixins/ValueMixin.js +31 -0
  72. package/src/styles/_base.scss +17 -0
  73. package/src/styles/_button.scss +191 -0
  74. package/src/styles/_imports.scss +3 -0
  75. package/src/styles/_info.scss +19 -0
  76. package/src/styles/_layout.scss +19 -0
  77. package/src/styles/_pulldown.scss +38 -0
  78. package/src/styles/_scroll.scss +13 -0
  79. package/src/styles/_settings.scss +88 -0
  80. package/src/styles/_table.scss +223 -0
  81. package/src/styles/_tippy.scss +45 -0
  82. package/src/styles/style.scss +9 -0
  83. package/src/types/DitoTypeButton.vue +143 -0
  84. package/src/types/DitoTypeCheckbox.vue +27 -0
  85. package/src/types/DitoTypeCheckboxes.vue +65 -0
  86. package/src/types/DitoTypeCode.vue +199 -0
  87. package/src/types/DitoTypeColor.vue +272 -0
  88. package/src/types/DitoTypeComponent.vue +31 -0
  89. package/src/types/DitoTypeComputed.vue +50 -0
  90. package/src/types/DitoTypeDate.vue +99 -0
  91. package/src/types/DitoTypeLabel.vue +23 -0
  92. package/src/types/DitoTypeList.vue +364 -0
  93. package/src/types/DitoTypeMarkup.vue +700 -0
  94. package/src/types/DitoTypeMultiselect.vue +522 -0
  95. package/src/types/DitoTypeNumber.vue +66 -0
  96. package/src/types/DitoTypeObject.vue +136 -0
  97. package/src/types/DitoTypePanel.vue +18 -0
  98. package/src/types/DitoTypeProgress.vue +40 -0
  99. package/src/types/DitoTypeRadio.vue +45 -0
  100. package/src/types/DitoTypeSection.vue +80 -0
  101. package/src/types/DitoTypeSelect.vue +133 -0
  102. package/src/types/DitoTypeSlider.vue +66 -0
  103. package/src/types/DitoTypeSpacer.vue +11 -0
  104. package/src/types/DitoTypeSwitch.vue +40 -0
  105. package/src/types/DitoTypeText.vue +101 -0
  106. package/src/types/DitoTypeTextarea.vue +48 -0
  107. package/src/types/DitoTypeTreeList.vue +193 -0
  108. package/src/types/DitoTypeUpload.vue +503 -0
  109. package/src/types/index.js +30 -0
  110. package/src/utils/SchemaGraph.js +147 -0
  111. package/src/utils/accessor.js +75 -0
  112. package/src/utils/agent.js +47 -0
  113. package/src/utils/data.js +92 -0
  114. package/src/utils/filter.js +266 -0
  115. package/src/utils/math.js +14 -0
  116. package/src/utils/options.js +48 -0
  117. package/src/utils/path.js +5 -0
  118. package/src/utils/resource.js +44 -0
  119. package/src/utils/route.js +53 -0
  120. package/src/utils/schema.js +1121 -0
  121. package/src/utils/type.js +81 -0
  122. package/src/utils/uid.js +15 -0
  123. package/src/utils/units.js +5 -0
  124. package/src/validators/_creditcard.js +6 -0
  125. package/src/validators/_decimals.js +11 -0
  126. package/src/validators/_domain.js +6 -0
  127. package/src/validators/_email.js +6 -0
  128. package/src/validators/_hostname.js +6 -0
  129. package/src/validators/_integer.js +6 -0
  130. package/src/validators/_max.js +6 -0
  131. package/src/validators/_min.js +6 -0
  132. package/src/validators/_password.js +5 -0
  133. package/src/validators/_range.js +6 -0
  134. package/src/validators/_required.js +9 -0
  135. package/src/validators/_url.js +6 -0
  136. package/src/validators/index.js +12 -0
  137. package/src/verbs.js +17 -0
  138. package/types/index.d.ts +3298 -0
  139. package/types/tests/admin.test-d.ts +27 -0
  140. package/types/tests/component-buttons.test-d.ts +44 -0
  141. package/types/tests/component-list.test-d.ts +159 -0
  142. package/types/tests/component-misc.test-d.ts +137 -0
  143. package/types/tests/component-object.test-d.ts +69 -0
  144. package/types/tests/component-section.test-d.ts +174 -0
  145. package/types/tests/component-select.test-d.ts +107 -0
  146. package/types/tests/components.test-d.ts +81 -0
  147. package/types/tests/context.test-d.ts +31 -0
  148. package/types/tests/fixtures.ts +24 -0
  149. package/types/tests/form.test-d.ts +109 -0
  150. package/types/tests/instance.test-d.ts +20 -0
  151. package/types/tests/schema-features.test-d.ts +402 -0
  152. package/types/tests/variance.test-d.ts +125 -0
  153. package/types/tests/view.test-d.ts +146 -0
@@ -0,0 +1,364 @@
1
+ <template lang="pug">
2
+ .dito-list(
3
+ v-if="isReady"
4
+ :id="dataPath"
5
+ )
6
+ .dito-list__header(
7
+ v-if="scopes || hasPagination"
8
+ )
9
+ DitoScopes(
10
+ v-if="scopes"
11
+ :query="query"
12
+ :scopes="scopes"
13
+ )
14
+ //- When there's only pagination without scopes, we need a good ol' spacer
15
+ //- div, for the layout not to break...
16
+ .dito-spacer(
17
+ v-else-if="hasPagination"
18
+ )
19
+ DitoPagination(
20
+ v-if="hasPagination"
21
+ :query="query"
22
+ :limit="paginate"
23
+ :total="total || 0"
24
+ )
25
+ table.dito-table(
26
+ :class=`{
27
+ 'dito-table--separators': isInlined,
28
+ 'dito-table--larger-padding': hasEditButtons && !isInlined,
29
+ 'dito-table--alternate-colors': !isInlined,
30
+ 'dito-table--even-count': hasEvenCount
31
+ }`
32
+ )
33
+ DitoTableHead(
34
+ v-if="columns"
35
+ :query="query"
36
+ :columns="columns"
37
+ :hasEditButtons="hasEditButtons"
38
+ )
39
+ DitoDraggable(
40
+ as="tbody"
41
+ :options="getDraggableOptions()"
42
+ :draggable="draggable"
43
+ :modelValue="updateOrder(sourceSchema, listData, paginationRange)"
44
+ @update:modelValue="value => (listData = value)"
45
+ )
46
+ tr(
47
+ v-for="(item, index) in listData"
48
+ :id="getDataPath(index)"
49
+ :key="getItemUid(schema, item)"
50
+ )
51
+ template(
52
+ v-if="columns"
53
+ )
54
+ template(
55
+ v-for="column in columns"
56
+ )
57
+ DitoTableCell(
58
+ v-if="shouldRenderSchema(column)"
59
+ :key="column.name"
60
+ :class="getCellClass(column)"
61
+ :cell="column"
62
+ :schema="schema"
63
+ :dataPath="getDataPath(index)"
64
+ :data="item"
65
+ :meta="nestedMeta"
66
+ :store="store"
67
+ :nested="false"
68
+ :disabled="disabled || isLoading"
69
+ )
70
+ template(
71
+ v-else
72
+ )
73
+ td
74
+ DitoSchemaInlined(
75
+ v-if="isInlined"
76
+ :label="getItemLabel(schema, item, { index, asObject: true })"
77
+ :schema="getItemFormSchema(schema, item, context)"
78
+ :dataPath="getDataPath(index)"
79
+ :data="item"
80
+ :meta="nestedMeta"
81
+ :store="getItemStore(schema, item, index)"
82
+ :disabled="disabled || isLoading"
83
+ :collapsed="collapsed"
84
+ :collapsible="collapsible"
85
+ :deletable="deletable"
86
+ :draggable="draggable"
87
+ :editable="editable"
88
+ :editPath="getEditPath(item, index)"
89
+ @delete="deleteItem(item, index)"
90
+ )
91
+ component(
92
+ v-else-if="schema.component"
93
+ :is="schema.component"
94
+ :dataPath="getDataPath(index)"
95
+ :data="item"
96
+ :nested="false"
97
+ )
98
+ span(
99
+ v-else-if="render"
100
+ v-html="render(getContext(item, index))"
101
+ )
102
+ span(
103
+ v-else
104
+ v-html="getItemLabel(schema, item, { index })"
105
+ )
106
+ td.dito-table__buttons(
107
+ v-if="hasCellEditButtons"
108
+ )
109
+ DitoEditButtons(
110
+ nested
111
+ :schema="getItemFormSchema(schema, item, context)"
112
+ :dataPath="getDataPath(index)"
113
+ :data="item"
114
+ :meta="nestedMeta"
115
+ :store="getItemStore(schema, item, index)"
116
+ :disabled="disabled || isLoading"
117
+ :deletable="deletable"
118
+ :draggable="draggable"
119
+ :editable="editable"
120
+ :editPath="getEditPath(item, index)"
121
+ @delete="deleteItem(item, index)"
122
+ )
123
+ //- Render create buttons inside table when not in a single component view:
124
+ tfoot(
125
+ v-if="hasListButtons && !single"
126
+ )
127
+ tr
128
+ td.dito-table__buttons(:colspan="numColumns")
129
+ DitoEditButtons(
130
+ :buttons="buttonSchemas"
131
+ :schema="schema"
132
+ :dataPath="dataPath"
133
+ :data="data"
134
+ :meta="meta"
135
+ :store="store"
136
+ :nested="nested"
137
+ :disabled="disabled || isLoading"
138
+ :creatable="creatable"
139
+ :createPath="createPath"
140
+ )
141
+ //- Render create buttons outside table when in a single component view:
142
+ DitoEditButtons.dito-buttons--large.dito-buttons--main.dito-buttons--sticky(
143
+ v-if="hasListButtons && single"
144
+ :buttons="buttonSchemas"
145
+ :schema="schema"
146
+ :dataPath="dataPath"
147
+ :data="listData"
148
+ :meta="meta"
149
+ :store="store"
150
+ :disabled="disabled || isLoading"
151
+ :creatable="creatable"
152
+ :createPath="createPath"
153
+ )
154
+ </template>
155
+
156
+ <script>
157
+ import DitoTypeComponent from '../DitoTypeComponent.js'
158
+ import DitoContext from '../DitoContext.js'
159
+ import SourceMixin from '../mixins/SourceMixin.js'
160
+ import SortableMixin from '../mixins/SortableMixin.js'
161
+ import {
162
+ getViewEditPath,
163
+ resolveSchemaComponent,
164
+ resolveSchemaComponents
165
+ } from '../utils/schema.js'
166
+ import { createFiltersPanel } from '../utils/filter.js'
167
+ import { appendDataPath } from '../utils/data.js'
168
+ import { pickBy, equals, hyphenate } from '@ditojs/utils'
169
+ import { computed } from 'vue'
170
+
171
+ // @vue/component
172
+ export default DitoTypeComponent.register('list', {
173
+ mixins: [SourceMixin, SortableMixin],
174
+
175
+ getSourceType(type) {
176
+ // No need for transformation here. See TypeTreeList for details.
177
+ return type
178
+ },
179
+
180
+ getPanelSchema(api, schema, dataPath, component) {
181
+ const { filters } = schema
182
+ // See if this list component wants to display a filter panel, and if so,
183
+ // create the panel schema for it through `getFiltersPanel()`.
184
+ if (filters) {
185
+ return createFiltersPanel(
186
+ api,
187
+ filters,
188
+ dataPath,
189
+ // Pass a computed value to get / set the query, see getFiltersPanel()
190
+ computed({
191
+ get() {
192
+ return component.query
193
+ },
194
+
195
+ set(query) {
196
+ // Filter out undefined values for comparing with equals()
197
+ const filter = obj => pickBy(obj, value => value !== undefined)
198
+ if (!equals(filter(query), filter(component.query))) {
199
+ component.query = query
200
+ component.loadData(false)
201
+ }
202
+ }
203
+ })
204
+ )
205
+ }
206
+ },
207
+
208
+ computed: {
209
+ hasPagination() {
210
+ return !!this.paginate
211
+ },
212
+
213
+ hasListButtons() {
214
+ return !!(this.buttonSchemas || this.creatable)
215
+ },
216
+
217
+ hasEditButtons() {
218
+ const { listData } = this
219
+ return (
220
+ listData.length > 0 && (
221
+ this.editable ||
222
+ this.deletable ||
223
+ this.draggable
224
+ )
225
+ )
226
+ },
227
+
228
+ hasCellEditButtons() {
229
+ return !this.isInlined && this.hasEditButtons
230
+ },
231
+
232
+ hasEvenCount() {
233
+ return !(this.listData.length % 2)
234
+ },
235
+
236
+ numColumns() {
237
+ return (
238
+ (this.columns ? Object.keys(this.columns).length : 1) +
239
+ (this.hasCellEditButtons ? 1 : 0)
240
+ )
241
+ }
242
+ },
243
+
244
+ methods: {
245
+ getDataPath(index) {
246
+ return appendDataPath(this.dataPath, index)
247
+ },
248
+
249
+ getEditPath(item, index) {
250
+ if (this.editable) {
251
+ const id = this.getItemId(this.schema, item, index)
252
+ return (
253
+ getViewEditPath(this.schema, id, this.context) ||
254
+ `${this.path}/${id}`
255
+ )
256
+ }
257
+ return null
258
+ },
259
+
260
+ getCellClass(column) {
261
+ return `dito-cell--${hyphenate(column.name)}`
262
+ },
263
+
264
+ getContext(item, index) {
265
+ return new DitoContext(this, {
266
+ data: item,
267
+ value: item,
268
+ index,
269
+ dataPath: this.getDataPath(index)
270
+ })
271
+ },
272
+
273
+ onFilterErrors(errors) {
274
+ const filtersDataPath = appendDataPath(this.dataPath, '$filters')
275
+ const panel = this.schemaComponent.getPanelByDataPath(filtersDataPath)
276
+ if (panel) {
277
+ panel.showValidationErrors(errors, true)
278
+ return true
279
+ }
280
+ }
281
+ },
282
+
283
+ async processSchema(
284
+ api,
285
+ schema,
286
+ name,
287
+ routes,
288
+ level,
289
+ nested = false,
290
+ flatten = false,
291
+ process = null
292
+ ) {
293
+ await Promise.all([
294
+ resolveSchemaComponent(schema),
295
+ resolveSchemaComponents(schema.columns),
296
+ SourceMixin.processSchema(
297
+ api,
298
+ schema,
299
+ name,
300
+ routes,
301
+ level,
302
+ nested,
303
+ flatten,
304
+ process
305
+ )
306
+ ])
307
+ }
308
+ })
309
+ </script>
310
+
311
+ <style lang="scss">
312
+ @import '../styles/_imports';
313
+
314
+ .dito-list {
315
+ $self: &;
316
+
317
+ position: relative;
318
+
319
+ &__header {
320
+ display: flex;
321
+ justify-content: space-between;
322
+ padding-bottom: $content-padding-half;
323
+ @include user-select(none);
324
+
325
+ &:empty {
326
+ display: none;
327
+ }
328
+
329
+ .dito-scopes,
330
+ .dito-pagination {
331
+ display: flex;
332
+ flex: 0 1 auto;
333
+ min-width: 0;
334
+ }
335
+ }
336
+
337
+ &.dito-component--single {
338
+ // So that list buttons can be sticky to the bottom:
339
+ display: grid;
340
+ grid-template-rows: min-content;
341
+ height: 100%;
342
+
343
+ // Make single list header, navigation and buttons sticky to the top and
344
+ // bottom:
345
+ #{$self}__header {
346
+ position: sticky;
347
+ top: 0;
348
+ margin-top: -$content-padding;
349
+ padding-top: $content-padding;
350
+ background: $content-color-background;
351
+ z-index: 1;
352
+
353
+ + .dito-table {
354
+ .dito-table-head {
355
+ position: sticky;
356
+ top: calc($input-height + $content-padding + $content-padding-half);
357
+ background: $content-color-background;
358
+ z-index: 1;
359
+ }
360
+ }
361
+ }
362
+ }
363
+ }
364
+ </style>