apostrophe 3.53.0 → 3.55.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/CHANGELOG.md +58 -1
- package/defaults.js +1 -0
- package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextModeAndSettings.vue +5 -2
- package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextTitle.vue +28 -19
- package/modules/@apostrophecms/any-doc-type/index.js +2 -2
- package/modules/@apostrophecms/any-page-type/index.js +2 -2
- package/modules/@apostrophecms/doc/index.js +55 -29
- package/modules/@apostrophecms/doc-type/index.js +11 -6
- package/modules/@apostrophecms/doc-type/ui/apos/components/AposDocContextMenu.vue +4 -440
- package/modules/@apostrophecms/doc-type/ui/apos/logic/AposDocContextMenu.js +445 -0
- package/modules/@apostrophecms/i18n/i18n/de.json +113 -105
- package/modules/@apostrophecms/i18n/i18n/es.json +10 -0
- package/modules/@apostrophecms/i18n/i18n/fr.json +8 -0
- package/modules/@apostrophecms/i18n/i18n/pt-BR.json +10 -0
- package/modules/@apostrophecms/i18n/i18n/sk.json +8 -0
- package/modules/@apostrophecms/image/ui/apos/components/AposMediaManager.vue +1 -0
- package/modules/@apostrophecms/log/index.js +429 -0
- package/modules/@apostrophecms/login/index.js +47 -4
- package/modules/@apostrophecms/modal/ui/apos/components/AposDocsManagerToolbar.vue +14 -1
- package/modules/@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js +1 -1
- package/modules/@apostrophecms/module/index.js +32 -6
- package/modules/@apostrophecms/module/lib/log.js +68 -0
- package/modules/@apostrophecms/page/index.js +71 -19
- package/modules/@apostrophecms/page/lib/legacy-migrations.js +0 -57
- package/modules/@apostrophecms/page/ui/apos/components/AposPagesManager.vue +8 -285
- package/modules/@apostrophecms/page/ui/apos/logic/AposPagesManager.js +291 -0
- package/modules/@apostrophecms/page-type/index.js +39 -26
- package/modules/@apostrophecms/piece-type/index.js +19 -11
- package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManager.vue +1 -0
- package/modules/@apostrophecms/schema/ui/apos/components/AposArrayEditor.vue +2 -357
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputArea.vue +2 -86
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputArray.vue +2 -254
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputAttachment.vue +2 -77
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputBoolean.vue +2 -44
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputCheckboxes.vue +2 -64
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputColor.vue +2 -94
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputDateAndTime.vue +3 -47
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputObject.vue +2 -82
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputPassword.vue +2 -37
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputRadio.vue +2 -26
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputRange.vue +2 -57
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputRelationship.vue +2 -259
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputSelect.vue +2 -38
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputSlug.vue +2 -275
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputString.vue +2 -167
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputWrapper.vue +2 -115
- package/modules/@apostrophecms/schema/ui/apos/components/AposSchema.vue +3 -279
- package/modules/@apostrophecms/schema/ui/apos/components/AposSearchList.vue +2 -83
- package/modules/@apostrophecms/schema/ui/apos/lib/detectChange.js +10 -1
- package/modules/@apostrophecms/schema/ui/apos/logic/AposArrayEditor.js +361 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputArea.js +89 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputArray.js +257 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputAttachment.js +81 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputBoolean.js +48 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputCheckboxes.js +68 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputColor.js +98 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputDateAndTime.js +49 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputObject.js +86 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputPassword.js +41 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputRadio.js +29 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputRange.js +60 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputRelationship.js +262 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputSelect.js +41 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputSlug.js +278 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputString.js +170 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputWrapper.js +118 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposSchema.js +281 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposSearchList.js +85 -0
- package/modules/@apostrophecms/template/index.js +1 -1
- package/modules/@apostrophecms/ui/ui/apos/components/AposTreeHeader.vue +2 -2
- package/modules/@apostrophecms/util/index.js +83 -13
- package/modules/@apostrophecms/util/lib/logger.js +19 -17
- package/package.json +1 -1
- package/test/docs.js +35 -2
- package/test/log.js +1765 -0
- package/test/pages.js +57 -0
- package/test-lib/util.js +1 -1
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
>
|
|
30
30
|
<slot name="before" />
|
|
31
31
|
<component
|
|
32
|
-
v-for="field in schema" :key="field.name"
|
|
32
|
+
v-for="field in schema" :key="field.name.concat(field._id ?? '')"
|
|
33
33
|
:data-apos-field="field.name"
|
|
34
34
|
:is="fieldStyle === 'table' ? 'td' : 'div'"
|
|
35
35
|
v-show="displayComponent(field)"
|
|
@@ -56,286 +56,10 @@
|
|
|
56
56
|
</template>
|
|
57
57
|
|
|
58
58
|
<script>
|
|
59
|
-
import
|
|
60
|
-
|
|
59
|
+
import AposSchemaLogic from '../logic/AposSchema';
|
|
61
60
|
export default {
|
|
62
61
|
name: 'AposSchema',
|
|
63
|
-
|
|
64
|
-
value: {
|
|
65
|
-
type: Object,
|
|
66
|
-
required: true
|
|
67
|
-
},
|
|
68
|
-
generation: {
|
|
69
|
-
type: Number,
|
|
70
|
-
required: false,
|
|
71
|
-
default() {
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
schema: {
|
|
76
|
-
type: Array,
|
|
77
|
-
required: true
|
|
78
|
-
},
|
|
79
|
-
fieldStyle: {
|
|
80
|
-
type: String,
|
|
81
|
-
required: false,
|
|
82
|
-
default: ''
|
|
83
|
-
},
|
|
84
|
-
currentFields: {
|
|
85
|
-
type: Array,
|
|
86
|
-
default() {
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
followingValues: {
|
|
91
|
-
type: Object,
|
|
92
|
-
default() {
|
|
93
|
-
return {};
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
conditionalFields: {
|
|
97
|
-
type: Object,
|
|
98
|
-
default() {
|
|
99
|
-
return {};
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
modifiers: {
|
|
103
|
-
type: Array,
|
|
104
|
-
default() {
|
|
105
|
-
return [];
|
|
106
|
-
}
|
|
107
|
-
},
|
|
108
|
-
triggerValidation: Boolean,
|
|
109
|
-
utilityRail: {
|
|
110
|
-
type: Boolean,
|
|
111
|
-
default() {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
docId: {
|
|
116
|
-
type: String,
|
|
117
|
-
default() {
|
|
118
|
-
return null;
|
|
119
|
-
}
|
|
120
|
-
},
|
|
121
|
-
serverErrors: {
|
|
122
|
-
type: Object,
|
|
123
|
-
default() {
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
displayOptions: {
|
|
128
|
-
type: Object,
|
|
129
|
-
default() {
|
|
130
|
-
return {};
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
changed: {
|
|
134
|
-
type: Array,
|
|
135
|
-
default() {
|
|
136
|
-
return [];
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
},
|
|
140
|
-
emits: [
|
|
141
|
-
'input',
|
|
142
|
-
'reset',
|
|
143
|
-
'validate',
|
|
144
|
-
'update-doc-data'
|
|
145
|
-
],
|
|
146
|
-
data() {
|
|
147
|
-
return {
|
|
148
|
-
schemaReady: false,
|
|
149
|
-
next: {
|
|
150
|
-
hasErrors: false,
|
|
151
|
-
data: {},
|
|
152
|
-
fieldErrors: {}
|
|
153
|
-
},
|
|
154
|
-
fieldState: {},
|
|
155
|
-
fieldComponentMap: window.apos.schema.components.fields || {}
|
|
156
|
-
};
|
|
157
|
-
},
|
|
158
|
-
computed: {
|
|
159
|
-
fields() {
|
|
160
|
-
const fields = {};
|
|
161
|
-
this.schema.forEach(item => {
|
|
162
|
-
fields[item.name] = {};
|
|
163
|
-
fields[item.name].field = item;
|
|
164
|
-
fields[item.name].value = {
|
|
165
|
-
data: this.value[item.name]
|
|
166
|
-
};
|
|
167
|
-
fields[item.name].serverError = this.serverErrors && this.serverErrors[item.name];
|
|
168
|
-
fields[item.name].modifiers = [
|
|
169
|
-
...(this.modifiers || []),
|
|
170
|
-
...(item.modifiers || [])
|
|
171
|
-
];
|
|
172
|
-
});
|
|
173
|
-
return fields;
|
|
174
|
-
}
|
|
175
|
-
},
|
|
176
|
-
watch: {
|
|
177
|
-
fieldState: {
|
|
178
|
-
deep: true,
|
|
179
|
-
handler() {
|
|
180
|
-
this.updateNextAndEmit();
|
|
181
|
-
}
|
|
182
|
-
},
|
|
183
|
-
schema() {
|
|
184
|
-
this.populateDocData();
|
|
185
|
-
},
|
|
186
|
-
'value.data._id'(_id) {
|
|
187
|
-
// The doc might be swapped out completely in cases such as the media
|
|
188
|
-
// library editor. Repopulate the fields if that happens.
|
|
189
|
-
if (
|
|
190
|
-
// If the fieldState had been cleared and there's new populated data
|
|
191
|
-
(!this.fieldState._id && _id) ||
|
|
192
|
-
// or if there *is* active fieldState, but the new data is a new doc
|
|
193
|
-
(this.fieldState._id && _id !== this.fieldState._id.data)
|
|
194
|
-
) {
|
|
195
|
-
// repopulate the schema.
|
|
196
|
-
this.populateDocData();
|
|
197
|
-
}
|
|
198
|
-
},
|
|
199
|
-
generation() {
|
|
200
|
-
// repopulate the schema.
|
|
201
|
-
this.populateDocData();
|
|
202
|
-
},
|
|
203
|
-
conditionalFields(newVal, oldVal) {
|
|
204
|
-
for (const field in oldVal) {
|
|
205
|
-
if (!this.fieldState[field] || (newVal[field] === oldVal[field]) || !this.fieldState[field].ranValidation) {
|
|
206
|
-
continue;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (
|
|
210
|
-
(newVal[field] === false) ||
|
|
211
|
-
(newVal[field] && this.fieldState[field].ranValidation)
|
|
212
|
-
) {
|
|
213
|
-
this.$emit('validate');
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
},
|
|
218
|
-
created() {
|
|
219
|
-
this.populateDocData();
|
|
220
|
-
},
|
|
221
|
-
methods: {
|
|
222
|
-
getDisplayOptions(fieldName) {
|
|
223
|
-
let options = {};
|
|
224
|
-
if (this.displayOptions) {
|
|
225
|
-
options = { ...this.displayOptions };
|
|
226
|
-
}
|
|
227
|
-
if (this.changed && this.changed.includes(fieldName)) {
|
|
228
|
-
options.changed = true;
|
|
229
|
-
}
|
|
230
|
-
return options;
|
|
231
|
-
},
|
|
232
|
-
populateDocData() {
|
|
233
|
-
this.schemaReady = false;
|
|
234
|
-
const next = {
|
|
235
|
-
hasErrors: false,
|
|
236
|
-
data: {}
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
const fieldState = {};
|
|
240
|
-
|
|
241
|
-
// Though not in the schema, keep track of the _id field.
|
|
242
|
-
if (this.value.data._id) {
|
|
243
|
-
next.data._id = this.value.data._id;
|
|
244
|
-
fieldState._id = { data: this.value.data._id };
|
|
245
|
-
}
|
|
246
|
-
// Though not *always* in the schema, keep track of the archived status.
|
|
247
|
-
if (this.value.data.archived !== undefined) {
|
|
248
|
-
next.data.archived = this.value.data.archived;
|
|
249
|
-
fieldState.archived = { data: this.value.data.archived };
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
this.schema.forEach(field => {
|
|
253
|
-
const value = this.value.data[field.name];
|
|
254
|
-
fieldState[field.name] = {
|
|
255
|
-
error: false,
|
|
256
|
-
data: (value === undefined) ? field.def : value
|
|
257
|
-
};
|
|
258
|
-
next.data[field.name] = fieldState[field.name].data;
|
|
259
|
-
});
|
|
260
|
-
this.next = next;
|
|
261
|
-
this.fieldState = fieldState;
|
|
262
|
-
|
|
263
|
-
// Wait until the next tick so the parent editor component is done
|
|
264
|
-
// updating. This is only really a concern in editors that can swap
|
|
265
|
-
// the active doc/object without unmounting AposSchema.
|
|
266
|
-
this.$nextTick(() => {
|
|
267
|
-
this.schemaReady = true;
|
|
268
|
-
// Signal that the schema data is ready to be tracked.
|
|
269
|
-
this.$emit('reset');
|
|
270
|
-
});
|
|
271
|
-
},
|
|
272
|
-
updateNextAndEmit() {
|
|
273
|
-
if (!this.schemaReady) {
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
const oldHasErrors = this.next.hasErrors;
|
|
277
|
-
// destructure these for non-linked comparison
|
|
278
|
-
const oldFieldState = { ...this.next.fieldState };
|
|
279
|
-
const newFieldState = { ...this.fieldState };
|
|
280
|
-
|
|
281
|
-
let changeFound = false;
|
|
282
|
-
|
|
283
|
-
this.next.hasErrors = false;
|
|
284
|
-
this.next.fieldState = { ...this.fieldState };
|
|
285
|
-
|
|
286
|
-
this.schema.filter(field => this.displayComponent(field)).forEach(field => {
|
|
287
|
-
if (this.fieldState[field.name].error) {
|
|
288
|
-
this.next.hasErrors = true;
|
|
289
|
-
}
|
|
290
|
-
if (
|
|
291
|
-
this.fieldState[field.name].data !== undefined &&
|
|
292
|
-
detectFieldChange(field, this.next.data[field.name], this.fieldState[field.name].data)
|
|
293
|
-
) {
|
|
294
|
-
changeFound = true;
|
|
295
|
-
this.next.data[field.name] = this.fieldState[field.name].data;
|
|
296
|
-
} else {
|
|
297
|
-
this.next.data[field.name] = this.value.data[field.name];
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
|
-
if (
|
|
301
|
-
oldHasErrors !== this.next.hasErrors ||
|
|
302
|
-
oldFieldState !== newFieldState
|
|
303
|
-
) {
|
|
304
|
-
// Otherwise the save button may never unlock
|
|
305
|
-
changeFound = true;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (changeFound) {
|
|
309
|
-
// ... removes need for deep watch at parent level
|
|
310
|
-
this.$emit('input', { ...this.next });
|
|
311
|
-
}
|
|
312
|
-
},
|
|
313
|
-
displayComponent({ name, hidden = false }) {
|
|
314
|
-
if (hidden === true) {
|
|
315
|
-
return false;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (this.currentFields && !this.currentFields.includes(name)) {
|
|
319
|
-
return false;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// Might not be a conditional field at all, so test explicitly for false
|
|
323
|
-
if (this.conditionalFields[name] === false) {
|
|
324
|
-
return false;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
return true;
|
|
328
|
-
},
|
|
329
|
-
scrollFieldIntoView(fieldName) {
|
|
330
|
-
// The refs for a name are an array if that ref was assigned
|
|
331
|
-
// in a v-for. We know there is only one in this case
|
|
332
|
-
// https://forum.vuejs.org/t/this-refs-theid-returns-an-array/31995/9
|
|
333
|
-
this.$refs[fieldName][0].$el.scrollIntoView();
|
|
334
|
-
},
|
|
335
|
-
onUpdateDocData(data) {
|
|
336
|
-
this.$emit('update-doc-data', data);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
62
|
+
mixins: [ AposSchemaLogic ]
|
|
339
63
|
};
|
|
340
64
|
</script>
|
|
341
65
|
|
|
@@ -41,91 +41,10 @@
|
|
|
41
41
|
</template>
|
|
42
42
|
|
|
43
43
|
<script>
|
|
44
|
-
|
|
44
|
+
import AposSearchListLogic from '../logic/AposSearchList';
|
|
45
45
|
export default {
|
|
46
46
|
name: 'AposSearchList',
|
|
47
|
-
|
|
48
|
-
list: {
|
|
49
|
-
type: Array,
|
|
50
|
-
default() {
|
|
51
|
-
return [];
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
customFields: {
|
|
55
|
-
type: Array,
|
|
56
|
-
default() {
|
|
57
|
-
return [];
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
selectedItems: {
|
|
61
|
-
type: Array,
|
|
62
|
-
default() {
|
|
63
|
-
return [];
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
disabledTooltip: {
|
|
67
|
-
type: String,
|
|
68
|
-
default: null
|
|
69
|
-
},
|
|
70
|
-
label: {
|
|
71
|
-
type: String,
|
|
72
|
-
default: ''
|
|
73
|
-
},
|
|
74
|
-
help: {
|
|
75
|
-
type: [ String, Object ],
|
|
76
|
-
default: ''
|
|
77
|
-
},
|
|
78
|
-
icon: {
|
|
79
|
-
type: String,
|
|
80
|
-
default: 'text-box-icon'
|
|
81
|
-
},
|
|
82
|
-
iconSize: {
|
|
83
|
-
type: Number,
|
|
84
|
-
default: 20
|
|
85
|
-
},
|
|
86
|
-
fields: {
|
|
87
|
-
type: Array,
|
|
88
|
-
default() {
|
|
89
|
-
return [ 'slug' ];
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
emits: [ 'select' ],
|
|
94
|
-
methods: {
|
|
95
|
-
select(item, $event) {
|
|
96
|
-
if (item.disabled) {
|
|
97
|
-
$event.stopPropagation();
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
const selectedItems = this.selectedItems;
|
|
101
|
-
if (!selectedItems.some(selectedItem => selectedItem._id === item._id)) {
|
|
102
|
-
// Never modify a prop
|
|
103
|
-
this.$emit('select', [ ...selectedItems, item ]);
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
getClasses(item) {
|
|
107
|
-
const classes = {
|
|
108
|
-
'apos-search__item': true
|
|
109
|
-
};
|
|
110
|
-
if (item.disabled) {
|
|
111
|
-
classes['apos-search__item--disabled'] = true;
|
|
112
|
-
}
|
|
113
|
-
item.classes && Array.isArray(item.classes) && item.classes.forEach(suffix => {
|
|
114
|
-
classes[`apos-search__item--${suffix}`] = true;
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
return classes;
|
|
118
|
-
},
|
|
119
|
-
getTooltip(item) {
|
|
120
|
-
return item.disabled && item.tooltip !== false ? this.disabledTooltip : null;
|
|
121
|
-
},
|
|
122
|
-
getIcon(item) {
|
|
123
|
-
return {
|
|
124
|
-
icon: item.icon ?? this.icon,
|
|
125
|
-
iconSize: item.iconSize || this.iconSize
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
}
|
|
47
|
+
mixins: [ AposSearchListLogic ]
|
|
129
48
|
};
|
|
130
49
|
</script>
|
|
131
50
|
|
|
@@ -44,7 +44,16 @@ export function detectFieldChange(field, v1, v2) {
|
|
|
44
44
|
if (isEqual(v1, v2)) {
|
|
45
45
|
return false;
|
|
46
46
|
} else if (!v1 && !v2) {
|
|
47
|
-
|
|
47
|
+
// False values from select,
|
|
48
|
+
// radio and boolean fields are
|
|
49
|
+
// detected as a change when selected.
|
|
50
|
+
if (
|
|
51
|
+
(v1 === false && v2 !== false) ||
|
|
52
|
+
(v1 !== false && v2 === false)
|
|
53
|
+
) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
48
57
|
} else if (!v1 && Array.isArray(v2) && v2.length === 0) {
|
|
49
58
|
return false;
|
|
50
59
|
} else {
|