From 26eb0c2f3d47a66a0ca680dfc726c7b2e449b6ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1io=20Simonassi?= Date: Tue, 17 Dec 2024 11:19:17 -0300 Subject: [PATCH] Merge remote-tracking branch 'origin/IIMAGE-8' --- README.md | 1 + build.gradle | 1 + gradle.properties | 4 +- .../admin/widgets/iimage/iimage.html | 6 +-- src/main/resources/assets/css/styles.css | 4 ++ src/main/resources/assets/js/main.js | 12 +++-- src/main/resources/lib/modules/iimage.js | 47 +++++++++++++++++-- .../services/import-image/import-image.js | 28 ++++++++++- 8 files changed, 91 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index e1e1c9f..beb8a6c 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ cd imageshop-xp | Version | XP version | | ------- | ------------ | | 1.0.x | 7.9.0 | +| 2.0.x | 7.11.0 | ## License and credits The application is licensed under the [Enonic License](https://github.com/99x/imageshop-xp/blob/main/LICENSE.txt) diff --git a/build.gradle b/build.gradle index 8112a3e..91684d3 100644 --- a/build.gradle +++ b/build.gradle @@ -24,6 +24,7 @@ dependencies { include "com.enonic.xp:lib-task:${xpVersion}" include "com.enonic.xp:lib-node:${xpVersion}" include "com.enonic.xp:lib-context:${xpVersion}" + include "com.enonic.xp:lib-schema:${xpVersion}" include "com.enonic.lib:lib-thymeleaf:2.1.0" include 'com.enonic.lib:lib-http-client:3.2.2' include "com.enonic.lib:lib-cron:1.1.2" diff --git a/gradle.properties b/gradle.properties index 64e5273..7121af1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,13 +1,13 @@ # Gradle Project settings projectName = imageshop -version = 1.0.3 +version = 2.0.0 # XP App values appDisplayName = ImageShop appName = io.99x.imageshop vendorName = 99x vendorUrl = https://99x.io -xpVersion = 7.9.2 +xpVersion = 7.11.0 # Settings for publishing to a Maven repo group = io.99x \ No newline at end of file diff --git a/src/main/resources/admin/widgets/iimage/iimage.html b/src/main/resources/admin/widgets/iimage/iimage.html index 9841999..ccb2f46 100644 --- a/src/main/resources/admin/widgets/iimage/iimage.html +++ b/src/main/resources/admin/widgets/iimage/iimage.html @@ -12,9 +12,9 @@ Select an input to set the image diff --git a/src/main/resources/assets/css/styles.css b/src/main/resources/assets/css/styles.css index d887a5f..0c188e8 100644 --- a/src/main/resources/assets/css/styles.css +++ b/src/main/resources/assets/css/styles.css @@ -29,4 +29,8 @@ widget.iimage-wrapper button { margin-bottom: 8px; border: none; cursor: pointer; +} + +widget.iimage-wrapper details ul li { + margin-bottom: 8px; } \ No newline at end of file diff --git a/src/main/resources/assets/js/main.js b/src/main/resources/assets/js/main.js index be76f91..5cefab3 100644 --- a/src/main/resources/assets/js/main.js +++ b/src/main/resources/assets/js/main.js @@ -5,11 +5,15 @@ function main() { function setMessageEventListener (event) { const eventData = event.data.split(';') - const propertyNameRadioElement = document.querySelector(`input[name="inputName"]:checked`) || {} + const selectedPropertyRadioElement = document.querySelector(`input[name="inputName"]:checked`) || {} changeUploadButtonState('loading') - storeImageInEnonic({ imageData: JSON.parse(eventData[0]), propertyName: propertyNameRadioElement.value }) + storeImageInEnonic({ + imageData: JSON.parse(eventData[0]), + propertyName: selectedPropertyRadioElement.value, + propertyPath: selectedPropertyRadioElement.getAttribute('data-property-path') + }) } const imageshop = { @@ -61,10 +65,12 @@ function syncImageInfo(e) { * @param {Object} params * @param {Object} params.imageData image object returned * @param {String} params.propertyName object property name to store the image in Enonic + * @param {String?} params.propertyPath object property path if the input selected is a part */ function storeImageInEnonic(params) { const imageData = params.imageData const propertyName = params.propertyName + const propertyPath = params.propertyPath const importImageServiceUrl = document.querySelector('[data-import-image-service-url]').getAttribute('data-import-image-service-url'); const openImageShopButton = document.getElementById('imageshop-button'); @@ -73,7 +79,7 @@ function storeImageInEnonic(params) { fetch(importImageServiceUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ imageData, propertyName }) + body: JSON.stringify({ imageData, propertyName, propertyPath }) }) .then(response => response.json()) .then(data => { diff --git a/src/main/resources/lib/modules/iimage.js b/src/main/resources/lib/modules/iimage.js index 5c4f106..a294bae 100644 --- a/src/main/resources/lib/modules/iimage.js +++ b/src/main/resources/lib/modules/iimage.js @@ -3,6 +3,7 @@ const libs = { content: require('/lib/xp/content'), context: require('/lib/xp/context'), + schema: require('/lib/xp/schema'), node: require('/lib/xp/node'), io: require('/lib/xp/io'), i18n: require('/lib/xp/i18n'), @@ -12,6 +13,7 @@ const libs = { } module.exports = { + getConnection, getImageShopURL, getInputsAllowedToUploadImage, getSite, @@ -65,13 +67,48 @@ function getInputsAllowedToUploadImage(contentId) { const currentContent = libs.content.get({ key: contentId }) const currentContentType = libs.content.getType(currentContent.type) + + const connection = getConnection() + + let partsWithImageSelector = [] + + if (connection) { + const n = connection.draft.get(contentId) + const parts = n.components.filter(c => c.type === 'part') + + let partIndex = 0 + + parts.forEach(p => { + const descriptor = p.part.descriptor + + const part = libs.schema.getComponent({ key: descriptor, type: 'PART' }) + + const form = explodeFieldSets(part.form) + + form.filter(item => item.formItemType === 'Input' && item.inputType === 'ImageSelector').forEach(item => { + partIndex++ + + let label = `${item.label} (${part.displayName} PART) (${partIndex})` + + partsWithImageSelector.push({ + name: item.name, + label, + path: p.path, + type: 'PART' + }) + }) + }) + } + //Make fieldsets flat - let form = explodeFieldSets(currentContentType.form) + const form = explodeFieldSets(currentContentType.form) return form.filter(item => item.formItemType === 'Input' && item.inputType === 'ImageSelector').map(item => ({ name: item.name, - label: item.label - })) + label: item.label, + path: '', + type: 'CONTENT-TYPE' + })).concat(partsWithImageSelector) } /** @@ -220,6 +257,10 @@ function translate (key, values = []) { return libs.i18n.localize({ key: key, locale: 'no', values }) } +/** + * Gets the connection from the current context repository for draft and master branches. + * @returns {{ draft: Object, master: Object }} + */ function getConnection () { const context = libs.context.get() diff --git a/src/main/resources/services/import-image/import-image.js b/src/main/resources/services/import-image/import-image.js index 4198e4c..7b346b6 100644 --- a/src/main/resources/services/import-image/import-image.js +++ b/src/main/resources/services/import-image/import-image.js @@ -15,6 +15,7 @@ exports.post = function (request) { /** @type ImageInfo */ const imageData = data.imageData || {} const propertyName = data.propertyName + const propertyPath = data.propertyPath if (!params.contentId) { return { @@ -78,7 +79,7 @@ exports.post = function (request) { const currentContent = libs.content.get({ key: params.contentId }) - if (currentContent && propertyName) { + if (currentContent && propertyName && !propertyPath) { const updatedContent = libs.content.modify({ key: params.contentId, editor: function (c) { @@ -91,6 +92,31 @@ exports.post = function (request) { image.wasContentUpdated = !!updatedContent } + if (currentContent && propertyName && propertyPath) { + const connection = libs.iimage.getConnection() + + if (connection) { + connection.draft.modify({ + key: params.contentId, + editor: function (n) { + n.components = n.components.map(component => { + if (component.type !== 'part' || component.path !== propertyPath) return component + + const descriptor = String(component.part.descriptor).split(':') + const appName = descriptor[0].replace(/\./g, "-"); + const partName = descriptor[1] + + component.part.config[appName][partName][propertyName] = image._id + + return component + }) + + return n + } + }) + } + } + image.editURL = generateEditURL({ request, imageId: image._id }) }