apostrophe 3.41.1 → 3.43.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 +60 -2
- package/modules/@apostrophecms/admin-bar/index.js +1 -0
- package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue +1 -1
- package/modules/@apostrophecms/asset/lib/globalIcons.js +3 -0
- package/modules/@apostrophecms/doc/ui/apos/apps/AposDoc.js +42 -0
- package/modules/@apostrophecms/doc-type/index.js +82 -51
- package/modules/@apostrophecms/doc-type/ui/apos/components/AposDocEditor.vue +10 -3
- package/modules/@apostrophecms/file/index.js +2 -1
- package/modules/@apostrophecms/file-tag/index.js +2 -1
- package/modules/@apostrophecms/i18n/i18n/en.json +116 -109
- package/modules/@apostrophecms/i18n/i18n/es.json +83 -78
- package/modules/@apostrophecms/i18n/i18n/fr.json +89 -84
- package/modules/@apostrophecms/i18n/i18n/pt-BR.json +81 -76
- package/modules/@apostrophecms/i18n/i18n/sk.json +91 -86
- package/modules/@apostrophecms/image/index.js +5 -1
- package/modules/@apostrophecms/image/ui/apos/components/AposMediaManager.vue +6 -1
- package/modules/@apostrophecms/image-tag/index.js +2 -1
- package/modules/@apostrophecms/login/index.js +2 -1
- package/modules/@apostrophecms/login/ui/apos/components/TheAposLoginHeader.vue +1 -1
- package/modules/@apostrophecms/modal/ui/apos/mixins/AposDocsManagerMixin.js +35 -2
- package/modules/@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js +2 -2
- package/modules/@apostrophecms/page/index.js +8 -4
- package/modules/@apostrophecms/piece-type/index.js +71 -3
- package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManager.vue +4 -64
- package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManagerDisplay.vue +9 -2
- package/modules/@apostrophecms/piece-type/ui/apos/components/AposUtilityOperations.vue +126 -0
- package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposRichTextWidgetEditor.vue +10 -10
- package/modules/@apostrophecms/rich-text-widget/ui/apos/tiptap-extensions/Default.js +44 -48
- package/modules/@apostrophecms/schema/index.js +105 -35
- package/modules/@apostrophecms/schema/lib/addFieldTypes.js +21 -2
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputArray.vue +348 -113
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputRelationship.vue +76 -22
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputSelect.vue +6 -0
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputString.vue +1 -1
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputWrapper.vue +7 -1
- package/modules/@apostrophecms/schema/ui/apos/components/AposSchema.vue +18 -4
- package/modules/@apostrophecms/schema/ui/apos/components/AposSearchList.vue +111 -30
- package/modules/@apostrophecms/submitted-draft/index.js +1 -1
- package/modules/@apostrophecms/ui/ui/apos/components/AposSlat.vue +11 -6
- package/modules/@apostrophecms/ui/ui/apos/components/AposSlatList.vue +9 -5
- package/modules/@apostrophecms/ui/ui/apos/lib/i18next.js +1 -0
- package/modules/@apostrophecms/user/index.js +2 -1
- package/modules/@apostrophecms/widget-type/index.js +6 -3
- package/package.json +15 -15
- package/test/login.js +6 -1
- package/test/pieces-tasks.js +94 -0
- package/test/pieces.js +726 -13
- package/test/schemas.js +392 -22
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.43.0 (2023-03-29)
|
|
4
|
+
|
|
5
|
+
### Adds
|
|
6
|
+
|
|
7
|
+
* Add the possibility to override the default "Add Item" button label by setting the `itemLabel` option of an `array` field.
|
|
8
|
+
* Adds `touch` task for every piece type. This task invokes `update` on each piece, which will execute all of the same event handlers that normally execute when a piece of that type is updated. Example usage: `node app article:touch`.
|
|
9
|
+
|
|
10
|
+
### Fixes
|
|
11
|
+
|
|
12
|
+
* Hide the suggestion help from the relationship input list when the user starts typing a search term.
|
|
13
|
+
* Hide the suggestion hint from the relationship input list when the user starts typing a search term except when there are no matches to display.
|
|
14
|
+
* Disable context menu for related items when their `relationship` field has no sub-[`fields`](https://v3.docs.apostrophecms.org/guide/relationships.html#providing-context-with-fields) configured.
|
|
15
|
+
|
|
16
|
+
## 3.42.0 (2023-03-16)
|
|
17
|
+
|
|
18
|
+
### Adds
|
|
19
|
+
|
|
20
|
+
* You can now set `style: table` on inline arrays. It will display the array as a regular HTML table instead of an accordion.
|
|
21
|
+
See the [array field documentation](https://v3.docs.apostrophecms.org/reference/field-types/array.html#settings) for more information.
|
|
22
|
+
* You can now set `draggable: false` on inline arrays. It will disable the drag and drop feature. Useful when the order is not significant.
|
|
23
|
+
See the [array field documentation](https://v3.docs.apostrophecms.org/reference/field-types/array.html#settings) for more information.
|
|
24
|
+
* You can now set the label and icon to display on inline arrays when they are empty.
|
|
25
|
+
See the [array field documentation](https://v3.docs.apostrophecms.org/reference/field-types/array.html#whenEmpty) for more information.
|
|
26
|
+
* We have added a new and improved suggestion UI to relationship fields.
|
|
27
|
+
* The `utilityOperations` feature of piece types now supports additional properties:
|
|
28
|
+
`relationship: true` (show the operation only when editing a relationship), `relationship: false` (never show
|
|
29
|
+
the operation when editing a relationship), `button: true`, `icon` and `iconOnly: true`.
|
|
30
|
+
When `button: true` is specified, the operation appears as a standalone button rather than
|
|
31
|
+
being tucked away in the "more" menu.
|
|
32
|
+
* In addition, `utilityOperations` can now specify `eventOptions` with an `event` subproperty
|
|
33
|
+
instead of `modalOptions`. This is useful with the new `edit` event (see below).
|
|
34
|
+
* Those extending our admin UI on the front end can now open a modal to create or edit a page or piece by calling
|
|
35
|
+
`await apos.doc.edit({ type: 'article' })` (the type here is an example). To edit an existing document add an
|
|
36
|
+
`_id` property. To copy an existing document (like our "duplicate" feature) add a `copyOf`
|
|
37
|
+
property. When creating new pages, `type` can be sent to `@apostrophecms/page` for convenience
|
|
38
|
+
(note that the `type` property does not override the default or current page type in the editor).
|
|
39
|
+
* The `edit` Apostrophe event is now available and takes an object with the same properties
|
|
40
|
+
as above. This is useful when configuring `utilityOperations`.
|
|
41
|
+
* The `content-changed` Apostrophe event can now be emitted with a `select: true` property. If a
|
|
42
|
+
document manager for the relevant content type is open, it will attempt to add the document to the
|
|
43
|
+
current selection. Currently this works best with newly inserted documents.
|
|
44
|
+
* Localized strings in the admin UI can now use `$t(key)` to localize a string inside
|
|
45
|
+
an interpolated variable. This was accomplished by setting `skipOnVariables` to false
|
|
46
|
+
for i18next, solely on the front end for admin UI purposes.
|
|
47
|
+
* The syntax of the method defined for dynamic `choices` now accepts a module prefix to get the method from, and the `()` suffix.
|
|
48
|
+
This has been done for consistency with the external conditions syntax shipped in the previous release. See the documentation for more information.
|
|
49
|
+
* Added the `viewPermission` property of schema fields, and renamed `permission` to `editPermission` (with backwards
|
|
50
|
+
compatibility) for clarity. You can now decide if a schema field requires permissions to be visible or editable.
|
|
51
|
+
See the documentation for more information.
|
|
52
|
+
* Display the right environment label on login page. By default, based on `NODE_ENV`, overriden by `environmentLabel` option in `@apostrophecms/login` module. The environment variable `APOS_ENV_LABEL` will override this. Note that `NODE_ENV` should generally only be set to `development` (the default) or `production` as many Node.js modules opt into optimizations suitable for all deployed environments when it is set to `production`. This is why we offer the separate `APOS_ENV_LABEL` variable.
|
|
53
|
+
|
|
54
|
+
### Fixes
|
|
55
|
+
|
|
56
|
+
* Do not log unnecessary "required" errors for hidden fields.
|
|
57
|
+
* Fixed a bug that prevented "Text Align" from working properly in the rich text editor in certain cases.
|
|
58
|
+
* Fix typo in `@apostrophecms/doc-type` and `@apostrophecms/submitted-drafts` where we were using `canCreate` instead of `showCreate` to display the `Create New` button or showing the `Copy` button in `Manager` modals.
|
|
59
|
+
* Send external condition results in an object so that numbers are supported as returned values.
|
|
60
|
+
|
|
3
61
|
## 3.41.1 (2023-03-07)
|
|
4
62
|
|
|
5
63
|
No changes. Publishing to make sure 3.x is tagged `latest` in npm, rather than 2.x.
|
|
@@ -8,8 +66,8 @@ No changes. Publishing to make sure 3.x is tagged `latest` in npm, rather than 2
|
|
|
8
66
|
|
|
9
67
|
### Adds
|
|
10
68
|
|
|
11
|
-
* Handle external conditions to display fields according to the result of a module method, or multiple methods from different modules.
|
|
12
|
-
This can be useful for displaying fields according to the result of an external API or any business logic run on the server.
|
|
69
|
+
* Handle external conditions to display fields according to the result of a module method, or multiple methods from different modules.
|
|
70
|
+
This can be useful for displaying fields according to the result of an external API or any business logic run on the server. See the documentation for more information.
|
|
13
71
|
|
|
14
72
|
### Fixes
|
|
15
73
|
|
|
@@ -338,6 +338,7 @@ module.exports = {
|
|
|
338
338
|
submitted: context.submitted,
|
|
339
339
|
lastPublishedAt: context.lastPublishedAt,
|
|
340
340
|
_edit: context._edit,
|
|
341
|
+
_publish: context._publish,
|
|
341
342
|
aposMode: context.aposMode,
|
|
342
343
|
aposLocale: context.aposLocale,
|
|
343
344
|
aposDocId: context.aposDocId
|
|
@@ -98,7 +98,7 @@ export default {
|
|
|
98
98
|
return !!this.patchesSinceSave.length;
|
|
99
99
|
},
|
|
100
100
|
canPublish() {
|
|
101
|
-
return apos.modules[this.context.type].canPublish;
|
|
101
|
+
return this.context._publish || apos.modules[this.context.type].canPublish;
|
|
102
102
|
},
|
|
103
103
|
readyToPublish() {
|
|
104
104
|
if (this.canPublish) {
|
|
@@ -15,6 +15,7 @@ module.exports = {
|
|
|
15
15
|
'arrow-left-icon': 'ArrowLeft',
|
|
16
16
|
'arrow-right-icon': 'ArrowRight',
|
|
17
17
|
'arrow-up-icon': 'ArrowUp',
|
|
18
|
+
'binoculars-icon': 'Binoculars',
|
|
18
19
|
'calendar-icon': 'Calendar',
|
|
19
20
|
'check-all-icon': 'CheckAll',
|
|
20
21
|
'check-bold-icon': 'CheckBold',
|
|
@@ -101,6 +102,8 @@ module.exports = {
|
|
|
101
102
|
'redo-icon': 'RedoVariant',
|
|
102
103
|
'refresh-icon': 'Refresh',
|
|
103
104
|
'sign-text-icon': 'SignText',
|
|
105
|
+
'tag-icon': 'Tag',
|
|
106
|
+
'text-box-icon': 'TextBox',
|
|
104
107
|
'text-box-remove-icon': 'TextBoxRemove',
|
|
105
108
|
'trash-can-icon': 'TrashCan',
|
|
106
109
|
'trash-can-outline-icon': 'TrashCanOutline',
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// High-level conveniences for working with documents in Apostrophe
|
|
2
|
+
// on the front end, so that developers need only know the document
|
|
3
|
+
// type they want and do not have to look up modal names in module
|
|
4
|
+
// configuration etc.
|
|
5
|
+
|
|
6
|
+
export default () => {
|
|
7
|
+
// Create or edit a document. `type` must be the document type, or
|
|
8
|
+
// `@apostrophecms/page`.
|
|
9
|
+
//
|
|
10
|
+
// `_id` should be the `_id` of the existing document to edit; leave
|
|
11
|
+
// blank to create a new document.
|
|
12
|
+
//
|
|
13
|
+
// `copyOf` is an optional, existing document from which properties should be copied.
|
|
14
|
+
//
|
|
15
|
+
// On success, returns the new or updated document. If the modal is cancelled,
|
|
16
|
+
// `undefined` is returned. Be sure to `await` the result.
|
|
17
|
+
apos.doc.edit = async ({
|
|
18
|
+
type,
|
|
19
|
+
_id,
|
|
20
|
+
copyOf
|
|
21
|
+
}) => {
|
|
22
|
+
if (!type) {
|
|
23
|
+
throw new Error('You must specify the type of document to edit.');
|
|
24
|
+
}
|
|
25
|
+
if (apos.page.validPageTypes.includes(type)) {
|
|
26
|
+
type = '@apostrophecms/page';
|
|
27
|
+
}
|
|
28
|
+
const modal = apos.modules[type]?.components?.editorModal;
|
|
29
|
+
if (!modal) {
|
|
30
|
+
throw new Error(`${type} is not a valid piece or page type, or cannot be edited`);
|
|
31
|
+
}
|
|
32
|
+
return apos.modal.execute(modal, {
|
|
33
|
+
moduleName: type,
|
|
34
|
+
docId: _id,
|
|
35
|
+
copyOf
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
// If you don't care about the returned value, you can emit an
|
|
39
|
+
// 'edit' apostrophe event with the same object you would pass to
|
|
40
|
+
// apos.doc.edit().
|
|
41
|
+
apos.bus.$on('edit', apos.doc.edit);
|
|
42
|
+
};
|
|
@@ -10,7 +10,13 @@ module.exports = {
|
|
|
10
10
|
publishRole: 'editor',
|
|
11
11
|
viewRole: false,
|
|
12
12
|
previewDraft: true,
|
|
13
|
-
relatedDocType: null
|
|
13
|
+
relatedDocType: null,
|
|
14
|
+
relationshipSuggestionLabel: 'apostrophe:relationshipSuggestionLabel',
|
|
15
|
+
relationshipSuggestionHelp: 'apostrophe:relationshipSuggestionHelp',
|
|
16
|
+
relationshipSuggestionLimit: 25,
|
|
17
|
+
relationshipSuggestionSort: { updatedAt: -1 },
|
|
18
|
+
relationshipSuggestionIcon: 'text-box-icon',
|
|
19
|
+
relationshipSuggestionFields: [ 'slug' ]
|
|
14
20
|
},
|
|
15
21
|
cascades: [ 'fields' ],
|
|
16
22
|
fields(self) {
|
|
@@ -77,7 +83,7 @@ module.exports = {
|
|
|
77
83
|
self.__meta.name === '@apostrophecms/global' ||
|
|
78
84
|
self.apos.instanceOf(self, '@apostrophecms/any-page-type') ||
|
|
79
85
|
self.apos.instanceOf(self, '@apostrophecms/page-type') ||
|
|
80
|
-
self.options.
|
|
86
|
+
self.options.showCreate === false ||
|
|
81
87
|
self.options.showPermissions === false
|
|
82
88
|
) {
|
|
83
89
|
return null;
|
|
@@ -212,54 +218,12 @@ module.exports = {
|
|
|
212
218
|
handlers(self) {
|
|
213
219
|
return {
|
|
214
220
|
beforeSave: {
|
|
215
|
-
async updateCacheField(req, doc) {
|
|
216
|
-
const relatedDocsIds = self.getRelatedDocsIds(req, doc);
|
|
217
|
-
|
|
218
|
-
// - Remove current doc reference from docs that include it
|
|
219
|
-
// - Update these docs' cache field
|
|
220
|
-
await self.apos.doc.db.updateMany({
|
|
221
|
-
relatedReverseIds: { $in: [ doc.aposDocId ] },
|
|
222
|
-
aposLocale: { $in: [ doc.aposLocale, null ] }
|
|
223
|
-
}, {
|
|
224
|
-
$pull: { relatedReverseIds: doc.aposDocId },
|
|
225
|
-
$set: { cacheInvalidatedAt: doc.updatedAt }
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
if (relatedDocsIds.length) {
|
|
229
|
-
// - Add current doc reference to related docs
|
|
230
|
-
// - Update related docs' cache field
|
|
231
|
-
await self.apos.doc.db.updateMany({
|
|
232
|
-
aposDocId: { $in: relatedDocsIds },
|
|
233
|
-
aposLocale: { $in: [ doc.aposLocale, null ] }
|
|
234
|
-
}, {
|
|
235
|
-
$push: { relatedReverseIds: doc.aposDocId },
|
|
236
|
-
$set: { cacheInvalidatedAt: doc.updatedAt }
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (doc.relatedReverseIds && doc.relatedReverseIds.length) {
|
|
241
|
-
// Update related reverse docs' cache field
|
|
242
|
-
await self.apos.doc.db.updateMany({
|
|
243
|
-
aposDocId: { $in: doc.relatedReverseIds },
|
|
244
|
-
aposLocale: { $in: [ doc.aposLocale, null ] }
|
|
245
|
-
}, {
|
|
246
|
-
$set: { cacheInvalidatedAt: doc.updatedAt }
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
if (doc._parentSlug) {
|
|
251
|
-
// Update piece index page's cache field
|
|
252
|
-
await self.apos.doc.db.updateOne({
|
|
253
|
-
slug: doc._parentSlug,
|
|
254
|
-
aposLocale: { $in: [ doc.aposLocale, null ] }
|
|
255
|
-
}, {
|
|
256
|
-
$set: { cacheInvalidatedAt: doc.updatedAt }
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
},
|
|
260
221
|
prepareForStorage(req, doc) {
|
|
261
222
|
self.apos.schema.prepareForStorage(req, doc);
|
|
262
223
|
},
|
|
224
|
+
async updateCacheField(req, doc) {
|
|
225
|
+
await self.updateCacheField(req, doc);
|
|
226
|
+
},
|
|
263
227
|
slugPrefix(req, doc) {
|
|
264
228
|
const prefix = self.options.slugPrefix;
|
|
265
229
|
if (prefix) {
|
|
@@ -398,6 +362,51 @@ module.exports = {
|
|
|
398
362
|
|
|
399
363
|
methods(self) {
|
|
400
364
|
return {
|
|
365
|
+
async updateCacheField(req, doc) {
|
|
366
|
+
const relatedDocsIds = self.getRelatedDocsIds(req, doc);
|
|
367
|
+
|
|
368
|
+
// - Remove current doc reference from docs that include it
|
|
369
|
+
// - Update these docs' cache field
|
|
370
|
+
await self.apos.doc.db.updateMany({
|
|
371
|
+
relatedReverseIds: { $in: [ doc.aposDocId ] },
|
|
372
|
+
aposLocale: { $in: [ doc.aposLocale, null ] }
|
|
373
|
+
}, {
|
|
374
|
+
$pull: { relatedReverseIds: doc.aposDocId },
|
|
375
|
+
$set: { cacheInvalidatedAt: doc.updatedAt }
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
if (relatedDocsIds.length) {
|
|
379
|
+
// - Add current doc reference to related docs
|
|
380
|
+
// - Update related docs' cache field
|
|
381
|
+
await self.apos.doc.db.updateMany({
|
|
382
|
+
aposDocId: { $in: relatedDocsIds },
|
|
383
|
+
aposLocale: { $in: [ doc.aposLocale, null ] }
|
|
384
|
+
}, {
|
|
385
|
+
$push: { relatedReverseIds: doc.aposDocId },
|
|
386
|
+
$set: { cacheInvalidatedAt: doc.updatedAt }
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (doc.relatedReverseIds && doc.relatedReverseIds.length) {
|
|
391
|
+
// Update related reverse docs' cache field
|
|
392
|
+
await self.apos.doc.db.updateMany({
|
|
393
|
+
aposDocId: { $in: doc.relatedReverseIds },
|
|
394
|
+
aposLocale: { $in: [ doc.aposLocale, null ] }
|
|
395
|
+
}, {
|
|
396
|
+
$set: { cacheInvalidatedAt: doc.updatedAt }
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
if (doc._parentSlug) {
|
|
401
|
+
// Update piece index page's cache field
|
|
402
|
+
await self.apos.doc.db.updateOne({
|
|
403
|
+
slug: doc._parentSlug,
|
|
404
|
+
aposLocale: { $in: [ doc.aposLocale, null ] }
|
|
405
|
+
}, {
|
|
406
|
+
$set: { cacheInvalidatedAt: doc.updatedAt }
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
},
|
|
401
410
|
addContextMenu() {
|
|
402
411
|
self.apos.doc.addContextOperation(self.__meta.name, {
|
|
403
412
|
action: 'shareDraft',
|
|
@@ -412,7 +421,7 @@ module.exports = {
|
|
|
412
421
|
const relatedDocsIds = [];
|
|
413
422
|
const handlers = {
|
|
414
423
|
relationship: (field, doc) => {
|
|
415
|
-
relatedDocsIds.push(...doc[field.
|
|
424
|
+
relatedDocsIds.push(...(doc[field.idsStorage] || []));
|
|
416
425
|
}
|
|
417
426
|
};
|
|
418
427
|
|
|
@@ -522,13 +531,16 @@ module.exports = {
|
|
|
522
531
|
change.text = doc.title;
|
|
523
532
|
},
|
|
524
533
|
// Return a new schema containing only fields for which the
|
|
525
|
-
// current user has the permission specified by the `
|
|
526
|
-
// property of the schema field, or there is no `
|
|
534
|
+
// current user has the permission specified by the `editPermission`
|
|
535
|
+
// property of the schema field, or there is no `editPermission`|`viewPermission` property for the field.
|
|
527
536
|
allowedSchema(req) {
|
|
528
537
|
let disabled;
|
|
529
538
|
let type;
|
|
530
539
|
const schema = _.filter(self.schema, function (field) {
|
|
531
|
-
return !field.
|
|
540
|
+
return (!field.editPermission && !field.viewPermission) ||
|
|
541
|
+
(field.editPermission && self.apos.permission.can(req, field.editPermission.action, field.editPermission.type)) ||
|
|
542
|
+
(field.viewPermission && self.apos.permission.can(req, field.viewPermission.action, field.viewPermission.type)) ||
|
|
543
|
+
false;
|
|
532
544
|
});
|
|
533
545
|
const typeIndex = _.findIndex(schema, { name: 'type' });
|
|
534
546
|
if (typeIndex !== -1) {
|
|
@@ -1375,6 +1387,25 @@ module.exports = {
|
|
|
1375
1387
|
});
|
|
1376
1388
|
|
|
1377
1389
|
return draft;
|
|
1390
|
+
},
|
|
1391
|
+
|
|
1392
|
+
// Remove forbidden fields from document
|
|
1393
|
+
// A forbidden field is a field for which the current user does not have the appropriate viewPermission to see it
|
|
1394
|
+
removeForbiddenFields(req, doc) {
|
|
1395
|
+
if (!doc) {
|
|
1396
|
+
return doc;
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
const forbiddenSchemaFields = Object.values(self.schema)
|
|
1400
|
+
.filter(field => {
|
|
1401
|
+
return field.viewPermission && !self.apos.permission.can(req, field.viewPermission.action, field.viewPermission.type);
|
|
1402
|
+
});
|
|
1403
|
+
|
|
1404
|
+
forbiddenSchemaFields.forEach(field => {
|
|
1405
|
+
delete doc[field.name];
|
|
1406
|
+
});
|
|
1407
|
+
|
|
1408
|
+
return doc;
|
|
1378
1409
|
}
|
|
1379
1410
|
};
|
|
1380
1411
|
},
|
|
@@ -174,6 +174,13 @@ export default {
|
|
|
174
174
|
followingUtils() {
|
|
175
175
|
return this.followingValues('utility');
|
|
176
176
|
},
|
|
177
|
+
canPublish() {
|
|
178
|
+
if (this.original && this.original._id) {
|
|
179
|
+
return this.original._publish;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return this.moduleOptions.canPublish;
|
|
183
|
+
},
|
|
177
184
|
saveDisabled() {
|
|
178
185
|
if (this.restoreOnly) {
|
|
179
186
|
// Can always restore if it's a read-only view of the archive
|
|
@@ -197,7 +204,7 @@ export default {
|
|
|
197
204
|
if (!this.manuallyPublished) {
|
|
198
205
|
return true;
|
|
199
206
|
}
|
|
200
|
-
if (this.
|
|
207
|
+
if (this.canPublish) {
|
|
201
208
|
// Primary button is "publish". If it is previously published and the
|
|
202
209
|
// draft is not modified since then, don't allow it
|
|
203
210
|
return this.published && !this.isModifiedFromPublished;
|
|
@@ -261,7 +268,7 @@ export default {
|
|
|
261
268
|
if (this.restoreOnly) {
|
|
262
269
|
return 'apostrophe:restore';
|
|
263
270
|
} else if (this.manuallyPublished) {
|
|
264
|
-
if (this.
|
|
271
|
+
if (this.canPublish) {
|
|
265
272
|
if (this.copyOf) {
|
|
266
273
|
return 'apostrophe:publish';
|
|
267
274
|
} else if (this.original && this.original.lastPublishedAt) {
|
|
@@ -468,7 +475,7 @@ export default {
|
|
|
468
475
|
await this.loadDoc();
|
|
469
476
|
},
|
|
470
477
|
async onSave(navigate = false) {
|
|
471
|
-
if (this.
|
|
478
|
+
if (this.canPublish || !this.manuallyPublished) {
|
|
472
479
|
await this.save({
|
|
473
480
|
andPublish: this.manuallyPublished,
|
|
474
481
|
navigate
|
|
@@ -23,7 +23,8 @@ module.exports = {
|
|
|
23
23
|
showPermissions: true,
|
|
24
24
|
// Files should by default be considered "related documents" when localizing
|
|
25
25
|
// another document that references them
|
|
26
|
-
relatedDocument: true
|
|
26
|
+
relatedDocument: true,
|
|
27
|
+
relationshipSuggestionIcon: 'file-document-icon'
|
|
27
28
|
},
|
|
28
29
|
fields: {
|
|
29
30
|
remove: [ 'visibility' ],
|