apostrophe 3.27.0 → 3.28.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 +12 -0
- package/modules/@apostrophecms/attachment/index.js +7 -4
- package/modules/@apostrophecms/attachment/lib/tasks/rescale.js +1 -1
- package/modules/@apostrophecms/doc-type/ui/apos/components/AposDocEditor.vue +3 -0
- package/modules/@apostrophecms/modal/ui/apos/components/AposModal.vue +26 -16
- package/modules/@apostrophecms/schema/lib/addFieldTypes.js +15 -0
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputCheckboxes.vue +11 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.28.0 (2022-08-31)
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
|
|
7
|
+
* Fix UI bug when creating a document via a relationship.
|
|
8
|
+
|
|
9
|
+
### Adds
|
|
10
|
+
|
|
11
|
+
* Support for uploading `webp` files for display as images. This is supported by all current browsers now that Microsoft has removed IE11. For best results, you should run `npm update` on your project to make sure you are receiving the latest release of `uploadfs` which uses `sharp` for image processing. Thanks to [Isaac Preston](https://github.com/ixc7) for this addition.
|
|
12
|
+
* Clicking outside a modal now closes it, the same way the `Escape` key does when pressed.
|
|
13
|
+
* `checkboxes` fields now support `min` and `max` properties. Thanks to [Gabe Flores](https://github.com/gabeflores-appstem).
|
|
14
|
+
|
|
3
15
|
## 3.27.0 (2022-08-18)
|
|
4
16
|
|
|
5
17
|
### Adds
|
|
@@ -54,7 +54,8 @@ module.exports = {
|
|
|
54
54
|
'gif',
|
|
55
55
|
'jpg',
|
|
56
56
|
'png',
|
|
57
|
-
'svg'
|
|
57
|
+
'svg',
|
|
58
|
+
'webp'
|
|
58
59
|
],
|
|
59
60
|
extensionMaps: { jpeg: 'jpg' },
|
|
60
61
|
// uploadfs should treat this as an image and create scaled versions
|
|
@@ -90,14 +91,16 @@ module.exports = {
|
|
|
90
91
|
self.croppable = {
|
|
91
92
|
gif: true,
|
|
92
93
|
jpg: true,
|
|
93
|
-
png: true
|
|
94
|
+
png: true,
|
|
95
|
+
webp: true
|
|
94
96
|
};
|
|
95
97
|
|
|
96
98
|
// Do NOT add keys here unless they have the value `true`
|
|
97
99
|
self.sized = {
|
|
98
100
|
gif: true,
|
|
99
101
|
jpg: true,
|
|
100
|
-
png: true
|
|
102
|
+
png: true,
|
|
103
|
+
webp: true
|
|
101
104
|
};
|
|
102
105
|
|
|
103
106
|
self.sizeAvailableInArchive = self.options.sizeAvailableInArchive || 'one-sixth';
|
|
@@ -1018,7 +1021,7 @@ module.exports = {
|
|
|
1018
1021
|
return;
|
|
1019
1022
|
}
|
|
1020
1023
|
let sizes;
|
|
1021
|
-
if (![ 'gif', 'jpg', 'png' ].includes(self.resolveExtension(attachment.extension))) {
|
|
1024
|
+
if (![ 'gif', 'jpg', 'png', 'webp' ].includes(self.resolveExtension(attachment.extension))) {
|
|
1022
1025
|
sizes = [ { name: 'original' } ];
|
|
1023
1026
|
} else {
|
|
1024
1027
|
sizes = self.imageSizes.concat([ { name: 'original' } ]);
|
|
@@ -12,7 +12,7 @@ module.exports = function(self) {
|
|
|
12
12
|
const total = await self.db.count();
|
|
13
13
|
let n = 0;
|
|
14
14
|
await self.each({}, argv.parallel || 1, async function(file) {
|
|
15
|
-
if (!_.includes([ 'jpg', 'png', 'gif' ], file.extension)) {
|
|
15
|
+
if (!_.includes([ 'jpg', 'png', 'gif', 'webp' ], file.extension)) {
|
|
16
16
|
n++;
|
|
17
17
|
console.log('Skipping a non-image attachment: ' + file.name + '.' + file.extension);
|
|
18
18
|
return;
|
|
@@ -727,6 +727,9 @@ export default {
|
|
|
727
727
|
window.localStorage.setItem(this.savePreferenceName, pref);
|
|
728
728
|
},
|
|
729
729
|
onContentChanged(e) {
|
|
730
|
+
if (this.original?._id !== e.doc._id) {
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
730
733
|
if (e.doc.type !== this.docType) {
|
|
731
734
|
this.docType = e.doc.type;
|
|
732
735
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<transition
|
|
3
3
|
:name="transitionType"
|
|
4
|
-
@enter="
|
|
5
|
-
@leave="
|
|
4
|
+
@enter="onEnter"
|
|
5
|
+
@leave="onLeave"
|
|
6
6
|
:duration="250"
|
|
7
7
|
>
|
|
8
8
|
<section
|
|
@@ -14,12 +14,18 @@
|
|
|
14
14
|
ref="modalEl"
|
|
15
15
|
>
|
|
16
16
|
<transition :name="transitionType">
|
|
17
|
-
<div
|
|
17
|
+
<div
|
|
18
|
+
@click="close"
|
|
19
|
+
v-if="modal.showModal"
|
|
20
|
+
class="apos-modal__overlay"
|
|
21
|
+
/>
|
|
18
22
|
</transition>
|
|
19
23
|
<transition :name="transitionType" @after-leave="$emit('inactive')">
|
|
20
24
|
<div
|
|
21
|
-
v-if="modal.showModal"
|
|
22
|
-
class="
|
|
25
|
+
v-if="modal.showModal"
|
|
26
|
+
:class="innerClasses"
|
|
27
|
+
class="apos-modal__inner"
|
|
28
|
+
data-apos-modal-inner
|
|
23
29
|
>
|
|
24
30
|
<template v-if="modal.busy">
|
|
25
31
|
<div class="apos-modal__busy">
|
|
@@ -180,16 +186,13 @@ export default {
|
|
|
180
186
|
}
|
|
181
187
|
},
|
|
182
188
|
methods: {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
if (e.keyCode === 27) {
|
|
188
|
-
e.stopPropagation();
|
|
189
|
-
this.$emit('esc');
|
|
189
|
+
onKeydown (e) {
|
|
190
|
+
const hasPressedEsc = e.keyCode === 27;
|
|
191
|
+
if (hasPressedEsc) {
|
|
192
|
+
this.close(e);
|
|
190
193
|
}
|
|
191
194
|
},
|
|
192
|
-
|
|
195
|
+
onEnter () {
|
|
193
196
|
this.$emit('show-modal');
|
|
194
197
|
this.bindEventListeners();
|
|
195
198
|
apos.modal.stack = apos.modal.stack || [];
|
|
@@ -198,7 +201,7 @@ export default {
|
|
|
198
201
|
this.$emit('ready');
|
|
199
202
|
});
|
|
200
203
|
},
|
|
201
|
-
|
|
204
|
+
onLeave () {
|
|
202
205
|
this.removeEventListeners();
|
|
203
206
|
this.$emit('no-modal');
|
|
204
207
|
// pop doesn't quite suffice because of race conditions when
|
|
@@ -206,10 +209,17 @@ export default {
|
|
|
206
209
|
apos.modal.stack = apos.modal.stack.filter(modal => modal !== this);
|
|
207
210
|
},
|
|
208
211
|
bindEventListeners () {
|
|
209
|
-
window.addEventListener('keydown', this.
|
|
212
|
+
window.addEventListener('keydown', this.onKeydown);
|
|
210
213
|
},
|
|
211
214
|
removeEventListeners () {
|
|
212
|
-
window.removeEventListener('keydown', this.
|
|
215
|
+
window.removeEventListener('keydown', this.onKeydown);
|
|
216
|
+
},
|
|
217
|
+
close (e) {
|
|
218
|
+
if (apos.modal.stack[apos.modal.stack.length - 1] !== this) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
e.stopPropagation();
|
|
222
|
+
this.$emit('esc');
|
|
213
223
|
},
|
|
214
224
|
trapFocus () {
|
|
215
225
|
// Adapted from https://uxdesign.cc/how-to-trap-focus-inside-modal-to-make-it-ada-compliant-6a50f9a70700
|
|
@@ -254,6 +254,13 @@ module.exports = (self) => {
|
|
|
254
254
|
});
|
|
255
255
|
}
|
|
256
256
|
}
|
|
257
|
+
|
|
258
|
+
if ((field.min !== undefined) && (destination[field.name].length < field.min)) {
|
|
259
|
+
throw self.apos.error('min');
|
|
260
|
+
}
|
|
261
|
+
if ((field.max !== undefined) && (destination[field.name].length > field.max)) {
|
|
262
|
+
throw self.apos.error('max');
|
|
263
|
+
}
|
|
257
264
|
},
|
|
258
265
|
index: function (value, field, texts) {
|
|
259
266
|
const silent = field.silent === undefined ? true : field.silent;
|
|
@@ -300,6 +307,14 @@ module.exports = (self) => {
|
|
|
300
307
|
return choices;
|
|
301
308
|
}
|
|
302
309
|
});
|
|
310
|
+
},
|
|
311
|
+
validate: function (field, options, warn, fail) {
|
|
312
|
+
if (field.max && typeof field.max !== 'number') {
|
|
313
|
+
fail('Property "max" must be a number');
|
|
314
|
+
}
|
|
315
|
+
if (field.min && typeof field.min !== 'number') {
|
|
316
|
+
fail('Property "min" must be a number');
|
|
317
|
+
}
|
|
303
318
|
}
|
|
304
319
|
});
|
|
305
320
|
|
|
@@ -47,6 +47,17 @@ export default {
|
|
|
47
47
|
return 'required';
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
if (this.field.min) {
|
|
51
|
+
if ((values != null) && (values.length < this.field.min)) {
|
|
52
|
+
return 'min';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (this.field.max) {
|
|
56
|
+
if ((values != null) && (values.length > this.field.max)) {
|
|
57
|
+
return 'max';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
50
61
|
if (Array.isArray(values)) {
|
|
51
62
|
values.forEach(chosen => {
|
|
52
63
|
if (!this.choices.map(choice => {
|