From 372b5a95202a6e9c60f7b4e21a8769b12bdce3c3 Mon Sep 17 00:00:00 2001 From: Atirna <288419661+atirna@users.noreply.github.com> Date: Thu, 27 Aug 2026 00:07:03 +0530 Subject: [PATCH] [6.x] Keep crop copies in asset fields --- resources/js/components/assets/Editor/Editor.vue | 11 ++++++++++- resources/js/components/fieldtypes/assets/Asset.js | 5 +++++ .../js/components/fieldtypes/assets/AssetRow.vue | 2 ++ .../js/components/fieldtypes/assets/AssetTile.vue | 2 ++ resources/js/tests/components/assets/Editor.test.js | 13 +++++++++++++ 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/resources/js/components/assets/Editor/Editor.vue b/resources/js/components/assets/Editor/Editor.vue index a2b805b5120..cd1ae848060 100644 --- a/resources/js/components/assets/Editor/Editor.vue +++ b/resources/js/components/assets/Editor/Editor.vue @@ -214,7 +214,7 @@ import ItemActions from '@/components/actions/ItemActions.vue'; import useCheckerboard from '@/composables/checkerboard.js'; export default { - emits: ['previous', 'next', 'saved', 'closed', 'action-started', 'action-completed'], + emits: ['previous', 'next', 'saved', 'closed', 'created', 'action-started', 'action-completed'], components: { Button, @@ -249,6 +249,10 @@ export default { return true; }, }, + redirectAfterCrop: { + type: Boolean, + default: true, + }, }, data() { @@ -448,6 +452,11 @@ export default { }, handleCropCreated(newAssetId) { + if (!this.redirectAfterCrop) { + this.$emit('created', newAssetId); + return; + } + const [containerHandle, assetPath] = newAssetId.split('::'); const editUrl = cp_url(`assets/browse/${containerHandle}/${assetPath}/edit`); router.get(editUrl); diff --git a/resources/js/components/fieldtypes/assets/Asset.js b/resources/js/components/fieldtypes/assets/Asset.js index a505a628dd9..b910984c7f2 100644 --- a/resources/js/components/fieldtypes/assets/Asset.js +++ b/resources/js/components/fieldtypes/assets/Asset.js @@ -112,6 +112,11 @@ export default { this.closeEditor(); }, + assetCreated(assetId) { + this.$emit('id-changed', this.editingId, assetId); + this.closeEditor(); + }, + actionCompleted(successful, response) { if (successful === false) return; const id = response.ids[0] || null; diff --git a/resources/js/components/fieldtypes/assets/AssetRow.vue b/resources/js/components/fieldtypes/assets/AssetRow.vue index 3f9fef16e0d..7625488a36c 100644 --- a/resources/js/components/fieldtypes/assets/AssetRow.vue +++ b/resources/js/components/fieldtypes/assets/AssetRow.vue @@ -61,10 +61,12 @@ :id="editingId" :allow-deleting="false" :show-navigation="siblings.length > 1" + :redirect-after-crop="false" @previous="navigateToPrevious" @next="navigateToNext" @closed="closeEditor" @saved="assetSaved" + @created="assetCreated" @action-completed="actionCompleted" > diff --git a/resources/js/components/fieldtypes/assets/AssetTile.vue b/resources/js/components/fieldtypes/assets/AssetTile.vue index bfab7cdd54d..5a256e931e3 100644 --- a/resources/js/components/fieldtypes/assets/AssetTile.vue +++ b/resources/js/components/fieldtypes/assets/AssetTile.vue @@ -13,10 +13,12 @@ :id="editingId" :allow-deleting="false" :show-navigation="siblings.length > 1" + :redirect-after-crop="false" @previous="navigateToPrevious" @next="navigateToNext" @closed="closeEditor" @saved="assetSaved" + @created="assetCreated" @action-completed="actionCompleted" > diff --git a/resources/js/tests/components/assets/Editor.test.js b/resources/js/tests/components/assets/Editor.test.js index faa8c48f928..1055b5eaec7 100644 --- a/resources/js/tests/components/assets/Editor.test.js +++ b/resources/js/tests/components/assets/Editor.test.js @@ -1,5 +1,6 @@ import { expect, test, vi } from 'vitest'; import Editor from '@/components/assets/Editor/Editor.vue'; +import Asset from '@/components/fieldtypes/assets/Asset'; function keydown(key, target, modifier) { const component = { @@ -46,3 +47,15 @@ test.each([['ctrlKey'], ['metaKey']])( expect(keydown('ArrowRight', target, modifier).navigateToNextAsset).not.toHaveBeenCalled(); }, ); + +test('keeps crop copies in the asset field', () => { + const editor = { redirectAfterCrop: false, $emit: vi.fn() }; + const asset = { editingId: 'assets::source.png', $emit: vi.fn(), closeEditor: vi.fn() }; + + Editor.methods.handleCropCreated.call(editor, 'assets::crop.png'); + Asset.methods.assetCreated.call(asset, 'assets::crop.png'); + + expect(editor.$emit).toHaveBeenCalledWith('created', 'assets::crop.png'); + expect(asset.$emit).toHaveBeenCalledWith('id-changed', 'assets::source.png', 'assets::crop.png'); + expect(asset.closeEditor).toHaveBeenCalled(); +});