From 3227f6618b8b9cd60918690499ea9ad1c9df60bb Mon Sep 17 00:00:00 2001 From: Etienne Laurent Date: Fri, 1 Aug 2025 18:39:28 +0200 Subject: [PATCH 1/6] fix conditional fields in image editor --- modules/@apostrophecms/image/index.js | 18 +++++++++++++++++- .../apos/components/AposMediaManagerEditor.vue | 13 +++++++++---- .../modal/ui/apos/mixins/AposEditorMixin.js | 5 ++++- .../schema/ui/apos/lib/conditionalFields.js | 7 +++++++ 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/modules/@apostrophecms/image/index.js b/modules/@apostrophecms/image/index.js index adb4847dac..adc2ab3a56 100644 --- a/modules/@apostrophecms/image/index.js +++ b/modules/@apostrophecms/image/index.js @@ -104,10 +104,19 @@ module.exports = { fileGroup: 'images', required: true }, + showAlt: { + type: 'boolean', + label: 'Show Alt?', + def: false + }, alt: { type: 'string', label: 'apostrophe:altText', - help: 'apostrophe:altTextHelp' + help: 'apostrophe:altTextHelp', + if: { + 'getOrdersCount()': 10, + showAlt: true + } }, credit: { type: 'string', @@ -131,6 +140,7 @@ module.exports = { fields: [ 'attachment', 'title', + 'showAlt', 'alt', '_tags', 'credit', @@ -399,6 +409,12 @@ module.exports = { }, methods(self) { return { + async getOrdersCount(req, { docId }) { + // simulates API response takes 500ms + await new Promise(resolve => setTimeout(resolve, 2500)); + return 9; + }, + // This method is available as a template helper: apos.image.first // // Find the first image attachment referenced within an object that may diff --git a/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerEditor.vue b/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerEditor.vue index 5a5482d837..77ee17baef 100644 --- a/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerEditor.vue +++ b/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerEditor.vue @@ -87,6 +87,7 @@ :trigger-validation="triggerValidation" :doc-id="docFields.data._id" :following-values="followingValues()" + :conditional-fields="conditionalFields" :server-errors="serverErrors" @validate="triggerValidate" @reset="$emit('modified', false)" @@ -231,6 +232,7 @@ export default { 'docFields.data': { deep: true, handler(newData, oldData) { + this.evaluateConditions(); this.$nextTick(() => { // If either old or new state are an empty object, it's not // "modified." @@ -252,13 +254,14 @@ export default { } } }, - media(newVal) { - this.updateActiveDoc(newVal); + async media(newVal) { + await this.updateActiveDoc(newVal); } }, - mounted() { + async mounted() { this.generateLipKey(); this.$emit('modified', false); + }, methods: { moreMenuHandler(item) { @@ -271,6 +274,8 @@ export default { this.restoreOnly = !!this.activeMedia.archived; this.original = klona(newMedia); this.docFields.data = klona(newMedia); + this.evaluateConditions(); + await this.evaluateExternalConditions(); this.generateLipKey(); await this.unlock(); // Distinguish between an actual doc and an empty placeholder @@ -402,7 +407,7 @@ export default { } await this.cancel(); - this.updateActiveDoc(this.activeMedia); + await this.updateActiveDoc(this.activeMedia); } apos.bus.$emit('admin-menu-click', { itemName: '@apostrophecms/i18n:localize', diff --git a/modules/@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js b/modules/@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js index e00de8aed9..0adba460bb 100644 --- a/modules/@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js +++ b/modules/@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js @@ -78,7 +78,7 @@ export default { async evaluateExternalConditions() { this.externalConditionsResults = await evaluateExternalConditions( this.schema, - this.docId || this.docFields?.data?._docId, + this.docId || this.docFields?.data?._docId || this.docFields?.data?._id, this.$t ); }, @@ -162,7 +162,10 @@ export default { }, evaluateConditions() { + console.log('evaluateConditions', this.schema, this.docFields.data, this.externalConditionsResults); + console.trace(); this.conditionalFields = this.getConditionalFields(); + console.log('conditionalFields', this.conditionalFields); }, // Overridden by components that split the fields into several AposSchemas diff --git a/modules/@apostrophecms/schema/ui/apos/lib/conditionalFields.js b/modules/@apostrophecms/schema/ui/apos/lib/conditionalFields.js index 93a617e0d6..99711249af 100644 --- a/modules/@apostrophecms/schema/ui/apos/lib/conditionalFields.js +++ b/modules/@apostrophecms/schema/ui/apos/lib/conditionalFields.js @@ -14,10 +14,12 @@ export const getConditionTypesObject = () => Object // `docId` - the current docId (from prop or context) // `$t` - the i18n function (usually `this.$t`) export async function evaluateExternalConditions(schema, docId, $t) { + console.log('evaluateExternalConditions', schema, docId); const externalConditionsResults = getConditionTypesObject(); for (const field of schema) { for (const conditionType of conditionTypes) { + console.log(field[conditionType]); if (field[conditionType]) { const externalConditionKeys = Object .entries(field[conditionType]) @@ -25,6 +27,7 @@ export async function evaluateExternalConditions(schema, docId, $t) { .filter(Boolean); const uniqExternalConditionKeys = [ ...new Set(externalConditionKeys) ]; + console.log('uniqExternalConditionKeys', uniqExternalConditionKeys); try { const promises = uniqExternalConditionKeys @@ -51,6 +54,7 @@ export async function evaluateExternalConditions(schema, docId, $t) { } } } + console.log('externalConditionsResults', externalConditionsResults); return externalConditionsResults; function getExternalConditionKeys([ key, val ], conditionType) { @@ -66,6 +70,7 @@ export async function evaluateExternalConditions(schema, docId, $t) { } export async function evaluateExternalCondition(conditionKey, fieldId, docId) { + console.log('XHR'); const { result } = await apos.http.get( `${apos.schema.action}/evaluate-external-condition`, { @@ -115,6 +120,7 @@ export function getConditionalFields( values, externalConditionsResults ) { + console.log('getConditionalFields', schema, values, externalConditionsResults); const result = getConditionTypesObject(); for (const field of schema) { @@ -130,6 +136,7 @@ export function getConditionalFields( } } + console.log('result', result); return result; // Handle external conditions as a voter function. From bd20216ee5b031a6b892945e862cb3b03cf4e73f Mon Sep 17 00:00:00 2001 From: Etienne Laurent Date: Fri, 1 Aug 2025 18:41:10 +0200 Subject: [PATCH 2/6] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01207d3e31..4697b88b60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ * You can now use checkboxes as filter `inputType`. * Fixed a regression that prevented multiple variations of `p` with different classes from being recognized again when reopening the rich text editor, even if they are all on the style menu. This was caused by knock-on effects of upstream changes in tiptap and prosemirror and our previous efforts to mitigate these. Those upstream changes were correct, but they did have certain side effects in ApostropheCMS. By more fully specifying the desired behavior, we have now fully corrected the issue at the ApostropheCMS level. * Correctly update alt attribute of images in rich text widgets. +* Make conditional fields work in Image Editor. ### Security From f02a0078e2cb1789d5daacbc8de465ee86cd71b3 Mon Sep 17 00:00:00 2001 From: Etienne Laurent Date: Fri, 1 Aug 2025 18:43:50 +0200 Subject: [PATCH 3/6] remove logs --- .../@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js | 3 --- .../@apostrophecms/schema/ui/apos/lib/conditionalFields.js | 7 ------- 2 files changed, 10 deletions(-) diff --git a/modules/@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js b/modules/@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js index 0adba460bb..d223a526d0 100644 --- a/modules/@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js +++ b/modules/@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js @@ -162,10 +162,7 @@ export default { }, evaluateConditions() { - console.log('evaluateConditions', this.schema, this.docFields.data, this.externalConditionsResults); - console.trace(); this.conditionalFields = this.getConditionalFields(); - console.log('conditionalFields', this.conditionalFields); }, // Overridden by components that split the fields into several AposSchemas diff --git a/modules/@apostrophecms/schema/ui/apos/lib/conditionalFields.js b/modules/@apostrophecms/schema/ui/apos/lib/conditionalFields.js index 99711249af..93a617e0d6 100644 --- a/modules/@apostrophecms/schema/ui/apos/lib/conditionalFields.js +++ b/modules/@apostrophecms/schema/ui/apos/lib/conditionalFields.js @@ -14,12 +14,10 @@ export const getConditionTypesObject = () => Object // `docId` - the current docId (from prop or context) // `$t` - the i18n function (usually `this.$t`) export async function evaluateExternalConditions(schema, docId, $t) { - console.log('evaluateExternalConditions', schema, docId); const externalConditionsResults = getConditionTypesObject(); for (const field of schema) { for (const conditionType of conditionTypes) { - console.log(field[conditionType]); if (field[conditionType]) { const externalConditionKeys = Object .entries(field[conditionType]) @@ -27,7 +25,6 @@ export async function evaluateExternalConditions(schema, docId, $t) { .filter(Boolean); const uniqExternalConditionKeys = [ ...new Set(externalConditionKeys) ]; - console.log('uniqExternalConditionKeys', uniqExternalConditionKeys); try { const promises = uniqExternalConditionKeys @@ -54,7 +51,6 @@ export async function evaluateExternalConditions(schema, docId, $t) { } } } - console.log('externalConditionsResults', externalConditionsResults); return externalConditionsResults; function getExternalConditionKeys([ key, val ], conditionType) { @@ -70,7 +66,6 @@ export async function evaluateExternalConditions(schema, docId, $t) { } export async function evaluateExternalCondition(conditionKey, fieldId, docId) { - console.log('XHR'); const { result } = await apos.http.get( `${apos.schema.action}/evaluate-external-condition`, { @@ -120,7 +115,6 @@ export function getConditionalFields( values, externalConditionsResults ) { - console.log('getConditionalFields', schema, values, externalConditionsResults); const result = getConditionTypesObject(); for (const field of schema) { @@ -136,7 +130,6 @@ export function getConditionalFields( } } - console.log('result', result); return result; // Handle external conditions as a voter function. From 87d68eaa886adc7876a0842dc0967acba5e5cb32 Mon Sep 17 00:00:00 2001 From: Etienne Laurent Date: Fri, 1 Aug 2025 18:44:23 +0200 Subject: [PATCH 4/6] revert unnecessary change --- .../image/ui/apos/components/AposMediaManagerEditor.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerEditor.vue b/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerEditor.vue index 77ee17baef..a12f810749 100644 --- a/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerEditor.vue +++ b/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerEditor.vue @@ -258,10 +258,9 @@ export default { await this.updateActiveDoc(newVal); } }, - async mounted() { + mounted() { this.generateLipKey(); this.$emit('modified', false); - }, methods: { moreMenuHandler(item) { From 59b620cb296c6137bff2c0f23823f4546cb76cb0 Mon Sep 17 00:00:00 2001 From: Etienne Laurent Date: Mon, 4 Aug 2025 13:59:28 +0200 Subject: [PATCH 5/6] revert image module --- modules/@apostrophecms/image/index.js | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/modules/@apostrophecms/image/index.js b/modules/@apostrophecms/image/index.js index adc2ab3a56..adb4847dac 100644 --- a/modules/@apostrophecms/image/index.js +++ b/modules/@apostrophecms/image/index.js @@ -104,19 +104,10 @@ module.exports = { fileGroup: 'images', required: true }, - showAlt: { - type: 'boolean', - label: 'Show Alt?', - def: false - }, alt: { type: 'string', label: 'apostrophe:altText', - help: 'apostrophe:altTextHelp', - if: { - 'getOrdersCount()': 10, - showAlt: true - } + help: 'apostrophe:altTextHelp' }, credit: { type: 'string', @@ -140,7 +131,6 @@ module.exports = { fields: [ 'attachment', 'title', - 'showAlt', 'alt', '_tags', 'credit', @@ -409,12 +399,6 @@ module.exports = { }, methods(self) { return { - async getOrdersCount(req, { docId }) { - // simulates API response takes 500ms - await new Promise(resolve => setTimeout(resolve, 2500)); - return 9; - }, - // This method is available as a template helper: apos.image.first // // Find the first image attachment referenced within an object that may From 62179914e7b4edf7d3c6bb04bef838e9c34071c1 Mon Sep 17 00:00:00 2001 From: Etienne Laurent Date: Wed, 20 Aug 2025 13:48:18 +0200 Subject: [PATCH 6/6] re-order changelog avec merge --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 636e4aa784..04472aa63f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ ### Fixes * The `?render-areas=1` API feature now correctly disregards areas in separate documents loaded via relationship fields. Formerly their presence resulted in an error, not a rendering. +* Make conditional fields work in Image Editor. ## 4.20.0 (2025-08-06) @@ -38,7 +39,6 @@ * You can now use checkboxes as filter `inputType`. * Fixed a regression that prevented multiple variations of `p` with different classes from being recognized again when reopening the rich text editor, even if they are all on the style menu. This was caused by knock-on effects of upstream changes in tiptap and prosemirror and our previous efforts to mitigate these. Those upstream changes were correct, but they did have certain side effects in ApostropheCMS. By more fully specifying the desired behavior, we have now fully corrected the issue at the ApostropheCMS level. * Correctly update alt attribute of images in rich text widgets. -* Make conditional fields work in Image Editor. ### Security