apostrophe 4.28.1 → 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 +29 -4
- package/README.md +2 -2
- 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 -8
- 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 +17 -17
- package/test/add-missing-schema-fields-project/node_modules/.package-lock.json +2 -2
- 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/.claude/settings.local.json +0 -15
- package/modules/@apostrophecms/layout-widget/ui/apos/components/AposLayoutColControlDialog.vue +0 -171
|
@@ -92,6 +92,16 @@ export default {
|
|
|
92
92
|
moduleLabels: {
|
|
93
93
|
type: Object,
|
|
94
94
|
default: null
|
|
95
|
+
},
|
|
96
|
+
showUnpublish: {
|
|
97
|
+
type: Boolean,
|
|
98
|
+
default() {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
crossLocale: {
|
|
103
|
+
type: Boolean,
|
|
104
|
+
default: false
|
|
95
105
|
}
|
|
96
106
|
},
|
|
97
107
|
emits: [ 'menu-open', 'menu-close', 'close' ],
|
|
@@ -105,6 +115,12 @@ export default {
|
|
|
105
115
|
},
|
|
106
116
|
computed: {
|
|
107
117
|
menu() {
|
|
118
|
+
// TODO: Register core context actions (edit, preview,
|
|
119
|
+
// copy, localize, archive, etc.) as custom operations
|
|
120
|
+
// via `addContextOperation`. This would let us unify
|
|
121
|
+
// cross-locale gating through the `crossLocale`
|
|
122
|
+
// flag on each operation, eliminating the manual
|
|
123
|
+
// `!this.crossLocale` wrapping below.
|
|
108
124
|
const menu = [
|
|
109
125
|
// TODO
|
|
110
126
|
// ...(this.isModifiedFromPublished ? [
|
|
@@ -128,64 +144,76 @@ export default {
|
|
|
128
144
|
}
|
|
129
145
|
]
|
|
130
146
|
: []),
|
|
131
|
-
|
|
147
|
+
// In cross-locale mode, only Edit and Preview are safe.
|
|
148
|
+
// All other built-in ops are hidden.
|
|
149
|
+
...(!this.crossLocale
|
|
132
150
|
? [
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
...((this.showDismissSubmission && this.canDismissSubmission)
|
|
152
|
+
? [
|
|
153
|
+
{
|
|
154
|
+
label: 'apostrophe:dismissSubmission',
|
|
155
|
+
action: 'dismissSubmission'
|
|
156
|
+
}
|
|
157
|
+
]
|
|
158
|
+
: []),
|
|
159
|
+
...(this.showCopy && this.canCopy
|
|
160
|
+
? [
|
|
161
|
+
{
|
|
162
|
+
label: 'apostrophe:duplicate',
|
|
163
|
+
action: 'copy'
|
|
164
|
+
}
|
|
165
|
+
]
|
|
166
|
+
: []),
|
|
167
|
+
...(this.canLocalize
|
|
168
|
+
? [
|
|
169
|
+
{
|
|
170
|
+
label: 'apostrophe:localize',
|
|
171
|
+
action: 'localize'
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
: [])
|
|
153
175
|
]
|
|
154
176
|
: []),
|
|
155
177
|
...this.customMenusByContext,
|
|
156
|
-
...(
|
|
178
|
+
...(!this.crossLocale
|
|
157
179
|
? [
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
180
|
+
...((this.showDiscardDraft && this.canDiscardDraft)
|
|
181
|
+
? [
|
|
182
|
+
{
|
|
183
|
+
label: this.context.lastPublishedAt
|
|
184
|
+
? 'apostrophe:discardDraft'
|
|
185
|
+
: 'apostrophe:deleteDraft',
|
|
186
|
+
action: 'discardDraft',
|
|
187
|
+
modifiers: [ 'danger' ]
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
: []),
|
|
191
|
+
...(this.showArchive && this.canArchive
|
|
192
|
+
? [
|
|
193
|
+
{
|
|
194
|
+
label: 'apostrophe:archive',
|
|
195
|
+
action: 'archive',
|
|
196
|
+
modifiers: [ 'danger' ]
|
|
197
|
+
}
|
|
198
|
+
]
|
|
199
|
+
: []),
|
|
200
|
+
...(this.showUnpublish && this.canUnpublish
|
|
201
|
+
? [
|
|
202
|
+
{
|
|
203
|
+
label: 'apostrophe:unpublish',
|
|
204
|
+
action: 'unpublish',
|
|
205
|
+
modifiers: [ 'danger' ]
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
: []),
|
|
209
|
+
...(this.showRestore && this.canRestore
|
|
210
|
+
? [
|
|
211
|
+
{
|
|
212
|
+
label: 'apostrophe:restore',
|
|
213
|
+
action: 'restore'
|
|
214
|
+
}
|
|
215
|
+
]
|
|
216
|
+
: [])
|
|
189
217
|
]
|
|
190
218
|
: [])
|
|
191
219
|
];
|
|
@@ -208,8 +236,14 @@ export default {
|
|
|
208
236
|
},
|
|
209
237
|
customOperationsByContext() {
|
|
210
238
|
return this.customOperations.filter(({
|
|
211
|
-
manuallyPublished, hasUrl, conditions, context,
|
|
239
|
+
manuallyPublished, hasUrl, conditions, context,
|
|
240
|
+
if: ifProps, moduleIf, crossLocale
|
|
212
241
|
}) => {
|
|
242
|
+
// In cross-locale mode, only show operations explicitly marked as safe
|
|
243
|
+
if (this.crossLocale && !crossLocale) {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
|
|
213
247
|
if (typeof manuallyPublished === 'boolean' && manuallyPublished !== this.manuallyPublished) {
|
|
214
248
|
return false;
|
|
215
249
|
}
|
|
@@ -433,13 +467,19 @@ export default {
|
|
|
433
467
|
this[item.action](this.context);
|
|
434
468
|
},
|
|
435
469
|
async edit(doc) {
|
|
470
|
+
const props = {
|
|
471
|
+
moduleName: this.moduleName,
|
|
472
|
+
docId: doc._id,
|
|
473
|
+
type: doc.type
|
|
474
|
+
};
|
|
475
|
+
// Cross-locale mode suported.
|
|
476
|
+
if (this.crossLocale && doc.aposLocale) {
|
|
477
|
+
props.locale = doc.aposLocale.split(':')[0];
|
|
478
|
+
}
|
|
436
479
|
await apos.modal.execute(
|
|
437
480
|
doc._aposEditorModal || this.moduleOptions.components.editorModal,
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
docId: doc._id,
|
|
441
|
-
type: doc.type
|
|
442
|
-
});
|
|
481
|
+
props
|
|
482
|
+
);
|
|
443
483
|
},
|
|
444
484
|
preview(doc) {
|
|
445
485
|
window.open(doc._url, '_blank').focus();
|
|
@@ -490,6 +530,11 @@ export default {
|
|
|
490
530
|
...docProps(doc),
|
|
491
531
|
...operation.props
|
|
492
532
|
};
|
|
533
|
+
// In cross-locale mode, pass the doc's locale so the modal
|
|
534
|
+
// opens in the correct locale context.
|
|
535
|
+
if (this.crossLocale && doc.aposLocale) {
|
|
536
|
+
props.locale = doc.aposLocale.split(':')[0];
|
|
537
|
+
}
|
|
493
538
|
if (operation.type === 'event') {
|
|
494
539
|
apos.bus.$emit(operation.action, props);
|
|
495
540
|
return;
|
|
@@ -105,18 +105,112 @@ module.exports = {
|
|
|
105
105
|
attachmentDocIds: []
|
|
106
106
|
};
|
|
107
107
|
},
|
|
108
|
-
|
|
108
|
+
// Returns the pretty URL base path (e.g. `/files`) when
|
|
109
|
+
// pretty URLs are enabled, or `null` otherwise.
|
|
110
|
+
// The returned path is prefix-qualified. If `options.relative`
|
|
111
|
+
// is true, the path is relative (no origin).
|
|
112
|
+
getPrettyUrlBase(req, { relative = false } = {}) {
|
|
113
|
+
if (!self.options.prettyUrls) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
const base = relative
|
|
117
|
+
? self.apos.url.getBaseUrl(req, {
|
|
118
|
+
relative: true,
|
|
119
|
+
localePrefix: true
|
|
120
|
+
})
|
|
121
|
+
: req.prefix;
|
|
122
|
+
return `${base}${self.options.prettyUrlDir}`;
|
|
123
|
+
},
|
|
124
|
+
// Returns the pretty-URL path component for a file doc.
|
|
125
|
+
// E.g. `/my-document.pdf` — just the filename portion,
|
|
126
|
+
// without any base, prefix, or origin.
|
|
127
|
+
// Returns `null` when pretty URLs are disabled or the
|
|
128
|
+
// doc has no attachment. Works with any object that has
|
|
129
|
+
// `slug` and `attachment.extension` (including the
|
|
130
|
+
// lightweight projections used by `applyPrettyUrlPaths`).
|
|
131
|
+
getPrettyPath(doc) {
|
|
132
|
+
if (!self.options.prettyUrls || !doc.attachment) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
const slug = doc.slug.replace(self.options.slugPrefix || '', '');
|
|
136
|
+
return `/${slug}.${doc.attachment.extension}`;
|
|
137
|
+
},
|
|
138
|
+
// When `options.relative` is true, pretty URLs are built
|
|
139
|
+
// with only the prefix + prettyUrlDir (no origin).
|
|
140
|
+
addUrls(req, files, { relative = false } = {}) {
|
|
141
|
+
const prettyBase = self.getPrettyUrlBase(req, { relative });
|
|
109
142
|
for (const file of files) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const { extension } = file.attachment;
|
|
114
|
-
file._url = `${req.prefix}${self.options.prettyUrlDir}/${file.slug.replace(self.options.slugPrefix || '', '')}.${extension}`;
|
|
143
|
+
const prettyPath = self.getPrettyPath(file);
|
|
144
|
+
if (prettyBase && prettyPath) {
|
|
145
|
+
file._url = `${prettyBase}${prettyPath}`;
|
|
115
146
|
file.attachment._prettyUrl = file._url;
|
|
116
|
-
} else {
|
|
147
|
+
} else if (file.attachment) {
|
|
117
148
|
file._url = self.apos.attachment.url(file.attachment);
|
|
118
149
|
}
|
|
119
150
|
}
|
|
151
|
+
},
|
|
152
|
+
// Mutates `attachmentMeta.results` in-place, replacing
|
|
153
|
+
// uploadfs paths with pretty URL paths for file pieces
|
|
154
|
+
// that have pretty URLs enabled. Adds a `base` property
|
|
155
|
+
// to each affected entry so the consumer can override the
|
|
156
|
+
// global `uploadsUrl` for those entries.
|
|
157
|
+
//
|
|
158
|
+
// Uses a lightweight direct DB query (no builders) to
|
|
159
|
+
// find file docs by attachment ID. Returns nothing —
|
|
160
|
+
// the mutation is performed on the input object.
|
|
161
|
+
//
|
|
162
|
+
// Does nothing when pretty URLs are disabled.
|
|
163
|
+
// For the shape of the `attachmentMeta` object, see the
|
|
164
|
+
// `@apostrophecms/url:getAllAttachmentMetadata` method documentation.
|
|
165
|
+
async applyPrettyUrlPaths(req, attachmentMeta) {
|
|
166
|
+
if (!self.options.prettyUrls || !attachmentMeta?.results?.length) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const base = self.getPrettyUrlBase(req, { relative: true });
|
|
171
|
+
const batchSize = 100;
|
|
172
|
+
|
|
173
|
+
for (let i = 0; i < attachmentMeta.results.length; i += batchSize) {
|
|
174
|
+
const batch = attachmentMeta.results.slice(i, i + batchSize);
|
|
175
|
+
const batchIds = batch.map(a => a._id);
|
|
176
|
+
|
|
177
|
+
// Lightweight direct query — no builders, no relationship
|
|
178
|
+
// resolution. Only needs slug and attachment ID/extension.
|
|
179
|
+
const fileDocs = await self.apos.doc.db.find({
|
|
180
|
+
type: self.options.name,
|
|
181
|
+
'attachment._id': { $in: batchIds },
|
|
182
|
+
aposLocale: `${req.locale}:${req.mode}`,
|
|
183
|
+
archived: { $ne: true }
|
|
184
|
+
}, {
|
|
185
|
+
projection: {
|
|
186
|
+
slug: 1,
|
|
187
|
+
'attachment._id': 1,
|
|
188
|
+
'attachment.extension': 1
|
|
189
|
+
}
|
|
190
|
+
}).toArray();
|
|
191
|
+
|
|
192
|
+
if (!fileDocs.length) {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const byAttId = new Map();
|
|
197
|
+
for (const entry of batch) {
|
|
198
|
+
byAttId.set(entry._id, entry);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
for (const doc of fileDocs) {
|
|
202
|
+
const entry = byAttId.get(doc.attachment._id);
|
|
203
|
+
if (!entry) {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
const prettyPath = self.getPrettyPath(doc);
|
|
207
|
+
if (!prettyPath) {
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
entry.urls = [ { path: prettyPath } ];
|
|
211
|
+
entry.base = base;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
120
214
|
}
|
|
121
215
|
};
|
|
122
216
|
},
|
|
@@ -154,7 +248,14 @@ module.exports = {
|
|
|
154
248
|
const uglyUrl = self.apos.attachment.url(file.attachment, {
|
|
155
249
|
prettyUrl: false
|
|
156
250
|
});
|
|
157
|
-
|
|
251
|
+
// For relative URLs (local uploadfs, not CDN), resolve
|
|
252
|
+
// against the current server's origin so the proxy can
|
|
253
|
+
// make the self-request. During static builds
|
|
254
|
+
// `attachment.url()` may return only a path.
|
|
255
|
+
const proxyUrl = uglyUrl.startsWith('/')
|
|
256
|
+
? `${req.protocol}://${req.get('host')}${uglyUrl}`
|
|
257
|
+
: uglyUrl;
|
|
258
|
+
return await streamProxy(req, proxyUrl, { error: self.apos.util.error });
|
|
158
259
|
} catch (e) {
|
|
159
260
|
self.apos.util.error('Error in pretty URL route:', e);
|
|
160
261
|
return res.status(500).send('error');
|
|
@@ -71,7 +71,6 @@
|
|
|
71
71
|
"batchRestoreProgress": "Wiederherstellung {{ type }}...",
|
|
72
72
|
"batchTagProgress": "Taggen von {{ count }} {{ type }}...",
|
|
73
73
|
"batchUntagProgress": "Entfernen der Markierung von {{ count }} {{ type }}...",
|
|
74
|
-
"batchRestoreProgress": "Wiederherstellung {{ type }}...",
|
|
75
74
|
"boxFieldAriaLabelAll": "Wert - alle Seiten",
|
|
76
75
|
"boxFieldAriaLabelIndividual": "- {{ side }} Wert",
|
|
77
76
|
"boxFieldEditAll": "Alle Werte bearbeiten",
|
|
@@ -325,7 +324,6 @@
|
|
|
325
324
|
"localizeLocalized": "Lokalisierte",
|
|
326
325
|
"localizeNewRelated": "Übersetze alle neuen zugehörige Dokumente",
|
|
327
326
|
"localizeNotYetLocalized": "Noch nicht lokalisiert",
|
|
328
|
-
"localized": "{{ type }} {{ title }} auf {{ locale }} übersetzt",
|
|
329
327
|
"localizedBatch": "Verarbeitet {{ count }} {{ type }}",
|
|
330
328
|
"localizedBatchFailed": "Lokalisierung von {{ type }} fehlgeschlagen",
|
|
331
329
|
"localizedBatchWithFailures": "Verarbeitet {{ count }} {{ type }} ({{ bad }} von {{ total }} fehlgeschlagen)",
|
|
@@ -287,6 +287,7 @@
|
|
|
287
287
|
"insertTable": "Insert Table",
|
|
288
288
|
"invalid": "invalid",
|
|
289
289
|
"lastEdited": "Last Edited",
|
|
290
|
+
"lastEditor": "Last Editor",
|
|
290
291
|
"lastUpdatedBy": "Last saved on {{ updatedAt }} <br /> by {{ updatedBy }}",
|
|
291
292
|
"layout": "Layout",
|
|
292
293
|
"layoutAlign": "Vertical alignment",
|
|
@@ -318,6 +319,7 @@
|
|
|
318
319
|
"listJoiner": ", ",
|
|
319
320
|
"live": "Live",
|
|
320
321
|
"loadDocFailed": "The requested document was not found.",
|
|
322
|
+
"loadingMore": "Loading more...",
|
|
321
323
|
"locale": "Locale",
|
|
322
324
|
"localeSwitcherDiscardChangesAffirmative": "Save as draft and switch",
|
|
323
325
|
"localeSwitcherDiscardChangesNegative": "Discard changes and switch",
|
|
@@ -326,10 +328,12 @@
|
|
|
326
328
|
"localize": "Localize...",
|
|
327
329
|
"localizeAllRelated": "Localize all related documents and overwrite existing documents",
|
|
328
330
|
"localizeContent": "Localize Content",
|
|
331
|
+
"localizeEditDocument": "Edit document",
|
|
329
332
|
"localizeLocalized": "Localized",
|
|
333
|
+
"localizeManageDocuments": "Manage documents",
|
|
330
334
|
"localizeNewRelated": "Localize new related documents",
|
|
331
335
|
"localizeNotYetLocalized": "Not Yet Localized",
|
|
332
|
-
"
|
|
336
|
+
"localizeOpenDocument": "View document",
|
|
333
337
|
"localizedBatch": "Processed {{ count }} {{ type }}",
|
|
334
338
|
"localizedBatchFailed": "Localizing {{ type }} failed",
|
|
335
339
|
"localizedBatchWithFailures": "Processed {{ count }} {{ type }} ({{ bad }} of {{ total }} failed)",
|
|
@@ -444,6 +448,7 @@
|
|
|
444
448
|
"pageNumber": "Page {{ number }}",
|
|
445
449
|
"pageTitle": "Page Title",
|
|
446
450
|
"pages": "Pages",
|
|
451
|
+
"pieces": "Pieces",
|
|
447
452
|
"parentNotLocalized": "Localize the parent page first",
|
|
448
453
|
"password": "Password",
|
|
449
454
|
"passwordChangeHelp": "Modify your existing password",
|
|
@@ -476,6 +481,29 @@
|
|
|
476
481
|
"rawHtml": "Raw HTML",
|
|
477
482
|
"rawHtmlCode": "Raw HTML (Code)",
|
|
478
483
|
"rawHtmlCodeHelp": "Be careful when embedding third-party code, as it can break the website editing functionality. If a page becomes unusable, add \"?safe_mode=1\" to the URL to make it work temporarily without the problem code being rendered.",
|
|
484
|
+
"recentlyEdited": "Recently edited",
|
|
485
|
+
"recentlyEditedAction": "Action",
|
|
486
|
+
"recentlyEditedResetFilters": "Reset filters",
|
|
487
|
+
"recentlyEditedActionCreated": "Created",
|
|
488
|
+
"recentlyEditedActionLocalized": "Localized",
|
|
489
|
+
"recentlyEditedActionPublished": "Published",
|
|
490
|
+
"recentlyEditedActionSubmitted": "Submitted",
|
|
491
|
+
"recentlyEditedCurrentUser": "Me ({{ user }})",
|
|
492
|
+
"recentlyEditedDocuments": "Recently edited documents",
|
|
493
|
+
"recentlyEditedEditedBy": "Edited by",
|
|
494
|
+
"recentlyEditedClearAllFilters": "Clear all filters",
|
|
495
|
+
"recentlyEditedClearSearch": "Clear search",
|
|
496
|
+
"recentlyEditedEmpty": "No recently edited documents found in the past {{ count }} day",
|
|
497
|
+
"recentlyEditedEmpty_plural": "No recently edited documents found in the past {{ count }} days",
|
|
498
|
+
"recentlyEditedEmptyFiltered": "No documents match your current filters",
|
|
499
|
+
"recentlyEditedEmptyFilteredHint": "Try adjusting or clearing your filters to see more results",
|
|
500
|
+
"recentlyEditedEmptySearched": "No documents match your search",
|
|
501
|
+
"recentlyEditedEmptySearchedHint": "Try different search terms or adjust your filters",
|
|
502
|
+
"recentlyEditedFilters": "Filters",
|
|
503
|
+
"recentlyEditedSearchDocuments": "Search documents",
|
|
504
|
+
"recentlyEditedAddFilter": "Add filter value",
|
|
505
|
+
"recentlyEditedStatus": "Status",
|
|
506
|
+
"recentlyEditedStatusSubmitted": "Submitted",
|
|
479
507
|
"redo": "Redo",
|
|
480
508
|
"redoFailed": "The operation could not be redone.",
|
|
481
509
|
"redoTooltip": "Redo Change",
|
|
@@ -600,14 +628,25 @@
|
|
|
600
628
|
"splitCell": "Split Cell",
|
|
601
629
|
"style": "Style",
|
|
602
630
|
"styleAlignment": "Alignment",
|
|
631
|
+
"styleBackground": "Background",
|
|
632
|
+
"styleBackgroundColor": "Color",
|
|
633
|
+
"styleBackgroundGradient": "Gradient",
|
|
634
|
+
"styleBackgroundImage": "Image",
|
|
635
|
+
"styleBackgroundOverlay": "Overlay",
|
|
636
|
+
"styleBackgroundType": "Background Type",
|
|
603
637
|
"styleBorder": "Border",
|
|
604
638
|
"styleBorderWidth": "Border Width",
|
|
605
639
|
"styleCenter": "Center",
|
|
606
640
|
"styleColor": "Border Color",
|
|
607
641
|
"styleDashed": "Dashed",
|
|
608
642
|
"styleDotted": "Dotted",
|
|
643
|
+
"styleGradientAngle": "Angle",
|
|
644
|
+
"styleGradientEnd": "End Color",
|
|
645
|
+
"styleGradientStart": "Start Color",
|
|
609
646
|
"styleLeft": "Left",
|
|
610
647
|
"styleMargin": "Margin",
|
|
648
|
+
"styleOverlayColor": "Overlay Color",
|
|
649
|
+
"styleOverlayOpacity": "Overlay Opacity",
|
|
611
650
|
"stylePadding": "Padding",
|
|
612
651
|
"styleRadius": "Radius",
|
|
613
652
|
"styleRight": "Right",
|
|
@@ -324,7 +324,6 @@
|
|
|
324
324
|
"localizeLocalized": "Localizado",
|
|
325
325
|
"localizeNewRelated": "Traducir nuevos documentos relacionados",
|
|
326
326
|
"localizeNotYetLocalized": "No localizado aún",
|
|
327
|
-
"localized": "El {{ type }} {{ title }} ha sido traducido a la configuración regional {{ locale }}",
|
|
328
327
|
"localizedBatch": "Procesado {{ count }} {{ type }}",
|
|
329
328
|
"localizedBatchFailed": "Error al localizar {{ type }}",
|
|
330
329
|
"localizedBatchWithFailures": "Procesado {{ count }} {{ type }} ({{ bad }} de {{ total }} fallaron)",
|
|
@@ -324,7 +324,6 @@
|
|
|
324
324
|
"localizeLocalized": "Localisé",
|
|
325
325
|
"localizeNewRelated": "Changer la langue des nouveaux documents associés",
|
|
326
326
|
"localizeNotYetLocalized": "Pas encore localisé",
|
|
327
|
-
"localized": "{{ type }} {{ title }} changé en {{ locale }}",
|
|
328
327
|
"localizedBatch": "Traité {{ count }} {{ type }}",
|
|
329
328
|
"localizedBatchFailed": "La localisation de {{ type }} a échoué.",
|
|
330
329
|
"localizedBatchWithFailures": "Traité {{ count }} {{ type }} ({{ bad }} sur {{ total }} ont échoué).",
|
|
@@ -324,7 +324,6 @@
|
|
|
324
324
|
"localizeLocalized": "Localizzato",
|
|
325
325
|
"localizeNewRelated": "Localizza nuovi documenti correlati",
|
|
326
326
|
"localizeNotYetLocalized": "Non ancora localizzato",
|
|
327
|
-
"localized": "Localizzato il {{ type }} {{ title }} in {{ locale }}",
|
|
328
327
|
"localizedBatch": "Elaborato {{ count }} {{ type }}",
|
|
329
328
|
"localizedBatchFailed": "Localizzazione di {{ type }} fallita",
|
|
330
329
|
"localizedBatchWithFailures": "Elaborato {{ count }} {{ type }} ({{ bad }} di {{ total }} fallito)",
|
|
@@ -324,7 +324,6 @@
|
|
|
324
324
|
"localizeLocalized": "Localizado",
|
|
325
325
|
"localizeNewRelated": "Localizar novos documentos relacionados",
|
|
326
326
|
"localizeNotYetLocalized": "Ainda Não Localizado",
|
|
327
|
-
"localized": "Localizar o(a) {{ type }} {{ title }} para {{ locale }}",
|
|
328
327
|
"localizedBatch": "Processado {{ count }} {{ type }}",
|
|
329
328
|
"localizedBatchFailed": "Falha ao localizar {{ type }}",
|
|
330
329
|
"localizedBatchWithFailures": "Processado {{ count }} {{ type }} ({{ bad }} de {{ total }} falharam)",
|
|
@@ -324,7 +324,6 @@
|
|
|
324
324
|
"localizeLocalized": "Lokalizované",
|
|
325
325
|
"localizeNewRelated": "Preložte nové súvisiace dokumenty",
|
|
326
326
|
"localizeNotYetLocalized": "Ešte nie je lokalizované",
|
|
327
|
-
"localized": "Preložené {{ type }} {{ title }} do {{ locale }}",
|
|
328
327
|
"localizedBatch": "Spracované {{ count }} {{ type }}",
|
|
329
328
|
"localizedBatchFailed": "Lokalizácia {{ type }} zlyhala",
|
|
330
329
|
"localizedBatchWithFailures": "Spracované {{ count }} {{ type }} ({{ bad }} z {{ total }} zlyhalo)",
|
|
@@ -16,11 +16,28 @@ export default () => {
|
|
|
16
16
|
|
|
17
17
|
if (!skipCount) {
|
|
18
18
|
if (count) {
|
|
19
|
+
const targetLocales = [ ...new Set(
|
|
20
|
+
log.filter(isSuccess).map(entry => entry.locale)
|
|
21
|
+
) ];
|
|
22
|
+
const managerOpen = apos.modal.get()
|
|
23
|
+
.some(modal => modal.componentName === 'AposRecentlyEditedManager');
|
|
19
24
|
await apos.notify('apostrophe:localizingNotificationSuccess', {
|
|
20
25
|
type: 'success',
|
|
21
26
|
icon: 'translate-icon',
|
|
22
27
|
interpolate: { count },
|
|
23
|
-
dismiss:
|
|
28
|
+
dismiss: managerOpen,
|
|
29
|
+
...!managerOpen && {
|
|
30
|
+
buttons: [
|
|
31
|
+
{
|
|
32
|
+
type: 'event',
|
|
33
|
+
label: 'apostrophe:localizeManageDocuments',
|
|
34
|
+
name: 'localize-manage-documents',
|
|
35
|
+
data: {
|
|
36
|
+
locales: targetLocales
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
24
41
|
});
|
|
25
42
|
}
|
|
26
43
|
return;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export default () => {
|
|
2
|
+
let once = false;
|
|
3
|
+
|
|
4
|
+
apos.util.onReady(() => {
|
|
5
|
+
if (once) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
once = true;
|
|
9
|
+
|
|
10
|
+
apos.bus.$on('localize-open-document', openDocument);
|
|
11
|
+
apos.bus.$on('localize-manage-documents', manageDocuments);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
function openDocument(data) {
|
|
15
|
+
if (!data) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (data._url) {
|
|
19
|
+
window.open(data._url, '_blank');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const docModuleName = data.slug?.startsWith('/')
|
|
23
|
+
? '@apostrophecms/page'
|
|
24
|
+
: data.type;
|
|
25
|
+
if (!apos.modules[docModuleName]) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const editorComponent = apos.modules[docModuleName]?.components?.editorModal || 'AposDocEditor';
|
|
29
|
+
apos.modal.execute(editorComponent, {
|
|
30
|
+
moduleName: docModuleName,
|
|
31
|
+
docId: data._id,
|
|
32
|
+
locale: data.locale
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function manageDocuments(data) {
|
|
37
|
+
if (!data) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
apos.bus.$emit('admin-menu-click', {
|
|
41
|
+
itemName: '@apostrophecms/recently-edited:manager',
|
|
42
|
+
props: {
|
|
43
|
+
initialFilters: {
|
|
44
|
+
_action: [ 'localized' ],
|
|
45
|
+
_locale: data.locales || []
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
};
|