apostrophe 4.4.2 → 4.5.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 +62 -3
- package/index.js +2 -3
- package/lib/glob.js +12 -0
- package/lib/moog-require.js +3 -3
- package/modules/@apostrophecms/admin-bar/index.js +9 -2
- package/modules/@apostrophecms/admin-bar/ui/apos/apps/AposAdminBar.js +1 -1
- package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue +2 -2
- package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextTitle.vue +0 -1
- package/modules/@apostrophecms/area/ui/apos/components/AposAreaContextualMenu.vue +2 -2
- package/modules/@apostrophecms/area/ui/apos/components/AposAreaEditor.vue +6 -6
- package/modules/@apostrophecms/area/ui/apos/components/AposAreaExpandedMenu.vue +7 -1
- package/modules/@apostrophecms/asset/index.js +5 -6
- package/modules/@apostrophecms/command-menu/index.js +7 -2
- package/modules/@apostrophecms/doc/index.js +2 -2
- package/modules/@apostrophecms/doc-type/index.js +1 -1
- package/modules/@apostrophecms/i18n/i18n/en.json +37 -1
- package/modules/@apostrophecms/i18n/index.js +2 -2
- package/modules/@apostrophecms/i18n/ui/apos/components/AposI18nLocalize.vue +5 -5
- package/modules/@apostrophecms/image/index.js +1 -1
- package/modules/@apostrophecms/image/ui/apos/components/AposImageRelationshipEditor.vue +4 -3
- package/modules/@apostrophecms/image/ui/apos/components/AposMediaManager.vue +221 -76
- package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerDisplay.vue +91 -24
- package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerEditor.vue +48 -51
- package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerSelections.vue +1 -0
- package/modules/@apostrophecms/login/index.js +3 -3
- package/modules/@apostrophecms/modal/ui/apos/components/AposDocsManagerToolbar.vue +3 -11
- package/modules/@apostrophecms/modal/ui/apos/components/AposModal.vue +4 -12
- package/modules/@apostrophecms/modal/ui/apos/components/AposModalBody.vue +20 -6
- package/modules/@apostrophecms/modal/ui/apos/components/AposModalBreadcrumbs.vue +1 -1
- package/modules/@apostrophecms/modal/ui/apos/components/AposModalShareDraft.vue +1 -1
- package/modules/@apostrophecms/modal/ui/apos/components/AposModalTabs.vue +3 -5
- package/modules/@apostrophecms/modal/ui/apos/components/AposWidgetModalTabs.vue +3 -5
- package/modules/@apostrophecms/modal/ui/apos/mixins/AposDocErrorsMixin.js +2 -2
- package/modules/@apostrophecms/modal/ui/apos/mixins/AposDocsManagerMixin.js +44 -39
- package/modules/@apostrophecms/modal/ui/apos/mixins/AposModalTabsMixin.js +2 -2
- package/modules/@apostrophecms/oembed/index.js +2 -2
- package/modules/@apostrophecms/oembed-field/ui/apos/components/AposInputOembed.vue +2 -2
- package/modules/@apostrophecms/page/index.js +5 -2
- package/modules/@apostrophecms/page/ui/apos/components/AposPagesManager.vue +1 -2
- package/modules/@apostrophecms/page/ui/apos/logic/AposPagesManager.js +14 -7
- package/modules/@apostrophecms/piece-type/index.js +5 -2
- package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManager.vue +23 -11
- package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManagerDisplay.vue +4 -1
- package/modules/@apostrophecms/rich-text-widget/index.js +31 -3
- package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapColor.vue +285 -0
- package/modules/@apostrophecms/rich-text-widget/ui/apos/tiptap-extensions/Color.js +5 -0
- package/modules/@apostrophecms/schema/lib/addFieldTypes.js +38 -25
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputBoolean.vue +2 -2
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputColor.vue +0 -1
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputObject.vue +1 -0
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputWrapper.vue +13 -2
- package/modules/@apostrophecms/schema/ui/apos/logic/AposArrayEditor.js +11 -9
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputArea.js +4 -4
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputArray.js +7 -7
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputObject.js +11 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputSlug.js +45 -51
- package/modules/@apostrophecms/schema/ui/apos/logic/AposSchema.js +3 -1
- package/modules/@apostrophecms/schema/ui/apos/mixins/AposInputMixin.js +1 -1
- package/modules/@apostrophecms/submitted-draft/index.js +2 -2
- package/modules/@apostrophecms/ui/ui/apos/components/AposButton.vue +7 -3
- package/modules/@apostrophecms/ui/ui/apos/components/AposButtonSplit.vue +0 -1
- package/modules/@apostrophecms/ui/ui/apos/components/AposContextMenu.vue +12 -4
- package/modules/@apostrophecms/ui/ui/apos/components/AposFile.vue +4 -4
- package/modules/@apostrophecms/ui/ui/apos/components/AposFilterMenu.vue +2 -1
- package/modules/@apostrophecms/ui/ui/apos/components/AposLoading.vue +1 -1
- package/modules/@apostrophecms/ui/ui/apos/components/AposLoadingBlock.vue +50 -0
- package/modules/@apostrophecms/ui/ui/apos/components/AposSlat.vue +0 -1
- package/modules/@apostrophecms/ui/ui/apos/components/AposSlatList.vue +6 -4
- package/modules/@apostrophecms/ui/ui/apos/components/AposTagApply.vue +17 -11
- package/modules/@apostrophecms/ui/ui/apos/components/AposTree.vue +2 -2
- package/modules/@apostrophecms/ui/ui/apos/components/AposTreeRows.vue +2 -2
- package/modules/@apostrophecms/ui/ui/apos/lib/tooltip.js +2 -2
- package/modules/@apostrophecms/ui/ui/apos/stores/modal.js +3 -3
- package/modules/@apostrophecms/user/index.js +1 -0
- package/modules/@apostrophecms/util/index.js +12 -4
- package/modules/@apostrophecms/widget-type/ui/apos/components/AposWidgetEditor.vue +2 -2
- package/package.json +8 -7
- package/scripts/lint-i18n.js +8 -3
- package/test/command-menu.js +76 -12
- package/test/pages-rest.js +102 -0
- package/test/pieces.js +133 -10
- package/test/recursionGuard.js +5 -5
- package/test/schemas.js +1 -1
- package/test/utils/commands.js +26 -0
- package/test-lib/util.js +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.5.0 (2024-07-10)
|
|
4
|
+
|
|
5
|
+
### Adds
|
|
6
|
+
|
|
7
|
+
* Allow to disable shortcut by setting the option `shortcut: false`
|
|
8
|
+
* Adds a new color picker tool for the rich-text-widget toolbar that matches the existing `color` schema field. This also adds the same `pickerOptions` and `format` options to the rich-text-widget configuration that exist in the `color` schema field.
|
|
9
|
+
* Add missing UI translation keys.
|
|
10
|
+
* Infite scroll in media manager instead of pagination and related search fixes.
|
|
11
|
+
* Improves loaders by using new `AposLoadingBlock` that uses `AposLoading` instead of the purple screen in media manager.
|
|
12
|
+
* Select the configured aspect ratio and add `data-apos-field` attributes to the fields inside `AposImageRelationshipEditor.vue`.
|
|
13
|
+
* Add `getShowAdminBar` method. This method can be overriden in projects to drive the admin bar visibility for logged-in users.
|
|
14
|
+
|
|
15
|
+
### Fixes
|
|
16
|
+
|
|
17
|
+
* Remove double GET request when saving image update.
|
|
18
|
+
* Fix filter menu forgetting selecting filters and not instantiating them.
|
|
19
|
+
* Remove blur emit for filter buttons and search bar to avoid re requesting when clicking outside…
|
|
20
|
+
* `this.modified` was not working properly (set to false when saving). We can now avoid to reload images when saving no changes.
|
|
21
|
+
* In media manager images checkboxes are disabled when max is reached.
|
|
22
|
+
* In media manager when updating an image or archiving, update the list instead of fetching and update checked documents to see changes in the right panel selected list.
|
|
23
|
+
* The `password` field type now has a proper fallback default, the empty string, just like the string field type
|
|
24
|
+
and its derivatives. This resolves bugs in which the unexpected `null` caused problems during validation. This bug
|
|
25
|
+
was old, but was masked in some situations until the release of version `4.4.3`.
|
|
26
|
+
* Identify and mark server validation errors in the admin UI. This helps editors identify already existing data fields, having validation errors when schema changes (e.g. optional field becomes required).
|
|
27
|
+
* Removes `menu-offset` props that were causing `AposContextMenu` to not display properly.
|
|
28
|
+
* Allows to pass a number or an array to `AposContextMenu` to set the offset of the context menu (main and cross axis see `floating-ui` documentation).
|
|
29
|
+
* Fixes the relationship fields not having the data when coming from the relationship modal.
|
|
30
|
+
* Fixes watch on `checkedDocs` passed to `AposSlatList` not being reactive and not seeing updated relationship fields.
|
|
31
|
+
* Adds styles for 1 column expanded area ([#4608](https://github.com/apostrophecms/apostrophe/issues/4608))
|
|
32
|
+
* Fixes weird slug computations based on followed values like title. Simplifies based on the new tech design.
|
|
33
|
+
* Prevent broken admin UI when there is a missing widget.
|
|
34
|
+
* Fixes media manager not loading images when last infinite scroll page have been reached (when uploading image for example).
|
|
35
|
+
* Upgrade oembetter versions to allow all vimeo urls.
|
|
36
|
+
|
|
37
|
+
### Changes
|
|
38
|
+
|
|
39
|
+
* Update `Choose Images` selection behavior. When choosing images as part of a relationship, you click on the image or checkbox to add the image to the selection.
|
|
40
|
+
If a max is set to allow only one image, clicking on the selected image will remove it from the selection. Clicking on another image will update the selection with the newly clicked image.
|
|
41
|
+
If a max is set to allow multiple images, you can remove images from the selection by using the checkbox. Clicking on the image will bring the image schema in the right panel.
|
|
42
|
+
You can upload images even if the max has been reached. We will append the uploaded images to the existing selection up to the max if any.
|
|
43
|
+
* Update `@apostrophecms/emulate-mongo-3-driver` dependency to keep supporting `mongodb@3.x` queries while using `mongodb@6.x`.
|
|
44
|
+
|
|
45
|
+
## 4.4.3 (2024-06-17)
|
|
46
|
+
|
|
47
|
+
### Fixes
|
|
48
|
+
|
|
49
|
+
* Do not use schema `field.def` when calling `convert`. Applying defaults to new documents is the job of `newInstance()` and similar code.
|
|
50
|
+
If you wish a field to be mandatory use `required: true`.
|
|
51
|
+
* As a convenience, using `POST` for pieces and pages with `_newInstance: true` keeps any additional `req.body` properties in the API response.
|
|
52
|
+
This feature unofficially existed before, it is now supported.
|
|
53
|
+
* Rollbacks watcher on `checked` array. Fixes, checked docs not being properly updated.
|
|
54
|
+
|
|
55
|
+
|
|
3
56
|
## 4.4.2 (2024-06-14)
|
|
4
57
|
|
|
5
58
|
### Fixes
|
|
@@ -58,13 +111,19 @@ We will now end up with page B slug as `/peer/page` and not `/peer/peer/page` as
|
|
|
58
111
|
* Detect shortcut conflicts when using multiple shortcuts.
|
|
59
112
|
* Updating schema fields as read-only no longer reset the value when updating the document.
|
|
60
113
|
* Fixes stylelint config file, uses config from our shared configuration, fixes all lint errors.
|
|
61
|
-
* Removes `$nextTick` use to re render schema in `AposArrayEditor` because it was triggering weird vue error in production.
|
|
62
|
-
Instead, makes the AposSchema for loop keys more unique using `modelValue.data._id`,
|
|
63
|
-
if document changes it re-renders schema fields.
|
|
64
114
|
* Fixes `TheAposCommandMenu` modals not computing shortcuts from the current opened modal.
|
|
65
115
|
* Fixes select boxes of relationships, we can now check manually published relationships, and `AposSlatList` renders properly checked relationships.
|
|
66
116
|
* Fixes issues in `AposInputArray` on production build to be able to add, remove and edit array items after `required` error.
|
|
67
117
|
* Relationships browse button isn't disabled when max is reached.
|
|
118
|
+
* In media manager images checkboxes are disabled when max is reached.
|
|
119
|
+
|
|
120
|
+
## 4.3.3 (2024-06-04)
|
|
121
|
+
|
|
122
|
+
### Fixes
|
|
123
|
+
|
|
124
|
+
* Removes `$nextTick` use to re render schema in `AposArrayEditor` because it was triggering weird vue error in production.
|
|
125
|
+
Instead, makes the AposSchema for loop keys more unique using `modelValue.data._id`,
|
|
126
|
+
if document changes it re-renders schema fields.
|
|
68
127
|
* In media manager image checkboxes are disabled when max is reached.
|
|
69
128
|
* Fixes tiptap bubble menu jumping on Firefox when clicking on buttons. Also fixes the fact that
|
|
70
129
|
double clicking on bubble menu out of buttons would prevent it from closing when unfocusing the rich text area.
|
package/index.js
CHANGED
|
@@ -9,8 +9,7 @@ const cluster = require('cluster');
|
|
|
9
9
|
const { cpus } = require('os');
|
|
10
10
|
const process = require('process');
|
|
11
11
|
const npmResolve = require('resolve');
|
|
12
|
-
const glob = require('glob');
|
|
13
|
-
|
|
12
|
+
const glob = require('./lib/glob.js');
|
|
14
13
|
let defaults = require('./defaults.js');
|
|
15
14
|
|
|
16
15
|
// ## Top-level options
|
|
@@ -389,7 +388,7 @@ async function apostrophe(options, telemetry, rootSpan) {
|
|
|
389
388
|
if (!options.nestedModuleSubdirs) {
|
|
390
389
|
return;
|
|
391
390
|
}
|
|
392
|
-
const configs = glob
|
|
391
|
+
const configs = glob(self.localModules + '/**/modules.js', { follow: true });
|
|
393
392
|
_.each(configs, function(config) {
|
|
394
393
|
try {
|
|
395
394
|
_.merge(self.options.modules, require(config));
|
package/lib/glob.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const { globSync } = require('glob');
|
|
2
|
+
|
|
3
|
+
// synchronous glob 10 but with the sorting semantics of glob 8,
|
|
4
|
+
// to ease backwards compatibility in Apostrophe startup logic
|
|
5
|
+
|
|
6
|
+
module.exports = (pattern, options) => {
|
|
7
|
+
const result = globSync(pattern, options);
|
|
8
|
+
if (!options.nosort) {
|
|
9
|
+
result.sort((a, b) => a.localeCompare(b, 'en'));
|
|
10
|
+
}
|
|
11
|
+
return result;
|
|
12
|
+
};
|
package/lib/moog-require.js
CHANGED
|
@@ -2,7 +2,7 @@ const _ = require('lodash');
|
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const npmResolve = require('resolve');
|
|
4
4
|
const path = require('path');
|
|
5
|
-
const glob = require('glob');
|
|
5
|
+
const glob = require('./glob.js');
|
|
6
6
|
const importFresh = require('import-fresh');
|
|
7
7
|
const resolveFrom = require('resolve-from');
|
|
8
8
|
const regExpQuote = require('regexp-quote');
|
|
@@ -60,7 +60,7 @@ module.exports = function(options) {
|
|
|
60
60
|
// Fetching a list of index.js files on the first call and then searching it each time for
|
|
61
61
|
// one that refers to the right type name shaves as much as 60 seconds off the startup
|
|
62
62
|
// time in a large project, compared to using the glob cache feature
|
|
63
|
-
self._indexes = glob
|
|
63
|
+
self._indexes = glob(self.options.localModules + '/**/index.js', { follow: true });
|
|
64
64
|
}
|
|
65
65
|
const matches = self._indexes.filter(function(index) {
|
|
66
66
|
// Double-check that we're not confusing "@apostrophecms/asset" with "asset" by
|
|
@@ -255,7 +255,7 @@ module.exports = function(options) {
|
|
|
255
255
|
// Ternary is required because glob expects at least 2 entries when using curly braces
|
|
256
256
|
const pattern = workspaces.length === 1 ? workspaces[0] : `{${workspaces.join(',')}}`;
|
|
257
257
|
const packagePath = path.resolve(folder, pattern, 'package.json');
|
|
258
|
-
const workspacePackages = glob
|
|
258
|
+
const workspacePackages = glob(packagePath, { follow: true });
|
|
259
259
|
|
|
260
260
|
return workspacePackages.flatMap(packagePath => {
|
|
261
261
|
const info = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// takes advantage of this module.
|
|
6
6
|
|
|
7
7
|
const _ = require('lodash');
|
|
8
|
-
const
|
|
8
|
+
const { createId } = require('@paralleldrive/cuid2');
|
|
9
9
|
|
|
10
10
|
module.exports = {
|
|
11
11
|
options: {
|
|
@@ -310,6 +310,12 @@ module.exports = {
|
|
|
310
310
|
return self.apos.permission.can(req, item.permission.action, item.permission.type, 'draft');
|
|
311
311
|
},
|
|
312
312
|
|
|
313
|
+
// Show admin bar for logged-in user only
|
|
314
|
+
|
|
315
|
+
getShowAdminBar(req) {
|
|
316
|
+
return !!req.user;
|
|
317
|
+
},
|
|
318
|
+
|
|
313
319
|
getBrowserData(req) {
|
|
314
320
|
if (!req.user) {
|
|
315
321
|
return false;
|
|
@@ -351,9 +357,10 @@ module.exports = {
|
|
|
351
357
|
},
|
|
352
358
|
// Base API URL appropriate to the context document
|
|
353
359
|
contextBar: context && self.apos.doc.getManager(context.type).options.contextBar,
|
|
360
|
+
showAdminBar: self.getShowAdminBar(req),
|
|
354
361
|
// Simplifies frontend logic
|
|
355
362
|
contextId: context && context._id,
|
|
356
|
-
tabId:
|
|
363
|
+
tabId: createId(),
|
|
357
364
|
contextEditorName,
|
|
358
365
|
pageTree: self.options.pageTree && self.apos.permission.can(req, 'edit', '@apostrophecms/any-page-type', 'draft'),
|
|
359
366
|
bars: self.bars,
|
|
@@ -4,7 +4,7 @@ export default function() {
|
|
|
4
4
|
const component = apos.vueComponents.TheAposAdminBar;
|
|
5
5
|
// Careful, login page is in user scene but has no admin bar
|
|
6
6
|
const el = document.querySelector('#apos-admin-bar');
|
|
7
|
-
if (!apos.adminBar || !el) {
|
|
7
|
+
if (!apos.adminBar || !el || apos?.adminBar.showAdminBar === false) {
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
10
10
|
const app = createApp(component, { items: apos.adminBar.items || [] });
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
|
|
36
36
|
<script>
|
|
37
37
|
import { klona } from 'klona';
|
|
38
|
-
import
|
|
38
|
+
import { createId } from '@paralleldrive/cuid2';
|
|
39
39
|
import AposPublishMixin from 'Modules/@apostrophecms/ui/mixins/AposPublishMixin';
|
|
40
40
|
import AposAdvisoryLockMixin from 'Modules/@apostrophecms/ui/mixins/AposAdvisoryLockMixin';
|
|
41
41
|
|
|
@@ -159,7 +159,7 @@ export default {
|
|
|
159
159
|
// sessionStorage because it is deliberately browser-tab specific
|
|
160
160
|
let tabId = sessionStorage.getItem('aposTabId');
|
|
161
161
|
if (!tabId) {
|
|
162
|
-
tabId =
|
|
162
|
+
tabId = createId();
|
|
163
163
|
sessionStorage.setItem('aposTabId', tabId);
|
|
164
164
|
}
|
|
165
165
|
window.apos.adminBar.tabId = tabId;
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
</template>
|
|
83
83
|
|
|
84
84
|
<script>
|
|
85
|
-
import
|
|
85
|
+
import { createId } from '@paralleldrive/cuid2';
|
|
86
86
|
|
|
87
87
|
export default {
|
|
88
88
|
name: 'AposAreaContextualMenu',
|
|
@@ -184,7 +184,7 @@ export default {
|
|
|
184
184
|
}
|
|
185
185
|
},
|
|
186
186
|
menuId() {
|
|
187
|
-
return `areaMenu-${
|
|
187
|
+
return `areaMenu-${createId()}`;
|
|
188
188
|
}
|
|
189
189
|
},
|
|
190
190
|
mounted() {
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
</template>
|
|
71
71
|
|
|
72
72
|
<script>
|
|
73
|
-
import
|
|
73
|
+
import { createId } from '@paralleldrive/cuid2';
|
|
74
74
|
import { klona } from 'klona';
|
|
75
75
|
import AposThemeMixin from 'Modules/@apostrophecms/ui/mixins/AposThemeMixin';
|
|
76
76
|
|
|
@@ -148,7 +148,7 @@ export default {
|
|
|
148
148
|
addWidgetEditor: null,
|
|
149
149
|
addWidgetOptions: null,
|
|
150
150
|
addWidgetType: null,
|
|
151
|
-
areaId:
|
|
151
|
+
areaId: createId(),
|
|
152
152
|
next: this.getValidItems(),
|
|
153
153
|
hoveredWidget: null,
|
|
154
154
|
hoveredNonForeignWidget: null,
|
|
@@ -406,7 +406,7 @@ export default {
|
|
|
406
406
|
// Regenerate all array item, area, object and widget ids so they are considered
|
|
407
407
|
// new. Useful when copying a widget with nested content.
|
|
408
408
|
regenerateIds(schema, object) {
|
|
409
|
-
object._id =
|
|
409
|
+
object._id = createId();
|
|
410
410
|
for (const field of schema) {
|
|
411
411
|
if (field.type === 'array') {
|
|
412
412
|
for (const item of (object[field.name] || [])) {
|
|
@@ -416,7 +416,7 @@ export default {
|
|
|
416
416
|
this.regenerateIds(field.schema, object[field.name] || {});
|
|
417
417
|
} else if (field.type === 'area') {
|
|
418
418
|
if (object[field.name]) {
|
|
419
|
-
object[field.name]._id =
|
|
419
|
+
object[field.name]._id = createId();
|
|
420
420
|
for (const item of (object[field.name].items || [])) {
|
|
421
421
|
const schema = apos.modules[apos.area.widgetManagers[item.type]].schema;
|
|
422
422
|
this.regenerateIds(schema, item);
|
|
@@ -513,7 +513,7 @@ export default {
|
|
|
513
513
|
},
|
|
514
514
|
async insert({ index, widget }) {
|
|
515
515
|
if (!widget._id) {
|
|
516
|
-
widget._id =
|
|
516
|
+
widget._id = createId();
|
|
517
517
|
}
|
|
518
518
|
if (!widget.metaType) {
|
|
519
519
|
widget.metaType = 'widget';
|
|
@@ -600,7 +600,7 @@ export default {
|
|
|
600
600
|
schema.forEach(field => {
|
|
601
601
|
if (field.type === 'area') {
|
|
602
602
|
widget[field.name] = {
|
|
603
|
-
_id:
|
|
603
|
+
_id: createId(),
|
|
604
604
|
metaType: 'area',
|
|
605
605
|
items: []
|
|
606
606
|
};
|
|
@@ -140,7 +140,7 @@ export default {
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
const group = {
|
|
143
|
-
label: '
|
|
143
|
+
label: this.$t('apostrophe:areaExpandedMenuClipboard'),
|
|
144
144
|
widgets: [
|
|
145
145
|
{
|
|
146
146
|
type: 'clipboard',
|
|
@@ -220,6 +220,12 @@ export default {
|
|
|
220
220
|
background-color: var(--a-base-10);
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
&--1-column {
|
|
224
|
+
display: grid;
|
|
225
|
+
grid-template-columns: 1fr;
|
|
226
|
+
gap: 15px;
|
|
227
|
+
}
|
|
228
|
+
|
|
223
229
|
&--2-columns {
|
|
224
230
|
display: grid;
|
|
225
231
|
grid-template-columns: repeat(2, 1fr);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const glob = require('glob');
|
|
2
1
|
const fs = require('fs-extra');
|
|
3
2
|
const Promise = require('bluebird');
|
|
4
3
|
const webpackModule = require('webpack');
|
|
@@ -8,7 +7,7 @@ const util = require('util');
|
|
|
8
7
|
const express = require('express');
|
|
9
8
|
const { stripIndent } = require('common-tags');
|
|
10
9
|
const { mergeWithCustomize: webpackMerge } = require('webpack-merge');
|
|
11
|
-
const
|
|
10
|
+
const { createId } = require('@paralleldrive/cuid2');
|
|
12
11
|
const chokidar = require('chokidar');
|
|
13
12
|
const _ = require('lodash');
|
|
14
13
|
const {
|
|
@@ -110,7 +109,7 @@ module.exports = {
|
|
|
110
109
|
components(self) {
|
|
111
110
|
return {
|
|
112
111
|
scripts(req, data) {
|
|
113
|
-
const placeholder = `[scripts-placeholder:${
|
|
112
|
+
const placeholder = `[scripts-placeholder:${createId()}]`;
|
|
114
113
|
|
|
115
114
|
req.scriptsPlaceholder = placeholder;
|
|
116
115
|
|
|
@@ -119,7 +118,7 @@ module.exports = {
|
|
|
119
118
|
};
|
|
120
119
|
},
|
|
121
120
|
stylesheets(req, data) {
|
|
122
|
-
const placeholder = `[stylesheets-placeholder:${
|
|
121
|
+
const placeholder = `[stylesheets-placeholder:${createId()}]`;
|
|
123
122
|
|
|
124
123
|
req.stylesheetsPlaceholder = placeholder;
|
|
125
124
|
|
|
@@ -247,7 +246,7 @@ module.exports = {
|
|
|
247
246
|
const scenes = [ ...new Set(Object.values(self.builds).map(options => options.scenes).flat()) ];
|
|
248
247
|
|
|
249
248
|
// enumerate public assets and include them in deployment if appropriate
|
|
250
|
-
const publicAssets = glob
|
|
249
|
+
const publicAssets = self.apos.util.glob('modules/**/*', {
|
|
251
250
|
cwd: bundleDir,
|
|
252
251
|
mark: true
|
|
253
252
|
}).filter(match => !match.endsWith('/'));
|
|
@@ -702,7 +701,7 @@ module.exports = {
|
|
|
702
701
|
if (seen[entry.dirname]) {
|
|
703
702
|
continue;
|
|
704
703
|
}
|
|
705
|
-
components = components.concat(glob
|
|
704
|
+
components = components.concat(self.apos.util.glob(`${entry.dirname}/ui/${folder}/${pattern}`));
|
|
706
705
|
seen[entry.dirname] = true;
|
|
707
706
|
}
|
|
708
707
|
}
|
|
@@ -205,7 +205,8 @@ module.exports = {
|
|
|
205
205
|
);
|
|
206
206
|
command.modal &&
|
|
207
207
|
assert.equal(typeof command.modal, 'string', `Invalid command modal for ${name}`);
|
|
208
|
-
|
|
208
|
+
command.shortcut !== false &&
|
|
209
|
+
assert.equal(typeof command.shortcut, 'string', `Invalid command shortcut, must be a string, for ${name}`);
|
|
209
210
|
|
|
210
211
|
return [ true, null ];
|
|
211
212
|
} catch (error) {
|
|
@@ -246,9 +247,13 @@ module.exports = {
|
|
|
246
247
|
}
|
|
247
248
|
},
|
|
248
249
|
buildCommands(initialState) {
|
|
250
|
+
const additionalRemoves = Object.entries(initialState.composed.commands)
|
|
251
|
+
.filter(([ , field ]) => field.shortcut === false)
|
|
252
|
+
.map(([ name ]) => name);
|
|
253
|
+
|
|
249
254
|
const concatenate = self.apos.util.omit(
|
|
250
255
|
initialState.composed.commands,
|
|
251
|
-
initialState.composed.removes
|
|
256
|
+
initialState.composed.removes.concat(additionalRemoves)
|
|
252
257
|
);
|
|
253
258
|
|
|
254
259
|
return {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const _ = require('lodash');
|
|
2
|
-
const
|
|
2
|
+
const { createId } = require('@paralleldrive/cuid2');
|
|
3
3
|
const { SemanticAttributes } = require('@opentelemetry/semantic-conventions');
|
|
4
4
|
const { klona } = require('klona');
|
|
5
5
|
|
|
@@ -1696,7 +1696,7 @@ module.exports = {
|
|
|
1696
1696
|
}
|
|
1697
1697
|
for (const widget of area.items || []) {
|
|
1698
1698
|
if ((!widget._id) || seen.has(widget._id)) {
|
|
1699
|
-
widget._id =
|
|
1699
|
+
widget._id = createId();
|
|
1700
1700
|
} else {
|
|
1701
1701
|
seen.add(widget._id);
|
|
1702
1702
|
}
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"archivingWillDeleteDraftChildren": "Child pages that have never been published will be permanently deleted.",
|
|
34
34
|
"archivingWillLoseDraftChanges": "Unpublished draft changes to this {{ type }} will be permanently deleted.",
|
|
35
35
|
"archivingWillUnpublish": "This will also un-publish the {{ type }}.",
|
|
36
|
+
"areaExpandedMenuClipboard": "Clipboard",
|
|
36
37
|
"areYouSure": "Are You Sure?",
|
|
37
38
|
"arrayCancelDescription": "Do you want to discard changes to this list?",
|
|
38
39
|
"aspectRatio": "Aspect Ratio",
|
|
@@ -195,8 +196,14 @@
|
|
|
195
196
|
"fileTypeCannotBeCropped": "{{ extension }} files cannot be cropped, do not present the cropping UI for this type",
|
|
196
197
|
"fileTypeNotAccepted": "File type was not accepted. Allowed extensions: {{ extensions }}",
|
|
197
198
|
"files": "Files",
|
|
199
|
+
"fileUploaderAttachmentLimitReached": "Attachment limit reached",
|
|
200
|
+
"fileUploaderDropFile": "Drop a file here or",
|
|
201
|
+
"fileUploaderFieldIsDisabled": "Field is disabled",
|
|
202
|
+
"fileUploaderOpenExplorer": "click to open the file explorer",
|
|
198
203
|
"filter": "Filter",
|
|
199
204
|
"filterByTag": "Filter by Tag",
|
|
205
|
+
"filterMenuChooseOne": "Choose One",
|
|
206
|
+
"filterMenuLoadingChoices": "Loading Choices...",
|
|
200
207
|
"filterResultsByType": "Filter Results By Type",
|
|
201
208
|
"findOrAddTag": "Find an existing tag or add a new one",
|
|
202
209
|
"focalPoint": "Select a focal point for this image",
|
|
@@ -205,6 +212,9 @@
|
|
|
205
212
|
"guest": "Guest",
|
|
206
213
|
"hideInNavigation": "Hide in Navigation",
|
|
207
214
|
"home": "Home",
|
|
215
|
+
"i18nCurrentLocale": "Current Locale",
|
|
216
|
+
"i18nCurrentlySelectedLocale": "Currently selected locale",
|
|
217
|
+
"i18nDefaultLocale": "Default locale",
|
|
208
218
|
"image": "Image",
|
|
209
219
|
"imageOnReplaceAutocropMessage": "The replaced image has been autocropped for \"{{ title }}\".",
|
|
210
220
|
"imageOnReplaceAutocropError": "An error occurred while autocropping the replaced image for {{ title }}",
|
|
@@ -214,10 +224,12 @@
|
|
|
214
224
|
"imageTag": "Image Tag",
|
|
215
225
|
"imageTags": "Image Tags",
|
|
216
226
|
"images": "Images",
|
|
227
|
+
"inputFieldIsDisabled": "This field is disabled",
|
|
217
228
|
"insertAndNew": "{{ saveLabel }} {{ typeLabel }} and create a new one.",
|
|
218
229
|
"insertAndRedirect": "{{ saveLabel }} {{ typeLabel }} and be redirected to the {{ typeLabel }}.",
|
|
219
230
|
"insertAndReturn": "{{ saveLabel }} and return to the {{ typeLabel }} listing.",
|
|
220
231
|
"insertTable": "Insert Table",
|
|
232
|
+
"invalid": "invalid",
|
|
221
233
|
"lastEdited": "Last Edited",
|
|
222
234
|
"lastUpdatedBy": "Last saved on {{ updatedAt }} <br /> by {{ updatedBy }}",
|
|
223
235
|
"leavePageDescription": "The content you're trying to edit belongs to another document and must be edited there.\nChanges made to {{ oldTitle }} are saved automatically.",
|
|
@@ -231,7 +243,9 @@
|
|
|
231
243
|
"localize": "Localize...",
|
|
232
244
|
"localizeAllRelated": "Localize all related documents and overwrite existing documents",
|
|
233
245
|
"localizeContent": "Localize Content",
|
|
246
|
+
"localizeLocalized": "Localized",
|
|
234
247
|
"localizeNewRelated": "Localize new related documents",
|
|
248
|
+
"localizeNotYetLocalized": "Not Yet Localized",
|
|
235
249
|
"localized": "Localized the {{ type }} {{ title }} to {{ locale }}",
|
|
236
250
|
"localizingBusy": "Localizing Content",
|
|
237
251
|
"logOut": "Log Out",
|
|
@@ -266,13 +280,19 @@
|
|
|
266
280
|
"mediaDimensions": "Dimensions: {{ width }} 𝗑 {{ height }}",
|
|
267
281
|
"mediaFileSize": "File Size: {{ fileSize }}",
|
|
268
282
|
"mediaKB": "{{ size }}KB",
|
|
283
|
+
"mediaLibraryEndReached": "You've reached the end of the media library.",
|
|
269
284
|
"mediaMB": "{{ size }}MB",
|
|
285
|
+
"mediaManagerErrorRestoring": "Error Restoring",
|
|
286
|
+
"mediaManagerErrorSaving": "Error Saving",
|
|
270
287
|
"mediaUploadViaDrop": "Drop ’em when you’re ready",
|
|
271
288
|
"mediaUploadViaExplorer": "Or click to open the file explorer",
|
|
272
289
|
"mergeCells": "Merge Cells",
|
|
273
290
|
"minLabel": "Min:",
|
|
274
291
|
"minSize": "Min size of {{ width }}x{{ height }}",
|
|
275
292
|
"minUi": "Min: {{ number }}",
|
|
293
|
+
"modalBreadcrumbsDefaultLabel": "Set a label",
|
|
294
|
+
"modalTabsError": "Error",
|
|
295
|
+
"modalTabsErrors": "Errors",
|
|
276
296
|
"modernBuild": "Public-facing modern JavaScript and Sass",
|
|
277
297
|
"modify": "Modify",
|
|
278
298
|
"modifyOrDelete": "Modify / Delete",
|
|
@@ -306,6 +326,9 @@
|
|
|
306
326
|
"nudgeDown": "Nudge Down",
|
|
307
327
|
"nudgeUp": "Nudge Up",
|
|
308
328
|
"numberAdded": "{{ count }} Added",
|
|
329
|
+
"oembedInvalidEmbedUrl": "Invalid embed URL",
|
|
330
|
+
"oembedTypeNotSupported": "Embed type not supported",
|
|
331
|
+
"oembedVideoUrlInvalid": "Video URL invalid",
|
|
309
332
|
"office": "Office",
|
|
310
333
|
"openGlobal": "Open Global Site Settings",
|
|
311
334
|
"openLinkInNewTab": "Open link in new tab",
|
|
@@ -341,10 +364,11 @@
|
|
|
341
364
|
"public": "Public",
|
|
342
365
|
"publish": "Publish",
|
|
343
366
|
"publishBeforeUsingTooltip": "Publish this content before using it in a relationship",
|
|
344
|
-
"publishType": "Publish {{
|
|
367
|
+
"publishType": "Publish {{ type }}",
|
|
345
368
|
"published": "Published",
|
|
346
369
|
"publishingBatchConfirmation": "Are you sure you want to publish {{ count }} {{ type }}?",
|
|
347
370
|
"publishingBatchConfirmationButton": "Yes, publish content.",
|
|
371
|
+
"required": "required",
|
|
348
372
|
"rawCssAndJs": "Raw CSS and JS",
|
|
349
373
|
"rawHtml": "Raw HTML",
|
|
350
374
|
"rawHtmlCode": "Raw HTML (Code)",
|
|
@@ -393,6 +417,7 @@
|
|
|
393
417
|
"richTextBold": "Bold",
|
|
394
418
|
"richTextBulletedList": "Bulleted List",
|
|
395
419
|
"richTextCodeBlock": "Code Block",
|
|
420
|
+
"richTextColor": "Color",
|
|
396
421
|
"richTextH2": "Heading 2 (H2)",
|
|
397
422
|
"richTextH3": "Heading 3 (H3)",
|
|
398
423
|
"richTextH4": "Heading 4 (H4)",
|
|
@@ -415,6 +440,7 @@
|
|
|
415
440
|
"richTextStyleConfigWarning": "Misconfigured rich text style: label: {{ label }}, {{ tag }}",
|
|
416
441
|
"richTextUnderline": "Underline",
|
|
417
442
|
"richTextUndo": "Undo",
|
|
443
|
+
"role": "Role",
|
|
418
444
|
"safeModeActive": "Running in safe mode, not showing raw HTML.",
|
|
419
445
|
"save": "Save",
|
|
420
446
|
"saveDraft": "Save Draft",
|
|
@@ -444,6 +470,7 @@
|
|
|
444
470
|
"selectManyLabel": "Select {{ typeLabel }}",
|
|
445
471
|
"selectOneLabel": "Select {{ typeLabel }}",
|
|
446
472
|
"selectPage": "Select Page",
|
|
473
|
+
"selectPages": "Select Pages",
|
|
447
474
|
"selectedMenuItem": "✓ {{ label }}",
|
|
448
475
|
"sentenceJoiner": " ",
|
|
449
476
|
"settings": "Personal Settings",
|
|
@@ -463,6 +490,7 @@
|
|
|
463
490
|
"submitUpdate": "Submit Update",
|
|
464
491
|
"submitted": "Submitted",
|
|
465
492
|
"submittedDraft": "Submitted Draft",
|
|
493
|
+
"submittedDrafts": "Submitted Drafts",
|
|
466
494
|
"submittedForReview": "Submitted to Admins and Editors for review",
|
|
467
495
|
"subscript": "Subscript",
|
|
468
496
|
"suggestionsHeader": "Try one of these suggestions:",
|
|
@@ -470,6 +498,14 @@
|
|
|
470
498
|
"switchLocalesAndLocalizePage": "Switch locales and localize page to {{ label }}?",
|
|
471
499
|
"table": "Table",
|
|
472
500
|
"tableDescription": "Add tabular content to your page",
|
|
501
|
+
"tagAddTag": "Add Tag",
|
|
502
|
+
"tagSearchApplyTags": "Apply Tags",
|
|
503
|
+
"tagSearchPlaceholder": "Tags...",
|
|
504
|
+
"tagCreateTag": "Create tag \"{{ tag }}\"",
|
|
505
|
+
"tagCreateNewTag": "Create new tag",
|
|
506
|
+
"tagNewTag": "New Tag",
|
|
507
|
+
"tagNoTagsFoundCreateOne": "create {{ tag }}?",
|
|
508
|
+
"tagNoTagsFoundPerhaps": "We couldn't find any matching tags. Perhaps",
|
|
473
509
|
"tagYourImages": "Tag your images to make searching and filtering the media manager easier",
|
|
474
510
|
"tags": "Tags",
|
|
475
511
|
"takeActionAndCreateNew": "{{ saveLabel }} and Create New",
|
|
@@ -595,7 +595,7 @@ module.exports = {
|
|
|
595
595
|
// if the appropriate query parameters were set, rewrite
|
|
596
596
|
// `_id` accordingly. Returns `_id`, after rewriting if appropriate.
|
|
597
597
|
inferIdLocaleAndMode(req, _id) {
|
|
598
|
-
let [
|
|
598
|
+
let [ id, locale, mode ] = _id.split(':');
|
|
599
599
|
if (locale && mode) {
|
|
600
600
|
if (!req.query.aposLocale) {
|
|
601
601
|
req.locale = locale;
|
|
@@ -621,7 +621,7 @@ module.exports = {
|
|
|
621
621
|
// will be interpreted later
|
|
622
622
|
return _id;
|
|
623
623
|
} else {
|
|
624
|
-
return `${
|
|
624
|
+
return `${id}:${locale}:${mode}`;
|
|
625
625
|
}
|
|
626
626
|
},
|
|
627
627
|
getBrowserData(req) {
|
|
@@ -120,15 +120,15 @@
|
|
|
120
120
|
icon="map-marker-icon"
|
|
121
121
|
class="apos-current-locale-icon"
|
|
122
122
|
:icon-size="14"
|
|
123
|
-
title="
|
|
124
|
-
tooltip="
|
|
123
|
+
:title="$t('apostrophe:i18nDefaultLocale')"
|
|
124
|
+
tooltip="apostrophe:i18nCurrentLocale"
|
|
125
125
|
/>
|
|
126
126
|
<AposIndicator
|
|
127
127
|
v-if="isSelected(loc)"
|
|
128
128
|
icon="check-bold-icon"
|
|
129
129
|
class="apos-check-icon"
|
|
130
130
|
:icon-size="10"
|
|
131
|
-
title="
|
|
131
|
+
:title="$t('apostrophe:i18nCurrentlySelectedLocale')"
|
|
132
132
|
/>
|
|
133
133
|
{{ loc.label }}
|
|
134
134
|
<span class="apos-locale-name">
|
|
@@ -136,8 +136,8 @@
|
|
|
136
136
|
</span>
|
|
137
137
|
<span
|
|
138
138
|
v-apos-tooltip="isLocalized(loc)
|
|
139
|
-
? '
|
|
140
|
-
: '
|
|
139
|
+
? 'apostrophe:localizeLocalized'
|
|
140
|
+
: 'apostrophe:localizeNotYetLocalized'"
|
|
141
141
|
class="apos-locale-localized"
|
|
142
142
|
:class="{
|
|
143
143
|
'apos-state-is-localized': isLocalized(loc),
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<template #leftRail>
|
|
26
26
|
<AposModalRail>
|
|
27
27
|
<div class="apos-schema">
|
|
28
|
-
<div class="apos-field">
|
|
28
|
+
<div class="apos-field" data-apos-field="aspectRatio">
|
|
29
29
|
<label class="apos-field__label">
|
|
30
30
|
{{ $t('apostrophe:aspectRatio') }}
|
|
31
31
|
<AposIndicator
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
/>
|
|
38
38
|
</label>
|
|
39
39
|
<AposSelect
|
|
40
|
+
:selected="aspectRatio"
|
|
40
41
|
:choices="aspectRatios"
|
|
41
42
|
:disabled="disableAspectRatio"
|
|
42
43
|
@change="updateAspectRatio"
|
|
@@ -58,7 +59,7 @@
|
|
|
58
59
|
}}
|
|
59
60
|
</div>
|
|
60
61
|
<div class="apos-schema__aligned-fields">
|
|
61
|
-
<div class="apos-field">
|
|
62
|
+
<div class="apos-field" data-apos-field="width">
|
|
62
63
|
<label class="apos-field__label apos-field__label--aligned">
|
|
63
64
|
W
|
|
64
65
|
</label>
|
|
@@ -72,7 +73,7 @@
|
|
|
72
73
|
@blur="blurInput"
|
|
73
74
|
>
|
|
74
75
|
</div>
|
|
75
|
-
<div class="apos-field">
|
|
76
|
+
<div class="apos-field" data-apos-field="height">
|
|
76
77
|
<label class="apos-field__label apos-field__label--aligned">
|
|
77
78
|
H
|
|
78
79
|
</label>
|