From 40cc20ec689eca15bc298741fde0785288b4c1b1 Mon Sep 17 00:00:00 2001 From: brandonkelly Date: Fri, 18 Mar 2022 06:21:14 -0700 Subject: [PATCH] =?UTF-8?q?Reimplement=20asset=20selection=20swapping=20on?= =?UTF-8?q?=20=E2=80=9CSave=20as=20a=20new=20asset=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves #8974 --- CHANGELOG.md | 4 +- src/controllers/AssetsController.php | 2 +- src/elements/Asset.php | 12 ++- .../_components/fieldtypes/Assets/input.twig | 19 +++-- .../fieldtypes/Categories/input.twig | 3 +- .../_includes/forms/elementSelect.twig | 12 ++- src/web/assets/cp/dist/cp.js | 2 +- src/web/assets/cp/dist/cp.js.map | 2 +- src/web/assets/cp/dist/css/cp.css | 2 +- src/web/assets/cp/dist/css/cp.css.map | 2 +- src/web/assets/cp/src/css/_main.scss | 8 +- src/web/assets/cp/src/js/AssetSelectInput.js | 31 ++++--- .../cp/src/js/BaseElementSelectInput.js | 82 ++++++++++++++----- src/web/assets/cp/src/js/ElementEditor.js | 2 + .../assets/cp/src/js/ElementEditorSlideout.js | 1 + src/web/assets/cp/src/js/Slideout.js | 1 + 16 files changed, 129 insertions(+), 56 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 112cb432e7e..4f1a0d38b80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +### Changed +- When an image is saved as a new asset from the Image Editor via an Assets field, the Assets field will now automatically replace the selected asset with the new one. ([#8974](https://github.com/craftcms/cms/discussions/8974)) + ### Deprecated - Deprecated `craft\base\ApplicationTrait::getInstalledSchemaVersion()`. @@ -438,7 +441,6 @@ - Filtering users by `active`, `pending`, and `locked` statuses no longer excludes suspended users. - `credentialed` and `inactive` are now reserved user group handles. - Assets fields that are restricted to a single location can now be configured to allow selection within subfolders of that location. ([#9070](https://github.com/craftcms/cms/discussions/9070)) -- When an image is saved as a new asset from the Image Editor via an Assets field, the Assets field will now automatically replace the selected asset with the new one. ([#8974](https://github.com/craftcms/cms/discussions/8974)) - `alt` is now a reserved field handle for volume field layouts. - Volumes no longer have “types”, and their file operations are now delegated to a filesystem selected by an “Asset Filesystem” setting on the volume. - Volumes now have a “Transform Filesystem” setting, which can be used to choose which filesystem image transforms should be stored in. (The volume’s Asset Filesystem will be used by default.) diff --git a/src/controllers/AssetsController.php b/src/controllers/AssetsController.php index b07641aa34b..27ed2ba5be3 100644 --- a/src/controllers/AssetsController.php +++ b/src/controllers/AssetsController.php @@ -922,7 +922,7 @@ public function actionSaveImage(): Response // Don't validate required custom fields Craft::$app->getElements()->saveElement($newAsset); - $output['elementId'] = $newAsset->id; + $output['newAssetId'] = $newAsset->id; } } catch (Throwable $exception) { return $this->asFailure($exception->getMessage()); diff --git a/src/elements/Asset.php b/src/elements/Asset.php index 30e0514e77f..a7d587f84e5 100644 --- a/src/elements/Asset.php +++ b/src/elements/Asset.php @@ -2068,7 +2068,17 @@ public function getPreviewHtml(): string $('#$editBtnId').on('click', () => { new Craft.AssetImageEditor($this->id, { allowDegreeFractions: Craft.isImagick, - onSave: () => { + onSave: data => { + if (data.newAssetId) { + // If this is within an Assets field’s editor slideout, replace the selected asset + const slideout = $('#$editBtnId').closest('[data-slideout]').data('slideout'); + if (slideout && slideout.settings.elementSelectInput) { + slideout.settings.elementSelectInput.replaceElement(slideout.\$element.data('id'), data.newAssetId) + .catch(() => {}); + } + return; + } + $updatePreviewThumbJs }, }); diff --git a/src/templates/_components/fieldtypes/Assets/input.twig b/src/templates/_components/fieldtypes/Assets/input.twig index d3b118868cb..1f231a170ca 100644 --- a/src/templates/_components/fieldtypes/Assets/input.twig +++ b/src/templates/_components/fieldtypes/Assets/input.twig @@ -8,6 +8,7 @@ {% set condition = condition ?? null -%} {% set criteria = criteria ?? null -%} {% set storageKey = storageKey ?? null -%} +{% set disabled = (disabled ?? false) ? true : false %}
@@ -19,19 +20,27 @@ {% endfor %}
- {% if sources %} -
+
+ {% if sources %} {{ tag('button', { type: 'button', text: selectionLabel, - class: ['btn', 'add', 'icon', 'dashed'], + class: [ + 'btn', + 'add', + 'icon', + 'dashed', + disabled ? 'disabled', + limit and elements|length >= limit ? 'hidden', + ], aria: { label: selectionLabel, describedby: describedBy ?? false, }, }) }} -
- {% endif %} + {% endif %} + +
{% do view.registerAssetBundle("craft\\web\\assets\\prismjs\\PrismJsAsset") %} diff --git a/src/templates/_components/fieldtypes/Categories/input.twig b/src/templates/_components/fieldtypes/Categories/input.twig index ed4aea20232..53513f270a5 100644 --- a/src/templates/_components/fieldtypes/Categories/input.twig +++ b/src/templates/_components/fieldtypes/Categories/input.twig @@ -17,8 +17,9 @@ {% endnav %} -
+
+
diff --git a/src/templates/_includes/forms/elementSelect.twig b/src/templates/_includes/forms/elementSelect.twig index 0d0c15fb398..7f8005329d3 100644 --- a/src/templates/_includes/forms/elementSelect.twig +++ b/src/templates/_includes/forms/elementSelect.twig @@ -41,10 +41,17 @@ {% endfor %} -
+
{{ tag('button', { type: 'button', - class: ['btn', 'add', 'icon', 'dashed', disabled ? 'disabled']|filter, + class: [ + 'btn', + 'add', + 'icon', + 'dashed', + disabled ? 'disabled', + limit and elements|length >= limit ? 'hidden', + ]|filter, text: selectionLabel ?? 'Choose'|t('app'), disabled: disabled, aria: { @@ -52,6 +59,7 @@ describedby: describedBy ?? false, } }) }} +
{% endtag %} diff --git a/src/web/assets/cp/dist/cp.js b/src/web/assets/cp/dist/cp.js index 3995360b862..b2c73bcd961 100644 --- a/src/web/assets/cp/dist/cp.js +++ b/src/web/assets/cp/dist/cp.js @@ -1,3 +1,3 @@ /*! For license information please see cp.js.LICENSE.txt */ -(function(){var __webpack_modules__={3839:function(){Craft.AddressesInput=Garnish.Base.extend({$container:null,$addBtn:null,$cards:null,init:function(t,e){var i=this;this.$container=$(t),this.setSettings(e,Craft.AddressesInput.defaults),this.$container.data("addresses")&&(console.warn("Double-instantiating an address input on an element"),this.$container.data("addresses").destroy()),this.$container.data("addresses",this),this.$addBtn=this.$container.find("> .btn.add"),this.$cards=this.$container.find("> .address-card");for(var s=0;s=this.settings.maxItems)){var e=$(t).appendTo(this.$tbody),i=e.find(".delete");this.settings.sortable&&this.sorter.addItems(e),this.$deleteBtns=this.$deleteBtns.add(i),this.addListener(i,"click","handleDeleteBtnClick"),this.totalItems++,this.updateUI()}},reorderItems:function(){var t=this;if(this.settings.sortable){for(var e=[],i=0;i=this.settings.maxItems?$(this.settings.newItemBtnSelector).addClass("hidden"):$(this.settings.newItemBtnSelector).removeClass("hidden"))}},{defaults:{tableSelector:null,noItemsSelector:null,newItemBtnSelector:null,idAttribute:"data-id",nameAttribute:"data-name",sortable:!1,allowDeleteAll:!0,minItems:0,maxItems:null,reorderAction:null,deleteAction:null,reorderSuccessMessage:Craft.t("app","New order saved."),reorderFailMessage:Craft.t("app","Couldn’t save new order."),confirmDeleteMessage:Craft.t("app","Are you sure you want to delete “{name}”?"),deleteSuccessMessage:Craft.t("app","“{name}” deleted."),deleteFailMessage:Craft.t("app","Couldn’t delete “{name}”."),onReorderItems:$.noop,onDeleteItem:$.noop}})},6872:function(){Craft.AssetImageEditor=Garnish.Modal.extend({$body:null,$footer:null,$imageTools:null,$buttons:null,$cancelBtn:null,$replaceBtn:null,$saveBtn:null,$editorContainer:null,$straighten:null,$croppingCanvas:null,$spinner:null,canvas:null,image:null,viewport:null,focalPoint:null,grid:null,croppingCanvas:null,clipper:null,croppingRectangle:null,cropperHandles:null,cropperGrid:null,croppingShade:null,croppingAreaText:null,imageStraightenAngle:0,viewportRotation:0,originalWidth:0,originalHeight:0,imageVerticeCoords:null,zoomRatio:1,animationInProgress:!1,currentView:"",assetId:null,cacheBust:null,draggingCropper:!1,scalingCropper:!1,draggingFocal:!1,previousMouseX:0,previousMouseY:0,shiftKeyHeld:!1,editorHeight:0,editorWidth:0,cropperState:!1,scaleFactor:1,flipData:{},focalPointState:!1,maxImageSize:null,lastLoadedDimensions:null,imageIsLoading:!1,mouseMoveEvent:null,croppingConstraint:!1,constraintOrientation:"landscape",showingCustomConstraint:!1,saving:!1,renderImage:null,renderCropper:null,init:function(t,e){var i=this;this.cacheBust=Date.now(),this.setSettings(e,Craft.AssetImageEditor.defaults),null===this.settings.allowDegreeFractions&&(this.settings.allowDegreeFractions=Craft.isImagick),this.assetId=t,this.flipData={x:0,y:0},this.$container=$('').appendTo(Garnish.$bod),this.$body=$('
').appendTo(this.$container),this.$footer=$('