Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## UNRELEASED

### Changes

* When selecting pieces or pages to populate a relationship, the "New Piece" / "New Page" buttons are easier to find. They are no longer hidden away in a context menu.
* When you create a new item while editing a relationship, that item is automatically selected, as long as you have not already reached `max` for that relationship.
* When the user chooses to create a new document while selecting pieces or pages to populate a relationship, the "save draft and preview" and "publish and view" options are no longer offered. This ensures that the user is able to complete the selection process. The page or piece can still be edited in context later.

## 4.23.0 (2025-10-30)

### Adds
Expand All @@ -24,6 +32,8 @@

### Fixes

* When creating a link or adding an image in the rich text editor, it is now possible to create or edit a page or piece as part of that process without losing the ability to finish creating the link or adding the image.
* Context menus and other controls lower in the modal stack no longer close themselves prematurely based on events in the top modal, e.g. escape key, outside clicks, clicks on context menus in the top modal, clicks on notifications, etc. These fixes also facilitate the flow of creating a new document as part of selecting a document.
* The `render-areas` query parameter now works correctly with areas nested in array items.
* Fix min size calculation for image widgets configured with an aspect ratio.
* Added missing `await` in helper library function for the asset module, ensuring JS assets build reliably.
Expand Down Expand Up @@ -156,11 +166,13 @@ Switch body attributes to this new div to keep supporting body styles in breakpo

* Set the `Cache-Control` header to `no-store` for error pages in order to prevent the risk of serving stale error pages to users.
* Updates rich-text default configuration.
* For added convenience, the "New" button is no longer hidden away in the kebab menu when selecting a page or piece.

### Fixes

* The Download links in the media library now immediately download the file as expected, rather than navigating to the image in the current tab. `AposButton` now supports the `:download="true"` prop as expected.
* Using an API key with the editor, contributor or guest role now have a `req` object with the corresponding rights. The old behavior gave non-admin API keys less access than expected.
* The `button: true` option for utility operations now works as expected.

## 4.17.1 (2025-05-16)

Expand Down
12 changes: 11 additions & 1 deletion modules/@apostrophecms/admin-bar/ui/apos/apps/AposAdminBar.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import createApp from 'Modules/@apostrophecms/ui/lib/vue';

export default function() {
if (!apos.adminBar) {
return;
}
apos.adminBar.disabledRefreshCount = 0;
apos.adminBar.disableRefresh = () => {
apos.adminBar.disabledRefreshCount++;
};
apos.adminBar.enableRefresh = () => {
apos.adminBar.disabledRefreshCount--;
};
const component = apos.vueComponents.TheAposAdminBar;
// Careful, login page is in user scene but has no admin bar
const el = document.querySelector('#apos-admin-bar');
if (!apos.adminBar || !el || apos?.adminBar.showAdminBar === false) {
if (!el || apos.adminBar.showAdminBar === false) {
return;
}
const app = createApp(component, { items: apos.adminBar.items || [] });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,10 @@ export default {
}
},
async onContentChanged(e) {
if (apos.adminBar.disabledRefreshCount > 0) {
return;
}

if (
(e.doc && (e.doc._id === this.context._id)) ||
(e.docIds && e.docIds.includes(this.context._id))
Expand Down Expand Up @@ -566,7 +570,6 @@ export default {
this.rememberLastBaseContext();
return;
}

const { action } = window.apos.modules[this.context.type];
let doc;
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,8 @@ export default {
this.getFocus($event, null);
document.activeElement.blur();
this.$refs.wrapper.focus();
// Don't confuse escape key handlers in other modal layers etc.
$event.stopPropagation();
}
},

Expand Down
6 changes: 4 additions & 2 deletions modules/@apostrophecms/area/ui/apos/logic/AposAreaEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { createId } from '@paralleldrive/cuid2';
import { mapState, mapActions } from 'pinia';
import AposThemeMixin from 'Modules/@apostrophecms/ui/mixins/AposThemeMixin';
import newInstance from 'apostrophe/modules/@apostrophecms/schema/lib/newInstance.js';
import { useModalStore } from 'Modules/@apostrophecms/ui/stores/modal';
import cloneWidget from 'Modules/@apostrophecms/area/lib/clone-widget.js';
import { useWidgetStore } from 'Modules/@apostrophecms/ui/stores/widget';

Expand Down Expand Up @@ -165,6 +166,7 @@ export default {
}
},
mounted() {
this.modalStore = useModalStore();
this.bindEventListeners();
},
beforeUnmount() {
Expand All @@ -179,7 +181,7 @@ export default {
apos.bus.$on('command-menu-area-duplicate-widget', this.handleDuplicate);
apos.bus.$on('command-menu-area-paste-widget', this.handlePaste);
apos.bus.$on('command-menu-area-remove-widget', this.handleRemove);
window.addEventListener('keydown', this.focusParentEvent);
this.modalStore.onKeyDown(this.$el, this.focusParentEvent);
},
unbindEventListeners() {
apos.bus.$off('area-updated', this.areaUpdatedHandler);
Expand All @@ -188,7 +190,7 @@ export default {
apos.bus.$off('command-menu-area-duplicate-widget', this.handleDuplicate);
apos.bus.$off('command-menu-area-paste-widget', this.handlePaste);
apos.bus.$off('command-menu-area-remove-widget', this.handleRemove);
window.removeEventListener('keydown', this.focusParentEvent);
this.modalStore.offKeyDown(this.focusParentEvent);
},
isInsideContentEditable() {
return document.activeElement.closest('[contenteditable]') !== null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,12 @@ export default {
type: Object,
required: true
},
// If true, we're creating this document to be included
// in a relationship
hasRelationshipField: {
type: Boolean,
default: false
},
// Optional. If present, properties of this object
// override the defaults for the corresponding fields.
// Currently supported only for new instances, not
Expand Down Expand Up @@ -775,7 +781,7 @@ export default {
def: true
}
];
if (canPreview) {
if (canPreview && !this.hasRelationshipField) {
menu.push({
label: {
key: 'apostrophe:takeActionAndView',
Expand All @@ -788,7 +794,7 @@ export default {
}
});
}
if (canNew) {
if (canNew && !this.hasRelationshipField) {
menu.push({
label: {
key: 'apostrophe:takeActionAndCreateNew',
Expand All @@ -809,7 +815,7 @@ export default {
description: 'apostrophe:saveDraftDescription'
});
}
if (this.manuallyPublished && canPreview) {
if (this.manuallyPublished && canPreview && !this.hasRelationshipField) {
menu.push({
label: {
key: 'apostrophe:saveDraftAndPreview',
Expand All @@ -822,7 +828,7 @@ export default {
}
});
};
if (this.manuallyPublished && canNew) {
if (this.manuallyPublished && canNew && !this.hasRelationshipField) {
menu.push({
label: 'apostrophe:saveDraftAndCreateNew',
action: 'onSaveDraftAndNew',
Expand Down
6 changes: 6 additions & 0 deletions modules/@apostrophecms/doc/ui/apos/apps/AposDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ export default () => {
// `copyOf` is an optional, existing document from which properties should be
// copied. It is present for BC.
//
// `hasRelationshipField` is a hint indicating the document is being
// edited or created as part of selecting documents of its type for
// a relationship.
//
// For new documents, a `values` object may optionally be passed. Its properties
// override the defaults for any matching schema fields.
//
Expand All @@ -26,6 +30,7 @@ export default () => {
_id,
copyOfId,
copyOf,
hasRelationshipField,
values
}) => {
if (!type) {
Expand All @@ -46,6 +51,7 @@ export default () => {
moduleName: type,
docId: _id,
copyOfId,
hasRelationshipField,
values
});
};
Expand Down
8 changes: 5 additions & 3 deletions modules/@apostrophecms/modal/ui/apos/components/AposModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -265,16 +265,18 @@ onMounted(async () => {
renderingElements.value = false;
}
store.updateModalData(props.modalData.id, { modalEl: modalEl.value });
window.addEventListener('keydown', onKeydown);
store.onKeyDown(modalEl.value, onKeydown);
});

onUnmounted(() => {
window.removeEventListener('keydown', onKeydown);
store.offKeyDown(onKeydown);
});

function onKeydown(e) {
const hasPressedEsc = e.keyCode === 27;
const hasPressedEsc = e.key === 'Escape';
if (hasPressedEsc) {
// Don't confuse escape key handlers in other modal layers etc.
e.stopPropagation();
close(e);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<div
role="alert"
:class="classList"
data-apos-notification=""
>
<span class="apos-notification__indicator">
<AposIndicator
Expand Down
1 change: 1 addition & 0 deletions modules/@apostrophecms/page/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ module.exports = {
new: {
canCreate: true,
relationship: true,
button: true,
label: {
key: 'apostrophe:newDocType',
type: '$t(apostrophe:page)'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ export default {
});
},
async mounted() {
this.modalStore = useModalStore();
this.headers = this.computeHeaders();
// Get the data. This will be more complex in actuality.
this.modal.active = true;
Expand All @@ -178,7 +179,8 @@ export default {
async create() {
const doc = await apos.modal.execute(this.moduleOptions.components.editorModal, {
moduleName: this.moduleName,
filterValues: this.filterValues
filterValues: this.filterValues,
hasRelationshipField: !!this.relationshipField
});
if (!doc) {
// Cancel clicked
Expand Down Expand Up @@ -585,6 +587,11 @@ export default {
if (action === 'archive') {
this.checked = this.checked.filter(checkedId => doc._id !== checkedId);
}
if (this.relationshipField && (action === 'insert') && this.modalStore.isTopManager(this)) {
const newDocs = [ ...this.checkedDocs, doc ];
const limit = this.relationshipField?.max || newDocs.length;
this.setCheckedDocs(newDocs.slice(0, limit));
}
}
},
async switchLocale({ locale, localized }) {
Expand Down
1 change: 1 addition & 0 deletions modules/@apostrophecms/piece-type/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ module.exports = {
new: {
canCreate: true,
relationship: true,
button: true,
label: {
key: 'apostrophe:newDocType',
type: `$t(${self.options.label})`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ export default {
};
},
computed: {
...mapState(useModalStore, [ 'activeModal', 'updateModalData' ]),
...mapState(useModalStore, [ 'activeModal' ]),
moduleOptions() {
return window.apos.modules[this.moduleName];
},
Expand Down Expand Up @@ -272,6 +272,7 @@ export default {
});
},
async mounted() {
this.modalStore = useModalStore();
this.bindShortcuts();
this.headers = this.computeHeaders();
// Get the data. This will be more complex in actuality.
Expand All @@ -280,7 +281,9 @@ export default {
await this.manageAllPiecesTotal();
this.modal.triggerFocusRefresh++;

apos.bus.$on('content-changed', this.onContentChanged);
apos.bus.$on('content-changed', (e) => {
this.onContentChanged(e);
});
apos.bus.$on('command-menu-manager-create-new', this.create);
apos.bus.$on('command-menu-manager-close', this.confirmAndCancel);
},
Expand Down Expand Up @@ -311,7 +314,8 @@ export default {
await apos.modal.execute(apos.modules[moduleName].components.editorModal, {
moduleName,
docId: piece && piece._id,
filterValues: this.filterValues
filterValues: this.filterValues,
hasRelationshipField: !!this.relationshipField
});
},
async finishSaved() {
Expand Down Expand Up @@ -489,10 +493,10 @@ export default {
}
},
bindShortcuts() {
window.addEventListener('keydown', this.shortcutNew);
this.modalStore.onKeyDown(this.$el, this.shortcutNew);
},
destroyShortcuts() {
window.removeEventListener('keydown', this.shortcutNew);
this.modalStore.offKeyDown(this.shortcutNew);
},
computeHeaders() {
let headers = this.moduleOptions.columns || [];
Expand Down Expand Up @@ -572,6 +576,11 @@ export default {
if (!types.includes(this.moduleName)) {
return;
}
if (this.relationshipField && (action === 'insert') && this.modalStore.isTopManager(this)) {
const newDocs = [ ...this.checkedDocs, doc ];
const limit = this.relationshipField?.max || newDocs.length;
this.setCheckedDocs(newDocs.slice(0, limit));
}
if (
docIds ||
!doc.aposLocale ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,16 @@ export default {

methods: {
async handleUtilityOperation(item) {
const operation = [

const sources = [
...this.utilityOperations.menu,
...this.utilityOperations.buttons
]
];
const operation = sources
.find((op) => op.action === item.action);

if (!operation) {
// eslint-disable-next-line no-console
console.error('utility operation definition was not found');
console.error('utility operation definition was not found:', item);
return;
}

Expand All @@ -89,9 +90,13 @@ export default {
action: item.action,
labels: this.moduleLabels,
messages: operation.messages,
// Indicates the operation is taking place as
// part of editing a relationship
hasRelationshipField: this.hasRelationshipField,
...modalOptions
});
} else if (event) {
payload.hasRelationshipField = this.hasRelationshipField;
apos.bus.$emit(event, payload);
} else {
// For backwards compatibility, because it did nothing before we should
Expand Down
Loading