apostrophe 3.47.0 → 3.49.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 +73 -2
- package/index.js +20 -2
- package/lib/locales.js +1 -1
- package/lib/moog-require.js +7 -0
- package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue +12 -2
- package/modules/@apostrophecms/any-page-type/index.js +5 -0
- package/modules/@apostrophecms/area/ui/apos/components/AposAreaEditor.vue +2 -0
- package/modules/@apostrophecms/area/ui/apos/components/AposAreaWidget.vue +7 -24
- package/modules/@apostrophecms/asset/index.js +27 -2
- package/modules/@apostrophecms/asset/lib/webpack/apos/webpack.config.js +23 -2
- package/modules/@apostrophecms/asset/lib/webpack/src/webpack.config.js +26 -2
- package/modules/@apostrophecms/doc/index.js +149 -0
- package/modules/@apostrophecms/doc-type/index.js +40 -1
- package/modules/@apostrophecms/global/index.js +4 -15
- package/modules/@apostrophecms/i18n/i18n/en.json +3 -2
- package/modules/@apostrophecms/i18n/index.js +76 -61
- package/modules/@apostrophecms/image/index.js +8 -0
- package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerDisplay.vue +14 -1
- package/modules/@apostrophecms/login/ui/apos/components/AposForgotPasswordForm.vue +3 -60
- package/modules/@apostrophecms/login/ui/apos/components/AposLoginForm.vue +3 -231
- package/modules/@apostrophecms/login/ui/apos/components/AposResetPasswordForm.vue +3 -96
- package/modules/@apostrophecms/login/ui/apos/components/TheAposLogin.vue +2 -99
- package/modules/@apostrophecms/login/ui/apos/logic/AposForgotPasswordForm.js +68 -0
- package/modules/@apostrophecms/login/ui/apos/logic/AposLoginForm.js +239 -0
- package/modules/@apostrophecms/login/ui/apos/logic/AposResetPasswordForm.js +105 -0
- package/modules/@apostrophecms/login/ui/apos/logic/TheAposLogin.js +107 -0
- package/modules/@apostrophecms/modal/ui/apos/components/AposDocsManagerToolbar.vue +9 -3
- package/modules/@apostrophecms/modal/ui/apos/components/AposModalToolbar.vue +1 -0
- package/modules/@apostrophecms/page/index.js +63 -1
- package/modules/@apostrophecms/page-type/index.js +6 -0
- package/modules/@apostrophecms/piece-type/index.js +93 -9
- package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManager.vue +4 -0
- package/modules/@apostrophecms/rich-text-widget/index.js +1 -1
- package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposImageControlDialog.vue +14 -10
- package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposRichTextWidgetEditor.vue +252 -86
- package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapAnchor.vue +0 -1
- package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapLink.vue +0 -1
- package/modules/@apostrophecms/rich-text-widget/ui/apos/tiptap-extensions/Image.js +76 -54
- package/modules/@apostrophecms/schema/index.js +1 -2
- package/modules/@apostrophecms/schema/lib/addFieldTypes.js +35 -7
- package/modules/@apostrophecms/schema/ui/apos/components/AposArrayEditor.vue +0 -1
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputArray.vue +0 -1
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputObject.vue +0 -1
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputSlug.vue +21 -1
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputString.vue +12 -7
- package/modules/@apostrophecms/schema/ui/apos/components/AposSchema.vue +7 -1
- package/modules/@apostrophecms/ui/ui/apos/components/AposCombo.vue +178 -20
- package/modules/@apostrophecms/ui/ui/apos/components/AposFilterMenu.vue +1 -1
- package/modules/@apostrophecms/ui/ui/apos/components/AposPager.vue +4 -6
- package/modules/@apostrophecms/ui/ui/apos/scss/mixins/_theme_mixins.scss +1 -0
- package/modules/@apostrophecms/util/index.js +5 -6
- package/modules/@apostrophecms/util/ui/src/http.js +6 -3
- package/modules/@apostrophecms/widget-type/index.js +4 -0
- package/package.json +20 -3
- package/test/change-doc-ids.js +134 -0
- package/test/i18n.js +310 -0
- package/test/pieces-children/pieces-malformed-child.js +32 -0
- package/test/pieces-malformed.js +33 -0
- package/test/widgets-children/widgets-malformed-child.js +32 -0
- package/test/widgets-malformed.js +34 -0
- package/test/static-i18n.js +0 -105
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// This is the business logic of the TheAposLogin Vue component.
|
|
2
|
+
// It is in a separate file so that you can override the component's templates
|
|
3
|
+
// and styles just by copying the .vue file to your project, and leave the business logic
|
|
4
|
+
// unchanged.
|
|
5
|
+
|
|
6
|
+
import AposThemeMixin from 'Modules/@apostrophecms/ui/mixins/AposThemeMixin';
|
|
7
|
+
|
|
8
|
+
const STAGES = [
|
|
9
|
+
'login',
|
|
10
|
+
'forgotPassword',
|
|
11
|
+
'resetPassword'
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
export default {
|
|
15
|
+
mixins: [ AposThemeMixin ],
|
|
16
|
+
data() {
|
|
17
|
+
return {
|
|
18
|
+
stage: STAGES[0],
|
|
19
|
+
mounted: false,
|
|
20
|
+
beforeCreateFinished: false,
|
|
21
|
+
error: '',
|
|
22
|
+
passwordResetData: {},
|
|
23
|
+
context: {}
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
computed: {
|
|
27
|
+
loaded() {
|
|
28
|
+
return this.mounted && this.beforeCreateFinished;
|
|
29
|
+
},
|
|
30
|
+
showNav() {
|
|
31
|
+
return this.stage !== STAGES[0];
|
|
32
|
+
},
|
|
33
|
+
homeUrl() {
|
|
34
|
+
return `${apos.prefix}/`;
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
// We need it here and not in the login form because the version used in the footer.
|
|
38
|
+
// The context will be passed to every form, might be a good thing in the future.
|
|
39
|
+
async beforeCreate() {
|
|
40
|
+
const stateChange = parseInt(window.sessionStorage.getItem('aposStateChange'));
|
|
41
|
+
const seen = JSON.parse(window.sessionStorage.getItem('aposStateChangeSeen') || '{}');
|
|
42
|
+
if (!seen[window.location.href]) {
|
|
43
|
+
const lastModified = Date.parse(document.lastModified);
|
|
44
|
+
if (stateChange && lastModified && (lastModified < stateChange)) {
|
|
45
|
+
seen[window.location.href] = true;
|
|
46
|
+
window.sessionStorage.setItem('aposStateChangeSeen', JSON.stringify(seen));
|
|
47
|
+
location.reload();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
this.context = await apos.http.post(`${apos.login.action}/context`, {
|
|
53
|
+
busy: true
|
|
54
|
+
});
|
|
55
|
+
} catch (e) {
|
|
56
|
+
this.context = {};
|
|
57
|
+
this.error = e.message || 'apostrophe:loginErrorGeneric';
|
|
58
|
+
} finally {
|
|
59
|
+
this.beforeCreateFinished = true;
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
created() {
|
|
63
|
+
const url = new URL(document.location);
|
|
64
|
+
const data = {
|
|
65
|
+
email: url.searchParams.get('email'),
|
|
66
|
+
reset: url.searchParams.get('reset')
|
|
67
|
+
};
|
|
68
|
+
if (data.email && data.reset) {
|
|
69
|
+
this.passwordResetData = data;
|
|
70
|
+
this.setStage('resetPassword');
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
mounted() {
|
|
74
|
+
this.mounted = true;
|
|
75
|
+
},
|
|
76
|
+
methods: {
|
|
77
|
+
setStage(name) {
|
|
78
|
+
// 1. Enabled status per stage. A bit cryptic but effective.
|
|
79
|
+
// Search for a method composed of the `name` + `Enabled`
|
|
80
|
+
// (e.g. `forgotPasswordEnabled` and execute it (should return boolean).
|
|
81
|
+
// If no method is found it is enabled. Fallback to the default stage.
|
|
82
|
+
const enabled = this[`${name}Enabled`]?.() ?? true;
|
|
83
|
+
if (!enabled) {
|
|
84
|
+
this.stage = STAGES[0];
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// 2. Set it only if it's a known stage
|
|
88
|
+
if (STAGES.includes(name)) {
|
|
89
|
+
this.stage = name;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// 3. Fallback to the default stage
|
|
93
|
+
this.stage = STAGES[0];
|
|
94
|
+
},
|
|
95
|
+
forgotPasswordEnabled() {
|
|
96
|
+
return apos.login.passwordResetEnabled;
|
|
97
|
+
},
|
|
98
|
+
resetPasswordEnabled() {
|
|
99
|
+
return apos.login.passwordResetEnabled;
|
|
100
|
+
},
|
|
101
|
+
onRedirect(loc) {
|
|
102
|
+
window.sessionStorage.setItem('aposStateChange', Date.now());
|
|
103
|
+
window.sessionStorage.setItem('aposStateChangeSeen', '{}');
|
|
104
|
+
location.assign(loc);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
v-if="canSelectAll"
|
|
6
6
|
label="apostrophe:select"
|
|
7
7
|
type="outline"
|
|
8
|
+
:modifiers="['small']"
|
|
8
9
|
text-color="var(--a-base-1)"
|
|
9
10
|
:icon-only="true"
|
|
10
11
|
:icon="checkboxIcon"
|
|
@@ -24,9 +25,9 @@
|
|
|
24
25
|
<AposButton
|
|
25
26
|
v-if="!operations"
|
|
26
27
|
:label="label"
|
|
27
|
-
:icon-only="true"
|
|
28
28
|
:icon="icon"
|
|
29
29
|
:disabled="!checkedCount"
|
|
30
|
+
:modifiers="['small']"
|
|
30
31
|
type="outline"
|
|
31
32
|
@click="confirmOperation({ action, label, ...rest })"
|
|
32
33
|
/>
|
|
@@ -302,7 +303,12 @@ export default {
|
|
|
302
303
|
</script>
|
|
303
304
|
|
|
304
305
|
<style lang="scss" scoped>
|
|
305
|
-
.apos-manager-toolbar ::v-deep
|
|
306
|
-
|
|
306
|
+
.apos-manager-toolbar ::v-deep {
|
|
307
|
+
.apos-field--search {
|
|
308
|
+
width: 250px;
|
|
309
|
+
}
|
|
310
|
+
.apos-input {
|
|
311
|
+
height: 32px;
|
|
312
|
+
}
|
|
307
313
|
}
|
|
308
314
|
</style>
|
|
@@ -100,6 +100,7 @@ module.exports = {
|
|
|
100
100
|
self.enableBrowserData();
|
|
101
101
|
self.addLegacyMigrations();
|
|
102
102
|
self.addMisreplicatedParkedPagesMigration();
|
|
103
|
+
self.addDuplicateParkedPagesMigration();
|
|
103
104
|
await self.createIndexes();
|
|
104
105
|
},
|
|
105
106
|
restApiRoutes(self) {
|
|
@@ -1959,7 +1960,10 @@ database.`);
|
|
|
1959
1960
|
delete _item._children;
|
|
1960
1961
|
if (!parent) {
|
|
1961
1962
|
// Parking the home page for the first time
|
|
1962
|
-
_item.aposDocId = self.apos.
|
|
1963
|
+
_item.aposDocId = await self.apos.doc.bestAposDocId({
|
|
1964
|
+
level: 0,
|
|
1965
|
+
slug: '/'
|
|
1966
|
+
});
|
|
1963
1967
|
_item.path = _item.aposDocId;
|
|
1964
1968
|
_item.lastPublishedAt = new Date();
|
|
1965
1969
|
return self.apos.doc.insert(req, _item);
|
|
@@ -2365,6 +2369,64 @@ database.`);
|
|
|
2365
2369
|
}
|
|
2366
2370
|
}
|
|
2367
2371
|
});
|
|
2372
|
+
},
|
|
2373
|
+
addDuplicateParkedPagesMigration() {
|
|
2374
|
+
self.apos.migration.add('duplicate-parked-pages', async () => {
|
|
2375
|
+
let parkedPages = await self.apos.doc.db.find({
|
|
2376
|
+
parkedId: {
|
|
2377
|
+
$ne: null
|
|
2378
|
+
}
|
|
2379
|
+
}).toArray();
|
|
2380
|
+
const parkedIds = [ ...new Set(parkedPages.map(page => page.parkedId)) ];
|
|
2381
|
+
const names = Object.keys(self.apos.i18n.locales);
|
|
2382
|
+
const locales = [
|
|
2383
|
+
...names.map(locale => `${locale}:draft`),
|
|
2384
|
+
...names.map(locale => `${locale}:published`),
|
|
2385
|
+
...names.map(locale => `${locale}:previous`)
|
|
2386
|
+
];
|
|
2387
|
+
let changes = 0;
|
|
2388
|
+
const winners = new Map();
|
|
2389
|
+
for (const locale of locales) {
|
|
2390
|
+
for (const parkedId of parkedIds) {
|
|
2391
|
+
let matches = parkedPages.filter(page =>
|
|
2392
|
+
(page.parkedId === parkedId) &&
|
|
2393
|
+
(page.aposLocale === locale)
|
|
2394
|
+
);
|
|
2395
|
+
if (matches.length > 0) {
|
|
2396
|
+
if (!winners.has(parkedId)) {
|
|
2397
|
+
winners.set(parkedId, matches[0].aposDocId);
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
if (matches.length > 1) {
|
|
2401
|
+
matches = matches.sort((a, b) => a.createdAt - b.createdAt);
|
|
2402
|
+
const ids = matches.slice(1).map(page => page._id);
|
|
2403
|
+
await self.apos.doc.db.removeMany({
|
|
2404
|
+
_id: {
|
|
2405
|
+
$in: ids
|
|
2406
|
+
}
|
|
2407
|
+
});
|
|
2408
|
+
parkedPages = parkedPages.filter(page => !ids.includes(page._id));
|
|
2409
|
+
changes++;
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
const idChanges = [];
|
|
2414
|
+
for (const parkedId of parkedIds) {
|
|
2415
|
+
const aposDocId = winners.get(parkedId);
|
|
2416
|
+
const matches = parkedPages.filter(page => page.parkedId === parkedId);
|
|
2417
|
+
for (const match of matches) {
|
|
2418
|
+
if (match.aposDocId !== aposDocId) {
|
|
2419
|
+
idChanges.push([ match._id, match._id.replace(match.aposDocId, aposDocId) ]);
|
|
2420
|
+
}
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
if (idChanges.length) {
|
|
2424
|
+
// Also calls self.apos.attachment.recomputeAllDocReferences
|
|
2425
|
+
await self.apos.doc.changeDocIds(idChanges);
|
|
2426
|
+
} else if (changes > 0) {
|
|
2427
|
+
await self.apos.attachment.recomputeAllDocReferences();
|
|
2428
|
+
}
|
|
2429
|
+
});
|
|
2368
2430
|
}
|
|
2369
2431
|
};
|
|
2370
2432
|
},
|
|
@@ -22,6 +22,7 @@ module.exports = {
|
|
|
22
22
|
type: 'select',
|
|
23
23
|
label: 'apostrophe:type',
|
|
24
24
|
required: true,
|
|
25
|
+
def: self.options.apos.page.typeChoices[0].name,
|
|
25
26
|
choices: self.options.apos.page.typeChoices.map(function (type) {
|
|
26
27
|
return {
|
|
27
28
|
value: type.name,
|
|
@@ -297,6 +298,11 @@ module.exports = {
|
|
|
297
298
|
// the `title` property, but since this is a page we are including
|
|
298
299
|
// the slug as well.
|
|
299
300
|
getAutocompleteTitle(doc, query) {
|
|
301
|
+
// TODO Remove in next major version.
|
|
302
|
+
self.apos.util.warnDevOnce(
|
|
303
|
+
'deprecate-get-autocomplete-title',
|
|
304
|
+
'self.getAutocompleteTitle() is deprecated. Use the autocomplete(\'...\') query builder instead. More info at https://v3.docs.apostrophecms.org/reference/query-builders.html#autocomplete'
|
|
305
|
+
);
|
|
300
306
|
return doc.title + ' (' + doc.slug + ')';
|
|
301
307
|
},
|
|
302
308
|
// `req` determines what the user is eligible to edit, `criteria`
|
|
@@ -26,17 +26,39 @@ module.exports = {
|
|
|
26
26
|
// publicApiProjection: {
|
|
27
27
|
// title: 1,
|
|
28
28
|
// _url: 1,
|
|
29
|
+
// },
|
|
30
|
+
// By default the manager modal will get all the pieces fields below + all manager columns
|
|
31
|
+
// you can enable a projection using
|
|
32
|
+
// managerApiProjection: {
|
|
33
|
+
// _id: 1,
|
|
34
|
+
// _url: 1,
|
|
35
|
+
// aposDocId: 1,
|
|
36
|
+
// aposLocale: 1,
|
|
37
|
+
// aposMode: 1,
|
|
38
|
+
// docPermissions: 1,
|
|
39
|
+
// slug: 1,
|
|
40
|
+
// title: 1,
|
|
41
|
+
// type: 1,
|
|
42
|
+
// visibility: 1
|
|
29
43
|
// }
|
|
30
44
|
},
|
|
31
|
-
fields
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
45
|
+
fields(self) {
|
|
46
|
+
return {
|
|
47
|
+
add: {
|
|
48
|
+
slug: {
|
|
49
|
+
type: 'slug',
|
|
50
|
+
label: 'apostrophe:slug',
|
|
51
|
+
following: [ 'title', 'archived' ],
|
|
52
|
+
required: true
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
remove: self.options.singletonAuto ? [
|
|
56
|
+
'title',
|
|
57
|
+
'slug',
|
|
58
|
+
'archived',
|
|
59
|
+
'visibility'
|
|
60
|
+
] : []
|
|
61
|
+
};
|
|
40
62
|
},
|
|
41
63
|
columns(self) {
|
|
42
64
|
return {
|
|
@@ -182,6 +204,10 @@ module.exports = {
|
|
|
182
204
|
if (!self.options.name) {
|
|
183
205
|
throw new Error('@apostrophecms/pieces require name option');
|
|
184
206
|
}
|
|
207
|
+
const badFieldName = Object.keys(self.fields).indexOf('type') !== -1;
|
|
208
|
+
if (badFieldName) {
|
|
209
|
+
throw new Error(`The ${self.__meta.name} module contains a forbidden field property name: "type".`);
|
|
210
|
+
}
|
|
185
211
|
if (!self.options.label) {
|
|
186
212
|
// Englishify it
|
|
187
213
|
self.options.label = _.startCase(self.options.name);
|
|
@@ -1063,7 +1089,49 @@ module.exports = {
|
|
|
1063
1089
|
return self.apos.permission.can(req, batchOperation.permission, self.name);
|
|
1064
1090
|
}
|
|
1065
1091
|
return true;
|
|
1092
|
+
|
|
1066
1093
|
});
|
|
1094
|
+
},
|
|
1095
|
+
getManagerApiProjection(req) {
|
|
1096
|
+
if (!self.options.managerApiProjection) {
|
|
1097
|
+
return null;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
const projection = { ...self.options.managerApiProjection };
|
|
1101
|
+
self.columns.forEach(({ name }) => {
|
|
1102
|
+
const column = (name.startsWith('draft:') || name.startsWith('published:'))
|
|
1103
|
+
? name.replace(/^(draft|published):/, '')
|
|
1104
|
+
: name;
|
|
1105
|
+
|
|
1106
|
+
projection[column] = 1;
|
|
1107
|
+
});
|
|
1108
|
+
|
|
1109
|
+
return projection;
|
|
1110
|
+
},
|
|
1111
|
+
async insertIfMissing() {
|
|
1112
|
+
if (!self.options.singletonAuto) {
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1115
|
+
// Insert at startup
|
|
1116
|
+
const req = self.apos.task.getReq();
|
|
1117
|
+
const criteria = {
|
|
1118
|
+
type: self.name
|
|
1119
|
+
};
|
|
1120
|
+
if (self.options.localized) {
|
|
1121
|
+
criteria.aposLocale = {
|
|
1122
|
+
$in: Object.keys(self.apos.i18n.locales).map(locale => [ `${locale}:published`, `${locale}:draft` ]).flat()
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
const existing = await self.apos.doc.db.findOne(criteria, { _id: 1 });
|
|
1126
|
+
if (!existing) {
|
|
1127
|
+
const _new = {
|
|
1128
|
+
...self.newInstance(),
|
|
1129
|
+
aposDocId: await self.apos.doc.bestAposDocId({
|
|
1130
|
+
type: self.name
|
|
1131
|
+
})
|
|
1132
|
+
};
|
|
1133
|
+
await self.insert(req, _new);
|
|
1134
|
+
}
|
|
1067
1135
|
}
|
|
1068
1136
|
};
|
|
1069
1137
|
},
|
|
@@ -1092,11 +1160,27 @@ module.exports = {
|
|
|
1092
1160
|
editorModal: 'AposDocEditor',
|
|
1093
1161
|
managerModal: 'AposDocsManager'
|
|
1094
1162
|
});
|
|
1163
|
+
browserOptions.managerApiProjection = self.getManagerApiProjection(req);
|
|
1095
1164
|
|
|
1096
1165
|
return browserOptions;
|
|
1097
1166
|
},
|
|
1098
1167
|
find(_super, req, criteria, projection) {
|
|
1099
1168
|
return _super(req, criteria, projection).defaultSort(self.options.sort || { updatedAt: -1 });
|
|
1169
|
+
},
|
|
1170
|
+
newInstance(_super) {
|
|
1171
|
+
if (!self.options.singletonAuto) {
|
|
1172
|
+
return _super();
|
|
1173
|
+
}
|
|
1174
|
+
const slug = self.apos.util.slugify(self.options.singletonAuto?.slug || self.name);
|
|
1175
|
+
return {
|
|
1176
|
+
..._super(),
|
|
1177
|
+
// These fields are removed from the editable schema of singletons,
|
|
1178
|
+
// but we assign them directly for broader compatibility
|
|
1179
|
+
slug,
|
|
1180
|
+
title: slug,
|
|
1181
|
+
archived: false,
|
|
1182
|
+
visibility: 'public'
|
|
1183
|
+
};
|
|
1100
1184
|
}
|
|
1101
1185
|
};
|
|
1102
1186
|
},
|
|
@@ -316,6 +316,10 @@ export default {
|
|
|
316
316
|
const {
|
|
317
317
|
currentPage, pages, results, choices
|
|
318
318
|
} = await this.request({
|
|
319
|
+
...(
|
|
320
|
+
this.moduleOptions.managerApiProjection &&
|
|
321
|
+
{ project: this.moduleOptions.managerApiProjection }
|
|
322
|
+
),
|
|
319
323
|
page: this.currentPage
|
|
320
324
|
});
|
|
321
325
|
|
package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposImageControlDialog.vue
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
v-if="active"
|
|
4
|
-
v-click-outside-element="
|
|
4
|
+
v-click-outside-element="cancel"
|
|
5
5
|
class="apos-popover apos-image-control__dialog"
|
|
6
6
|
x-placement="bottom"
|
|
7
7
|
:class="{
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
:schema="schema"
|
|
17
17
|
:trigger-validation="triggerValidation"
|
|
18
18
|
v-model="docFields"
|
|
19
|
-
:utility-rail="false"
|
|
20
19
|
:modifiers="formModifiers"
|
|
21
20
|
:key="lastSelectionTime"
|
|
22
21
|
:generation="generation"
|
|
@@ -26,7 +25,7 @@
|
|
|
26
25
|
<footer class="apos-image-control__footer">
|
|
27
26
|
<AposButton
|
|
28
27
|
type="default" label="apostrophe:cancel"
|
|
29
|
-
@click="
|
|
28
|
+
@click="cancel"
|
|
30
29
|
:modifiers="formModifiers"
|
|
31
30
|
/>
|
|
32
31
|
<AposButton
|
|
@@ -55,7 +54,7 @@ export default {
|
|
|
55
54
|
required: true
|
|
56
55
|
}
|
|
57
56
|
},
|
|
58
|
-
emits: [ 'before-commands', '
|
|
57
|
+
emits: [ 'before-commands', 'done', 'cancel' ],
|
|
59
58
|
data() {
|
|
60
59
|
return {
|
|
61
60
|
generation: 1,
|
|
@@ -114,8 +113,11 @@ export default {
|
|
|
114
113
|
}
|
|
115
114
|
},
|
|
116
115
|
methods: {
|
|
117
|
-
|
|
118
|
-
this.$emit('
|
|
116
|
+
cancel() {
|
|
117
|
+
this.$emit('cancel');
|
|
118
|
+
},
|
|
119
|
+
done() {
|
|
120
|
+
this.$emit('done');
|
|
119
121
|
},
|
|
120
122
|
save() {
|
|
121
123
|
this.triggerValidation = true;
|
|
@@ -125,23 +127,25 @@ export default {
|
|
|
125
127
|
}
|
|
126
128
|
const image = this.docFields.data._image[0];
|
|
127
129
|
this.docFields.data.imageId = image && image.aposDocId;
|
|
130
|
+
this.docFields.data.alt = image && image.alt;
|
|
128
131
|
this.$emit('before-commands');
|
|
129
132
|
this.editor.commands.setImage({
|
|
130
133
|
imageId: this.docFields.data.imageId,
|
|
131
134
|
caption: this.docFields.data.caption,
|
|
132
|
-
style: this.docFields.data.style
|
|
135
|
+
style: this.docFields.data.style,
|
|
136
|
+
alt: this.docFields.data.alt
|
|
133
137
|
});
|
|
134
|
-
this.
|
|
138
|
+
this.done();
|
|
135
139
|
});
|
|
136
140
|
},
|
|
137
141
|
keyboardHandler(e) {
|
|
138
142
|
if (e.keyCode === 27) {
|
|
139
|
-
this.
|
|
143
|
+
this.cancel();
|
|
140
144
|
}
|
|
141
145
|
if (e.keyCode === 13) {
|
|
142
146
|
if (this.docFields.data.href || e.metaKey) {
|
|
143
147
|
this.save();
|
|
144
|
-
this.
|
|
148
|
+
this.done();
|
|
145
149
|
}
|
|
146
150
|
e.preventDefault();
|
|
147
151
|
}
|