apostrophe 4.28.0 → 4.29.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 +33 -3
- package/README.md +142 -0
- package/defaults.js +1 -0
- package/lib/safe-json-script.js +27 -0
- package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposAdminBarLocale.vue +1 -1
- package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue +1 -0
- package/modules/@apostrophecms/area/ui/apos/components/AposAreaWidget.vue +3 -5
- package/modules/@apostrophecms/area/ui/apos/components/AposBreadcrumbOperations.vue +13 -1
- package/modules/@apostrophecms/asset/lib/globalIcons.js +3 -0
- package/modules/@apostrophecms/attachment/index.js +43 -1
- package/modules/@apostrophecms/color-field/index.js +7 -1
- package/modules/@apostrophecms/doc/index.js +11 -1
- package/modules/@apostrophecms/doc-type/index.js +165 -32
- package/modules/@apostrophecms/doc-type/ui/apos/components/AposDocEditor.vue +1 -1
- package/modules/@apostrophecms/doc-type/ui/apos/logic/AposDocContextMenu.js +104 -59
- package/modules/@apostrophecms/file/index.js +109 -9
- package/modules/@apostrophecms/i18n/i18n/de.json +0 -2
- package/modules/@apostrophecms/i18n/i18n/en.json +40 -1
- package/modules/@apostrophecms/i18n/i18n/es.json +0 -1
- package/modules/@apostrophecms/i18n/i18n/fr.json +0 -1
- package/modules/@apostrophecms/i18n/i18n/it.json +0 -1
- package/modules/@apostrophecms/i18n/i18n/pt-BR.json +0 -1
- package/modules/@apostrophecms/i18n/i18n/sk.json +0 -1
- package/modules/@apostrophecms/i18n/ui/apos/apps/AposI18nBatchReporting.js +18 -1
- package/modules/@apostrophecms/i18n/ui/apos/apps/AposI18nLocalizeActions.js +50 -0
- package/modules/@apostrophecms/i18n/ui/apos/components/AposI18nLocalize.vue +56 -13
- package/modules/@apostrophecms/image/ui/apos/components/AposImageRelationshipEditor.vue +8 -2
- package/modules/@apostrophecms/layout-column-widget/index.js +156 -163
- package/modules/@apostrophecms/layout-widget/index.js +7 -2
- package/modules/@apostrophecms/layout-widget/ui/apos/components/AposAreaLayoutEditor.vue +6 -11
- package/modules/@apostrophecms/layout-widget/ui/apos/components/AposGridColumn.vue +3 -5
- package/modules/@apostrophecms/layout-widget/ui/apos/components/AposGridLayout.vue +4 -4
- package/modules/@apostrophecms/layout-widget/ui/apos/components/AposGridManager.vue +0 -16
- package/modules/@apostrophecms/layout-widget/ui/apos/lib/grid-state.mjs +7 -27
- package/modules/@apostrophecms/layout-widget/views/column.html +7 -9
- package/modules/@apostrophecms/login/index.js +39 -40
- package/modules/@apostrophecms/modal/ui/apos/components/AposDocsManagerToolbar.vue +17 -2
- package/modules/@apostrophecms/modal/ui/apos/components/AposModal.vue +3 -2
- package/modules/@apostrophecms/notification/ui/apos/components/AposNotification.vue +1 -0
- package/modules/@apostrophecms/page/index.js +2 -0
- package/modules/@apostrophecms/piece-type/index.js +3 -1
- package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManager.vue +1 -0
- package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManagerDisplay.vue +5 -0
- package/modules/@apostrophecms/recently-edited/index.js +831 -0
- package/modules/@apostrophecms/recently-edited/ui/apos/components/AposCellTitle.vue +54 -0
- package/modules/@apostrophecms/recently-edited/ui/apos/components/AposRecentlyEditedCombo.vue +454 -0
- package/modules/@apostrophecms/recently-edited/ui/apos/components/AposRecentlyEditedFilterTag.vue +75 -0
- package/modules/@apostrophecms/recently-edited/ui/apos/components/AposRecentlyEditedFilters.vue +287 -0
- package/modules/@apostrophecms/recently-edited/ui/apos/components/AposRecentlyEditedIcon.vue +16 -0
- package/modules/@apostrophecms/recently-edited/ui/apos/components/AposRecentlyEditedManager.vue +346 -0
- package/modules/@apostrophecms/recently-edited/ui/apos/composables/useRecentlyEditedBatch.js +193 -0
- package/modules/@apostrophecms/recently-edited/ui/apos/composables/useRecentlyEditedData.js +276 -0
- package/modules/@apostrophecms/recently-edited/ui/apos/composables/useRecentlyEditedFetch.js +199 -0
- package/modules/@apostrophecms/recently-edited/ui/apos/composables/useRecentlyEditedFilters.js +100 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputRelationship.js +8 -4
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputWrapper.js +1 -1
- package/modules/@apostrophecms/styles/index.js +10 -0
- package/modules/@apostrophecms/styles/lib/apiRoutes.js +6 -0
- package/modules/@apostrophecms/styles/lib/handlers.js +5 -0
- package/modules/@apostrophecms/styles/lib/methods.js +9 -3
- package/modules/@apostrophecms/styles/lib/presets.js +119 -0
- package/modules/@apostrophecms/styles/ui/apos/components/TheAposStyles.vue +3 -8
- package/modules/@apostrophecms/styles/ui/apos/composables/AposStyles.js +1 -3
- package/modules/@apostrophecms/styles/ui/apos/render-factory.js +29 -0
- package/modules/@apostrophecms/styles/ui/apos/universal/backgroundHelpers.mjs +140 -0
- package/modules/@apostrophecms/styles/ui/apos/universal/customRules.mjs +105 -0
- package/modules/@apostrophecms/styles/ui/apos/universal/render.mjs +195 -15
- package/modules/@apostrophecms/template/index.js +22 -6
- package/modules/@apostrophecms/ui/ui/apos/components/AposCellContextMenu.vue +2 -0
- package/modules/@apostrophecms/ui/ui/apos/components/AposContextMenu.vue +18 -4
- package/modules/@apostrophecms/ui/ui/apos/composables/useInfiniteScroll.js +91 -0
- package/modules/@apostrophecms/ui/ui/apos/scss/global/_theme.scss +1 -0
- package/modules/@apostrophecms/ui/ui/apos/stores/modal.js +5 -2
- package/modules/@apostrophecms/ui/ui/apos/utils/index.js +9 -0
- package/modules/@apostrophecms/url/index.js +38 -4
- package/modules/@apostrophecms/widget-type/index.js +22 -6
- package/modules/@apostrophecms/widget-type/ui/apos/components/AposWidgetEditor.vue +8 -4
- package/package.json +19 -19
- package/test/files.js +129 -0
- package/test/layout-widget-migration.js +719 -0
- package/test/login-requirements.js +1 -1
- package/test/pieces-public-api.js +80 -0
- package/test/pieces.js +25 -0
- package/test/recently-edited.js +2311 -0
- package/test/schemas.js +39 -3
- package/test/static-build.js +642 -0
- package/test/styles.js +2569 -0
- package/modules/@apostrophecms/layout-widget/ui/apos/components/AposLayoutColControlDialog.vue +0 -171
|
@@ -293,68 +293,67 @@ module.exports = {
|
|
|
293
293
|
},
|
|
294
294
|
...self.isPasswordResetEnabled() && {
|
|
295
295
|
async resetRequest(req) {
|
|
296
|
-
const
|
|
296
|
+
const MIN_RESPONSE_TIME = 2000;
|
|
297
|
+
const startTime = Date.now();
|
|
297
298
|
const site = (req.headers.host || '').replace(/:\d+$/, '');
|
|
298
299
|
const email = self.apos.launder.string(req.body.email);
|
|
299
300
|
if (!email.length) {
|
|
300
301
|
throw self.apos.error('invalid', req.t('apostrophe:loginResetEmailRequired'));
|
|
301
302
|
}
|
|
302
303
|
let user;
|
|
303
|
-
// error not reported to browser for security reasons
|
|
304
304
|
try {
|
|
305
305
|
user = await self.getPasswordResetUser(req.body.email);
|
|
306
306
|
} catch (e) {
|
|
307
307
|
self.apos.util.error(e);
|
|
308
308
|
}
|
|
309
309
|
if (!user) {
|
|
310
|
-
await wait();
|
|
311
310
|
self.apos.util.error(
|
|
312
311
|
`Reset password request error - the user ${email} doesn\`t exist.`
|
|
313
312
|
);
|
|
314
|
-
|
|
315
|
-
}
|
|
316
|
-
if (!user.email) {
|
|
317
|
-
await wait();
|
|
313
|
+
} else if (!user.email) {
|
|
318
314
|
self.apos.util.error(
|
|
319
315
|
`Reset password request error - the user ${user.username} doesn\`t have an email.`
|
|
320
316
|
);
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
const reset = self.apos.util.generateId();
|
|
324
|
-
user.passwordReset = reset;
|
|
325
|
-
user.passwordResetAt = new Date();
|
|
326
|
-
await self.apos.user.update(req, user, { permissions: false });
|
|
327
|
-
// Fix - missing host in the absoluteUrl results in a panic.
|
|
328
|
-
let port = (req.headers.host || '').split(':')[1];
|
|
329
|
-
if (!port || [ '80', '443' ].includes(port)) {
|
|
330
|
-
port = '';
|
|
331
317
|
} else {
|
|
332
|
-
|
|
318
|
+
const reset = self.apos.util.generateId();
|
|
319
|
+
user.passwordReset = reset;
|
|
320
|
+
user.passwordResetAt = new Date();
|
|
321
|
+
await self.apos.user.update(req, user, { permissions: false });
|
|
322
|
+
let port = (req.headers.host || '').split(':')[1];
|
|
323
|
+
if (!port || [ '80', '443' ].includes(port)) {
|
|
324
|
+
port = '';
|
|
325
|
+
} else {
|
|
326
|
+
port = `:${port}`;
|
|
327
|
+
}
|
|
328
|
+
const parsed = new URL(
|
|
329
|
+
req.absoluteUrl,
|
|
330
|
+
self.apos.baseUrl
|
|
331
|
+
? undefined
|
|
332
|
+
: `${req.protocol}://${req.hostname}${port}`
|
|
333
|
+
);
|
|
334
|
+
parsed.pathname = self.login();
|
|
335
|
+
parsed.search = '?';
|
|
336
|
+
parsed.searchParams.append('reset', reset);
|
|
337
|
+
parsed.searchParams.append('email', user.email);
|
|
338
|
+
try {
|
|
339
|
+
await self.email(req, 'passwordResetEmail', {
|
|
340
|
+
user,
|
|
341
|
+
url: parsed.toString(),
|
|
342
|
+
site
|
|
343
|
+
}, {
|
|
344
|
+
to: user.email,
|
|
345
|
+
subject: req.t('apostrophe:passwordResetRequest', { site })
|
|
346
|
+
});
|
|
347
|
+
} catch (err) {
|
|
348
|
+
self.apos.util.error(`Error while sending email to ${user.email}`, err);
|
|
349
|
+
}
|
|
333
350
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
: `${req.protocol}://${req.hostname}${port}`
|
|
339
|
-
);
|
|
340
|
-
parsed.pathname = self.login();
|
|
341
|
-
parsed.search = '?';
|
|
342
|
-
parsed.searchParams.append('reset', reset);
|
|
343
|
-
parsed.searchParams.append('email', user.email);
|
|
344
|
-
try {
|
|
345
|
-
await self.email(req, 'passwordResetEmail', {
|
|
346
|
-
user,
|
|
347
|
-
url: parsed.toString(),
|
|
348
|
-
site
|
|
349
|
-
}, {
|
|
350
|
-
to: user.email,
|
|
351
|
-
subject: req.t('apostrophe:passwordResetRequest', { site })
|
|
352
|
-
});
|
|
353
|
-
} catch (err) {
|
|
354
|
-
self.apos.util.error(`Error while sending email to ${user.email}`, err);
|
|
351
|
+
// Pad all paths to a constant minimum duration
|
|
352
|
+
const elapsed = Date.now() - startTime;
|
|
353
|
+
if (elapsed < MIN_RESPONSE_TIME) {
|
|
354
|
+
await Promise.delay(MIN_RESPONSE_TIME - elapsed);
|
|
355
355
|
}
|
|
356
356
|
},
|
|
357
|
-
|
|
358
357
|
async reset(req) {
|
|
359
358
|
const password = self.apos.launder.string(req.body.password);
|
|
360
359
|
if (!password.length) {
|
|
@@ -158,6 +158,10 @@ export default {
|
|
|
158
158
|
moduleName: {
|
|
159
159
|
type: String,
|
|
160
160
|
required: true
|
|
161
|
+
},
|
|
162
|
+
searchPlaceholder: {
|
|
163
|
+
type: [ String, Object ],
|
|
164
|
+
default: null
|
|
161
165
|
}
|
|
162
166
|
},
|
|
163
167
|
emits: [
|
|
@@ -173,7 +177,7 @@ export default {
|
|
|
173
177
|
searchField: {
|
|
174
178
|
field: {
|
|
175
179
|
name: 'search',
|
|
176
|
-
placeholder: {
|
|
180
|
+
placeholder: this.searchPlaceholder || {
|
|
177
181
|
key: 'apostrophe:searchDocType',
|
|
178
182
|
type: this.$t(this.labels.plural)
|
|
179
183
|
},
|
|
@@ -197,7 +201,7 @@ export default {
|
|
|
197
201
|
}
|
|
198
202
|
},
|
|
199
203
|
canSelectAll() {
|
|
200
|
-
return this.displayedItems;
|
|
204
|
+
return this.displayedItems && (this.batchOperations.length || this.isRelationship);
|
|
201
205
|
},
|
|
202
206
|
canArchive() {
|
|
203
207
|
return this.checkedCount;
|
|
@@ -206,6 +210,17 @@ export default {
|
|
|
206
210
|
return !this.options.noSearch;
|
|
207
211
|
}
|
|
208
212
|
},
|
|
213
|
+
watch: {
|
|
214
|
+
batchOperations() {
|
|
215
|
+
this.computeActiveOperations();
|
|
216
|
+
},
|
|
217
|
+
filterValues: {
|
|
218
|
+
deep: true,
|
|
219
|
+
handler() {
|
|
220
|
+
this.computeActiveOperations();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
},
|
|
209
224
|
mounted () {
|
|
210
225
|
this.computeActiveOperations();
|
|
211
226
|
apos.bus.$on('command-menu-manager-select-all', this.selectAll);
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
<slot name="localeDisplay" />
|
|
101
101
|
</div>
|
|
102
102
|
<AposLocale
|
|
103
|
-
v-else-if="hasBeenLocalized"
|
|
103
|
+
v-else-if="hasBeenLocalized && !isCrossLocale"
|
|
104
104
|
class="apos-modal__locale"
|
|
105
105
|
:locale="currentLocale"
|
|
106
106
|
/>
|
|
@@ -205,7 +205,8 @@ const modalInnerEl = useTemplateRef('modalInnerEl');
|
|
|
205
205
|
const findPriorityFocusElementRetryMax = ref(3);
|
|
206
206
|
const currentPriorityFocusElementRetry = ref(0);
|
|
207
207
|
const renderingElements = ref(true);
|
|
208
|
-
const currentLocale =
|
|
208
|
+
const currentLocale = computed(() => store.activeModal?.locale || apos.i18n.locale);
|
|
209
|
+
const isCrossLocale = computed(() => store.activeModal?.crossLocale || false);
|
|
209
210
|
const nonDraggableElements = [
|
|
210
211
|
'.apos-input-wrapper',
|
|
211
212
|
'.apos-field--inline-array-field',
|
|
@@ -2951,10 +2951,12 @@ database.`);
|
|
|
2951
2951
|
_id: null
|
|
2952
2952
|
});
|
|
2953
2953
|
} else {
|
|
2954
|
+
// Note that we MUST NOT honor the "project" query builder here
|
|
2954
2955
|
query.project({
|
|
2955
2956
|
...self.options.publicApiProjection,
|
|
2956
2957
|
cacheInvalidatedAt: 1
|
|
2957
2958
|
});
|
|
2959
|
+
query.set('publicApiProjection', self.options.publicApiProjection);
|
|
2958
2960
|
}
|
|
2959
2961
|
}
|
|
2960
2962
|
return query;
|
|
@@ -1126,11 +1126,13 @@ module.exports = {
|
|
|
1126
1126
|
query.and({
|
|
1127
1127
|
_id: null
|
|
1128
1128
|
});
|
|
1129
|
-
} else
|
|
1129
|
+
} else {
|
|
1130
|
+
// Note that we MUST NOT honor the "project" query builder here
|
|
1130
1131
|
query.project({
|
|
1131
1132
|
...self.options.publicApiProjection,
|
|
1132
1133
|
cacheInvalidatedAt: 1
|
|
1133
1134
|
});
|
|
1135
|
+
query.set('publicApiProjection', self.options.publicApiProjection);
|
|
1134
1136
|
}
|
|
1135
1137
|
}
|
|
1136
1138
|
return query;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
<tbody>
|
|
4
4
|
<tr>
|
|
5
5
|
<th
|
|
6
|
+
v-if="hasBatchOperations"
|
|
6
7
|
class="apos-table__header"
|
|
7
8
|
/>
|
|
8
9
|
<th
|
|
@@ -46,6 +47,7 @@
|
|
|
46
47
|
@mouseout="out(item._id)"
|
|
47
48
|
>
|
|
48
49
|
<td
|
|
50
|
+
v-if="hasBatchOperations"
|
|
49
51
|
class="apos-table__cell"
|
|
50
52
|
>
|
|
51
53
|
<AposCheckbox
|
|
@@ -166,6 +168,9 @@ export default {
|
|
|
166
168
|
},
|
|
167
169
|
contextMenuOptions() {
|
|
168
170
|
return this.options;
|
|
171
|
+
},
|
|
172
|
+
hasBatchOperations() {
|
|
173
|
+
return this.options.batchOperations?.length > 0 || this.options.isRelationship;
|
|
169
174
|
}
|
|
170
175
|
},
|
|
171
176
|
watch: {
|