apostrophe 4.7.2 → 4.8.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +32 -2
  2. package/index.js +1 -1
  3. package/lib/moog.js +1 -1
  4. package/modules/@apostrophecms/admin-bar/index.js +61 -2
  5. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBreakpointPreviewMode.vue +166 -0
  6. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextTitle.vue +25 -0
  7. package/modules/@apostrophecms/area/ui/apos/components/AposAreaEditor.vue +3 -12
  8. package/modules/@apostrophecms/asset/index.js +41 -1
  9. package/modules/@apostrophecms/asset/lib/globalIcons.js +6 -0
  10. package/modules/@apostrophecms/asset/lib/webpack/apos/webpack.scss.js +16 -16
  11. package/modules/@apostrophecms/asset/lib/webpack/media-to-container-queries-loader.js +94 -0
  12. package/modules/@apostrophecms/asset/lib/webpack/src/webpack.scss.js +12 -0
  13. package/modules/@apostrophecms/attachment/index.js +8 -1
  14. package/modules/@apostrophecms/command-menu/ui/apos/components/AposCommandMenuKey.vue +1 -1
  15. package/modules/@apostrophecms/command-menu/ui/apos/components/AposCommandMenuShortcut.vue +5 -2
  16. package/modules/@apostrophecms/doc-type/ui/apos/components/AposDocEditor.vue +1 -19
  17. package/modules/@apostrophecms/i18n/i18n/en.json +12 -1
  18. package/modules/@apostrophecms/image/ui/apos/components/AposMediaUploader.vue +9 -18
  19. package/modules/@apostrophecms/migration/index.js +20 -13
  20. package/modules/@apostrophecms/migration/lib/addMissingSchemaFields.js +182 -0
  21. package/modules/@apostrophecms/page/index.js +4 -0
  22. package/modules/@apostrophecms/piece-type/ui/apos/components/AposRelationshipEditor.vue +2 -7
  23. package/modules/@apostrophecms/rich-text-widget/index.js +66 -0
  24. package/modules/@apostrophecms/schema/index.js +20 -29
  25. package/modules/@apostrophecms/schema/lib/addFieldTypes.js +2 -27
  26. package/modules/@apostrophecms/schema/lib/newInstance.js +36 -0
  27. package/modules/@apostrophecms/schema/ui/apos/components/AposInputArray.vue +238 -80
  28. package/modules/@apostrophecms/schema/ui/apos/components/AposInputWrapper.vue +34 -24
  29. package/modules/@apostrophecms/schema/ui/apos/logic/AposArrayEditor.js +2 -7
  30. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputArray.js +207 -44
  31. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputRelationship.js +3 -14
  32. package/modules/@apostrophecms/schema/ui/apos/scss/AposInputArray.scss +288 -105
  33. package/modules/@apostrophecms/template/views/outerLayoutBase.html +1 -0
  34. package/modules/@apostrophecms/ui/ui/apos/components/AposButton.vue +2 -1
  35. package/modules/@apostrophecms/ui/ui/apos/components/AposContextMenu.vue +9 -6
  36. package/modules/@apostrophecms/ui/ui/apos/components/AposContextMenuDialog.vue +8 -6
  37. package/modules/@apostrophecms/ui/ui/apos/components/AposContextMenuItem.vue +52 -51
  38. package/modules/@apostrophecms/ui/ui/apos/components/AposFile.vue +16 -6
  39. package/modules/@apostrophecms/ui/ui/apos/components/AposIndicator.vue +1 -0
  40. package/modules/@apostrophecms/ui/ui/apos/components/AposLocalePicker.vue +6 -4
  41. package/modules/@apostrophecms/ui/ui/apos/components/AposSlatList.vue +6 -2
  42. package/modules/@apostrophecms/ui/ui/apos/components/AposTagApply.vue +8 -6
  43. package/modules/@apostrophecms/ui/ui/apos/scss/global/_breakpoint_preview.scss +38 -0
  44. package/modules/@apostrophecms/ui/ui/apos/scss/global/_tables.scss +3 -1
  45. package/modules/@apostrophecms/ui/ui/apos/scss/global/import-all.scss +1 -0
  46. package/modules/@apostrophecms/widget-type/ui/apos/components/AposWidgetEditor.vue +2 -13
  47. package/package.json +3 -2
  48. package/test/add-missing-schema-fields.js +323 -0
  49. package/test/pages.js +10 -0
@@ -339,16 +339,7 @@ module.exports = (self) => {
339
339
  }
340
340
  },
341
341
  choices: async function () {
342
- const values = await query.toDistinct(field.name);
343
- const choices = _.map(values, function (value) {
344
- const choice = _.find(field.choices, { value: value });
345
- return {
346
- value: value,
347
- label: choice && (choice.label || value)
348
- };
349
- });
350
- self.apos.util.insensitiveSortByProperty(choices, 'label');
351
- return choices;
342
+ return self.getChoicesForQueryBuilder(field, query);
352
343
  }
353
344
  });
354
345
  },
@@ -408,23 +399,7 @@ module.exports = (self) => {
408
399
  }
409
400
  },
410
401
  choices: async function () {
411
- let allChoices;
412
- const values = await query.toDistinct(field.name);
413
- if ((typeof field.choices) === 'string') {
414
- const req = self.apos.task.getReq();
415
- allChoices = await self.apos.modules[field.moduleName][field.choices](req);
416
- } else {
417
- allChoices = field.choices;
418
- }
419
- const choices = _.map(values, function (value) {
420
- const choice = _.find(allChoices, { value: value });
421
- return {
422
- value: value,
423
- label: choice && (choice.label || value)
424
- };
425
- });
426
- self.apos.util.insensitiveSortByProperty(choices, 'label');
427
- return choices;
402
+ return self.getChoicesForQueryBuilder(field, query);
428
403
  }
429
404
  });
430
405
  }
@@ -0,0 +1,36 @@
1
+ const { klona } = require('klona');
2
+ const { createId } = require('@paralleldrive/cuid2');
3
+
4
+ module.exports = newInstance;
5
+
6
+ function newInstance(schema) {
7
+ const instance = {};
8
+ for (const field of schema) {
9
+ if (field.def !== undefined) {
10
+ instance[field.name] = klona(field.def);
11
+ } else {
12
+ // All fields should have an initial value in the database
13
+ instance[field.name] = null;
14
+ }
15
+ // A workaround specifically for areas. They must have a
16
+ // unique `_id` which makes `klona` a poor way to establish
17
+ // a default, and we don't pass functions in schema
18
+ // definitions, but top-level areas should always exist
19
+ // for reasonable results if the output of `newInstance`
20
+ // is saved without further editing on the front end
21
+ if ((field.type === 'area') && (!instance[field.name])) {
22
+ instance[field.name] = {
23
+ metaType: 'area',
24
+ items: [],
25
+ _id: createId()
26
+ };
27
+ }
28
+ // A workaround specifically for objects. These too need
29
+ // to have reasonable values in parked pages and any other
30
+ // situation where the data never passes through the UI
31
+ if ((field.type === 'object') && ((!instance[field.name]) || (Object.keys(instance[field.name]).length === 0))) {
32
+ instance[field.name] = newInstance(field.schema);
33
+ }
34
+ }
35
+ return instance;
36
+ }
@@ -1,74 +1,90 @@
1
1
  <template>
2
2
  <AposInputWrapper
3
+ ref="root"
3
4
  :field="field"
4
5
  :error="effectiveError"
5
6
  :uid="uid"
6
7
  :items="next"
7
8
  :display-options="displayOptions"
8
- :modifiers="[
9
- ...field.style === 'table' ? ['full-width'] : []
10
- ]"
9
+ :modifiers="[...(isInlineTable ? ['full-width'] : [])]"
11
10
  :meta="arrayMeta"
12
11
  >
13
12
  <template #additional>
14
- <AposMinMaxCount
15
- :field="field"
16
- :model-value="next"
17
- />
13
+ <AposMinMaxCount :field="field" :model-value="next" />
14
+ </template>
15
+ <template v-if="isInlineStandard" #meta>
16
+ <div class="apos-input-array-inline-all-controls">
17
+ <AposButton
18
+ class="apos-input-array-inline-all-control apos-input-array-inline-all-control--expand"
19
+ label="apostrophe:expandAll"
20
+ type="subtle"
21
+ :modifiers="['inline', 'no-motion']"
22
+ @click="toggleAll(true)"
23
+ />
24
+ <AposButton
25
+ class="apos-input-array-inline-all-control apos-input-array-inline-all-control--collapse"
26
+ label="apostrophe:collapseAll"
27
+ type="subtle"
28
+ :modifiers="['inline', 'no-motion']"
29
+ @click="toggleAll(false)"
30
+ />
31
+ </div>
18
32
  </template>
19
33
  <template #body>
20
- <div v-if="field.inline">
21
- <div
22
- v-if="!items.length && field.whenEmpty"
23
- class="apos-input-array-inline-empty"
24
- >
25
- <component
26
- :is="field.whenEmpty.icon"
27
- v-if="field.whenEmpty.icon"
28
- :size="50"
29
- />
30
- <label
31
- v-if="field.whenEmpty.label"
32
- class="apos-input-array-inline-empty-label"
33
- >
34
- {{ $t(field.whenEmpty.label) }}
35
- </label>
36
- </div>
34
+ <div
35
+ v-if="(isInlineStandard || isInlineTable) && !items.length"
36
+ class="apos-input-array-inline-empty"
37
+ >
37
38
  <component
38
- :is="field.style === 'table' ? 'table' : 'div'"
39
- v-if="items.length"
40
- :class="field.style === 'table' ? 'apos-input-array-inline-table' : 'apos-input-array-inline-standard'"
41
- >
42
- <thead
43
- v-if="field.style === 'table'"
44
- >
45
- <th class="apos-table-cell--hidden" />
39
+ :is="emptyWhenIcon"
40
+ :size="50"
41
+ />
42
+ <label class="apos-input-array-inline-empty-label">
43
+ {{ $t(emptyWhenLabel) }}
44
+ </label>
45
+ </div>
46
+
47
+ <!-- INLINE TABLE -->
48
+ <div v-if="isInlineTable">
49
+ <table v-if="items.length" class="apos-input-array-inline-table">
50
+ <thead class="apos-input-array-inline-table-header">
51
+ <th v-if="isDraggable" class="apos-input-array-inline-table-header-cell" />
46
52
  <th
47
53
  v-for="subfield in visibleSchema()"
48
54
  :key="subfield._id"
55
+ class="apos-input-array-inline-table-header-cell"
56
+ :class="getTableHeaderClass(subfield, 'apos-input-array-inline-table-header-cell')"
49
57
  :style="subfield.columnStyle || {}"
50
58
  >
51
59
  {{ $t(subfield.label) }}
52
60
  </th>
53
- <th />
61
+ <th class="apos-input-array-inline-table-header-cell" />
54
62
  </thead>
55
63
  <draggable
56
64
  :id="listId"
57
65
  item-key="_id"
58
- class="apos-input-array-inline"
59
66
  role="list"
67
+ :class="{ 'apos-input-array-inline-array--is-dragging': isDragging }"
60
68
  :options="dragOptions"
61
- :tag="field.style === 'table' ? 'tbody' : 'div'"
69
+ tag="tbody"
62
70
  :list="items"
63
71
  @update="moveUpdate"
72
+ @start="startDragging"
73
+ @end="stopDragging"
64
74
  >
65
- <template #item="{element: item, index}">
75
+ <template #item="{ element: item, index }">
66
76
  <AposSchema
67
77
  :key="item._id"
68
78
  v-model="item.schemaInput"
69
- class="apos-input-array-inline-item"
79
+ :data-id="item._id"
80
+ :tabindex="isDraggable ? '0' : '-1'"
81
+ class="apos-input-array-inline-table-row"
82
+ data-apos-input-array-inline-item
70
83
  :meta="arrayMeta[item._id]?.aposMeta"
71
- :class="item.open && !alwaysExpand ? 'apos-input-array-inline-item--active' : null"
84
+ :class="{
85
+ 'apos-input-array-inline-table-row--active': item.open,
86
+ 'apos-input-array-inline-table-row--engaged': item.engaged
87
+ }"
72
88
  :schema="schema"
73
89
  :trigger-validation="triggerValidation"
74
90
  :generation="generation"
@@ -76,69 +92,194 @@
76
92
  :doc-id="docId"
77
93
  :following-values="getFollowingValues(item)"
78
94
  :conditional-fields="itemsConditionalFields[item._id]"
79
- :field-style="field.style"
95
+ field-style="table"
80
96
  @update:model-value="setItemsConditionalFields(item._id)"
81
97
  @validate="emitValidate()"
98
+ @keydown.space="isDraggable ? toggleEngage($event, { exact: true, prevent: true }) : {}"
99
+ @keydown.enter="isDraggable ? toggleEngage($event, { exact: true, prevent: true }) : {}"
100
+ @keydown.arrow-up="isDraggable ? moveEngaged($event, item._id, -1, { prevent: true }) : {}"
101
+ @keydown.arrow-down="isDraggable ? moveEngaged($event, item._id, 1, { prevent: true }) : {}"
82
102
  >
83
103
  <template #before>
84
- <component
85
- :is="field.style === 'table' ? 'td' : 'div'"
86
- class="apos-input-array-inline-item-controls"
87
- :style="(field.style === 'table' && field.columnStyle) || {}"
104
+ <td
105
+ v-if="isDraggable"
106
+ class="apos-input-array-inline-table-cell apos-input-array-inline-table-cell--controls"
107
+ :style="field.columnStyle"
88
108
  >
89
109
  <AposIndicator
90
- v-if="field.draggable"
91
110
  icon="drag-icon"
92
- class="apos-drag-handle"
111
+ class="apos-input-array-inline-table-cell-drag-handle apos-drag-handle"
112
+ :decorative="false"
113
+ @keydown.prevent.space="toggleEngage($event, item._id)"
114
+ @keydown.prevent.enter="toggleEngage($event, item._id)"
93
115
  />
94
- <AposButton
95
- v-if="field.style !== 'table' && item.open && !alwaysExpand"
96
- class="apos-input-array-inline-collapse"
97
- :icon-size="15"
98
- label="apostrophe:close"
99
- icon="unfold-less-horizontal-icon"
100
- type="subtle"
101
- :modifiers="['inline', 'no-motion']"
102
- :icon-only="true"
103
- @click="closeInlineItem(item._id)"
104
- />
105
- </component>
106
- <h3
107
- v-if="field.style !== 'table' && !item.open && !alwaysExpand"
108
- class="apos-input-array-inline-label"
109
- @click="openInlineItem(item._id)"
110
- >
111
- {{ getLabel(item._id, index) }}
112
- </h3>
116
+ </td>
113
117
  </template>
114
118
  <template #after>
115
- <component
116
- :is="field.style === 'table' ? 'td' : 'div'"
117
- class="apos-input-array-inline-item-controls--remove"
118
- >
119
+ <td class="apos-input-array-inline-table-cell apos-input-array-inline-table-cell--controls apos-input-array-inline-table-cell--controls--menu">
120
+ <AposContextMenu
121
+ v-if="getInlineMenuItems(index).length > 1"
122
+ ref="menu"
123
+ data-apos-input-array-inline-item-menu
124
+ class=""
125
+ :button="{
126
+ label: 'apostrophe:moreOperations',
127
+ iconOnly: true,
128
+ icon: 'dots-vertical-icon',
129
+ type: 'subtle',
130
+ modifiers: ['small', 'no-motion'],
131
+ }"
132
+ :menu="getInlineMenuItems(index)"
133
+ menu-placement="bottom-end"
134
+ @keydown.space="$event.stopImmediatePropagation()"
135
+ @keydown.enter="$event.stopImmediatePropagation()"
136
+ @item-clicked="
137
+ inlineMenuHandler($event, { index, id: item._id })
138
+ "
139
+ />
119
140
  <AposButton
141
+ v-else
142
+ data-apos-input-array-inline-item-remove
120
143
  label="apostrophe:removeItem"
121
144
  icon="close-icon"
122
145
  type="subtle"
123
- :modifiers="['inline','no-motion']"
146
+ :modifiers="['inline', 'no-motion']"
124
147
  :icon-only="true"
125
148
  @click="remove(item._id)"
126
149
  />
127
- </component>
150
+ </td>
128
151
  </template>
129
152
  </AposSchema>
130
153
  </template>
131
154
  </draggable>
132
- </component>
133
- <AposButton
134
- type="primary"
135
- :label="itemLabel"
136
- icon="plus-icon"
137
- :disabled="disableAdd()"
138
- :modifiers="['block']"
139
- @click="add"
140
- />
155
+ </table>
141
156
  </div>
157
+
158
+ <!-- INLINE STANDARD-->
159
+ <div v-else-if="field.inline">
160
+ <draggable
161
+ :id="listId"
162
+ item-key="_id"
163
+ class="apos-input-array-inline-standard"
164
+ :class="{ 'apos-input-array-inline-array--is-dragging': isDragging }"
165
+ role="list"
166
+ :options="dragOptions"
167
+ tag="div"
168
+ :list="items"
169
+ @update="moveUpdate"
170
+ @start="startDragging"
171
+ @end="stopDragging"
172
+ >
173
+ <template #item="{ element: item, index }">
174
+ <div
175
+ :key="item._id"
176
+ class="apos-input-array-inline-item"
177
+ data-apos-input-array-inline-item
178
+ :data-id="item._id"
179
+ tabindex="0"
180
+ :aria-pressed="item.engaged"
181
+ role="listitem"
182
+ :class="{
183
+ 'apos-input-array-inline-item--open': item.open,
184
+ 'apos-input-array-inline-item--engaged': item.engaged,
185
+ 'apos-input-array-inline-item--drag-disabled': !isDraggable,
186
+ }"
187
+ @keydown.prevent.exact.space="isDraggable ? toggleOpenInlineItem($event) : {}"
188
+ @keydown.prevent.shift.space="isDraggable ? toggleEngage($event, item._id) : {}"
189
+ @keydown.prevent.enter="isDraggable ? toggleEngage($event, item._id) : {}"
190
+ @keydown.prevent.arrow-up="isDraggable ? moveEngaged($event, item._id, -1) : {}"
191
+ @keydown.prevent.arrow-down="isDraggable ? moveEngaged($event, item._id, 1) : {}"
192
+ >
193
+ <div
194
+ class="apos-input-array-inline-header"
195
+ @dblclick="toggleOpenInlineItem($event)"
196
+ >
197
+ <div
198
+ class="apos-input-array-inline-header-ui apos-input-array-inline-header-ui--left"
199
+ >
200
+ <AposIndicator
201
+ v-if="isDraggable"
202
+ icon="drag-icon"
203
+ class="apos-input-array-inline-header-ui-element"
204
+ />
205
+ <div class="apos-input-array-inline-label">
206
+ {{ getLabel(item._id, index) }}
207
+ </div>
208
+ </div>
209
+ <div
210
+ class="apos-input-array-inline-header-ui apos-input-array-inline-header-ui--right"
211
+ >
212
+ <AposButton
213
+ class="apos-input-array-inline-header-ui-element apos-input-array-inline-collapse"
214
+ :icon-size="16"
215
+ label="apostrophe:close"
216
+ :tooltip="item.open ? 'Collapse item' : 'Expand item'"
217
+ :icon="
218
+ item.open
219
+ ? 'arrow-collapse-vertical-icon'
220
+ : 'arrow-expand-vertical-icon'
221
+ "
222
+ type="subtle"
223
+ :modifiers="['inline', 'no-motion']"
224
+ :icon-only="true"
225
+ @click="toggleOpenInlineItem($event)"
226
+ @keydown.space="$event.stopImmediatePropagation()"
227
+ @keydown.enter="$event.stopImmediatePropagation()"
228
+ />
229
+ <AposContextMenu
230
+ ref="menu"
231
+ class="apos-input-array-inline-header-ui-element"
232
+ data-apos-input-array-inline-item-menu
233
+ :button="{
234
+ label: 'apostrophe:moreOperations',
235
+ iconOnly: true,
236
+ icon: 'dots-vertical-icon',
237
+ type: 'subtle',
238
+ modifiers: ['small', 'no-motion'],
239
+ }"
240
+ :menu="getInlineMenuItems(index)"
241
+ menu-placement="bottom-end"
242
+ @keydown.space="$event.stopImmediatePropagation()"
243
+ @keydown.enter="$event.stopImmediatePropagation()"
244
+ @item-clicked="
245
+ inlineMenuHandler($event, { index, id: item._id })
246
+ "
247
+ />
248
+ </div>
249
+ </div>
250
+ <transition name="collapse">
251
+ <div v-show="item.open" class="apos-input-array-inline-body">
252
+ <AposSchema
253
+ :key="item._id"
254
+ v-model="item.schemaInput"
255
+ :data-apos-id="item._id"
256
+ class="apos-input-array-inline-schema"
257
+ :meta="arrayMeta[item._id]?.aposMeta"
258
+ :class="
259
+ item.open
260
+ ? 'apos-input-array-inline-item--active'
261
+ : null
262
+ "
263
+ :schema="schema"
264
+ :trigger-validation="triggerValidation"
265
+ :generation="generation"
266
+ :modifiers="['small', 'inverted']"
267
+ :doc-id="docId"
268
+ :following-values="getFollowingValues(item)"
269
+ :conditional-fields="itemsConditionalFields[item._id]"
270
+ :field-style="field.style"
271
+ @update:model-value="setItemsConditionalFields(item._id)"
272
+ @validate="emitValidate()"
273
+ @keydown.space="$event.stopImmediatePropagation()"
274
+ @keydown.enter="$event.stopImmediatePropagation()"
275
+ />
276
+ </div>
277
+ </transition>
278
+ </div>
279
+ </template>
280
+ </draggable>
281
+ </div>
282
+
142
283
  <div v-else class="apos-input-array">
143
284
  <label class="apos-input-wrapper">
144
285
  <AposButton
@@ -149,6 +290,18 @@
149
290
  />
150
291
  </label>
151
292
  </div>
293
+
294
+ <!-- INLINE ADD BUTTON -->
295
+ <AposButton
296
+ v-if="isInlineStandard || isInlineTable"
297
+ type="primary"
298
+ class="apos-input-array-inline-add-button"
299
+ :label="itemLabel"
300
+ icon="plus-icon"
301
+ :disabled="isAddDisabled"
302
+ :modifiers="['block']"
303
+ @click="add"
304
+ />
152
305
  </template>
153
306
  </AposInputWrapper>
154
307
  </template>
@@ -166,5 +319,10 @@ export default {
166
319
  };
167
320
  </script>
168
321
 
169
- <style lang="scss" src="../scss/AposInputArray.scss" scoped>
322
+ <style lang="scss" src="../scss/AposInputArray.scss" scoped></style>
323
+ <style lang="scss">
324
+ .apos-is-dragging td {
325
+ flex: 1;
326
+ background-color: var(--a-background-primary);
327
+ }
170
328
  </style>
@@ -3,7 +3,7 @@
3
3
  class="apos-field__wrapper"
4
4
  :class="{
5
5
  [`apos-field__wrapper--${field.type}`]: true,
6
- 'apos-field__wrapper--full-width': modifiers.includes('full-width')
6
+ 'apos-field__wrapper--full-width': modifiers.includes('full-width'),
7
7
  }"
8
8
  >
9
9
  <component :is="wrapEl" :class="classList">
@@ -14,7 +14,8 @@
14
14
  class="apos-field__label"
15
15
  :class="{
16
16
  'apos-sr-only': field.hideLabel,
17
- 'apos-field__label--meta-left': field.meta && field.meta.position === 'left',
17
+ 'apos-field__label--meta-left':
18
+ field.meta && field.meta.position === 'left',
18
19
  }"
19
20
  :for="uid"
20
21
  :data-apos-test-name="field.name"
@@ -24,17 +25,21 @@
24
25
  <span class="apos-field_label-info">
25
26
  {{ $t(label) }}
26
27
  <span v-if="field.required" class="apos-field__required">
27
- *
28
- </span>
28
+ * </span>
29
29
  <AposLabel
30
30
  v-if="field.tag"
31
31
  class="apos-field__tag"
32
32
  :label="field.tag.value || field.tag"
33
- :modifiers="[ `apos-is-${field.tag.type || 'success'}`, 'apos-is-filled' ]"
33
+ :modifiers="[
34
+ `apos-is-${field.tag.type || 'success'}`,
35
+ 'apos-is-filled',
36
+ ]"
34
37
  data-apos-test="field-tag"
35
38
  />
36
39
  <span
37
- v-if="(field.help || field.htmlHelp) && displayOptions.helpTooltip"
40
+ v-if="
41
+ (field.help || field.htmlHelp) && displayOptions.helpTooltip
42
+ "
38
43
  data-apos-test="field-help-tooltip"
39
44
  class="apos-field__help-tooltip"
40
45
  >
@@ -54,26 +59,31 @@
54
59
  <AposLabel
55
60
  label="apostrophe:changed"
56
61
  class="apos-field__changed__label"
57
- :modifiers="[ 'apos-is-warning', 'apos-is-filled' ]"
62
+ :modifiers="['apos-is-warning', 'apos-is-filled']"
58
63
  tooltip="apostrophe:fieldHasUnpublishedChanges"
59
64
  />
60
65
  </span>
61
66
  </span>
62
- <span data-apos-test="field-meta-wrapper" class="apos-field__label-meta">
63
- <component
64
- :is="name"
65
- v-for="{name, namespace, data} in metaComponents"
66
- :key="name"
67
- :field="field"
68
- :items="items"
69
- :namespace="namespace"
70
- :meta="data"
71
- :meta-raw="meta"
72
- :data-apos-test-component="name"
73
- :data-apos-test-namespace="namespace"
74
- data-apos-test="field-meta"
75
- @replace-field-value="replaceFieldValue"
76
- />
67
+ <span
68
+ data-apos-test="field-meta-wrapper"
69
+ class="apos-field__label-meta"
70
+ >
71
+ <slot name="meta">
72
+ <component
73
+ :is="name"
74
+ v-for="{ name, namespace, data } in metaComponents"
75
+ :key="name"
76
+ :field="field"
77
+ :items="items"
78
+ :namespace="namespace"
79
+ :meta="data"
80
+ :meta-raw="meta"
81
+ :data-apos-test-component="name"
82
+ :data-apos-test-namespace="namespace"
83
+ data-apos-test="field-meta"
84
+ @replace-field-value="replaceFieldValue"
85
+ />
86
+ </slot>
77
87
  </span>
78
88
  </component>
79
89
  <!-- eslint-disable vue/no-v-html -->
@@ -131,7 +141,8 @@ export default {
131
141
  border-width: 0;
132
142
  padding: 0;
133
143
 
134
- [disable]:hover, [disabled] ~ .apos-choice-label-text:hover {
144
+ [disable]:hover,
145
+ [disabled] ~ .apos-choice-label-text:hover {
135
146
  cursor: not-allowed;
136
147
  }
137
148
  }
@@ -263,5 +274,4 @@ export default {
263
274
  }
264
275
  }
265
276
  }
266
-
267
277
  </style>
@@ -4,6 +4,7 @@ import { createId } from '@paralleldrive/cuid2';
4
4
  import { klona } from 'klona';
5
5
  import { get } from 'lodash';
6
6
  import { detectDocChange } from 'Modules/@apostrophecms/schema/lib/detectChange';
7
+ import newInstance from 'apostrophe/modules/@apostrophecms/schema/lib/newInstance.js';
7
8
 
8
9
  export default {
9
10
  name: 'AposArrayEditor',
@@ -281,13 +282,7 @@ export default {
281
282
  }
282
283
  },
283
284
  newInstance() {
284
- const instance = {};
285
- for (const field of this.schema) {
286
- if (field.def !== undefined) {
287
- instance[field.name] = klona(field.def);
288
- }
289
- }
290
- return instance;
285
+ return newInstance(this.schema);
291
286
  },
292
287
  label(item) {
293
288
  let candidate;