From 335131106796c08af6626f933178150b7ad8431e Mon Sep 17 00:00:00 2001 From: el-schneider Date: Wed, 20 May 2026 10:29:35 +0200 Subject: [PATCH] [5.x] Avoid eager loading asset move folders --- .../fieldtypes/AssetFolderFieldtype.vue | 34 ++++++++- src/Actions/MoveAsset.php | 18 ++--- src/Actions/MoveAssetFolder.php | 18 ++--- tests/Actions/MoveAssetTest.php | 69 +++++++++++++++++++ 4 files changed, 108 insertions(+), 31 deletions(-) create mode 100644 tests/Actions/MoveAssetTest.php diff --git a/resources/js/components/fieldtypes/AssetFolderFieldtype.vue b/resources/js/components/fieldtypes/AssetFolderFieldtype.vue index 03c71b017ba..db043ad78c5 100644 --- a/resources/js/components/fieldtypes/AssetFolderFieldtype.vue +++ b/resources/js/components/fieldtypes/AssetFolderFieldtype.vue @@ -5,7 +5,7 @@ :handle="handle" :value="value" :meta="relationshipMeta" - :config="{ type: 'asset_folder', max_items: this.config.max_items }" + :config="relationshipConfig" @input="update" /> @@ -16,12 +16,40 @@ export default { mixins: [Fieldtype], - inject: ['storeName'], + inject: { + storeName: { + default: null + } + }, computed: { container() { - return data_get(this.$store.state.publish[this.storeName].values.container, '0', this.config.container); + let container = this.config.container; + + if (container) { + return Array.isArray(container) ? container[0] : container; + } + + if (! this.storeName) return null; + + const state = this.$store?.state?.publish?.[this.storeName]; + if (! state) return null; + + container = state.values.container; + + if (Array.isArray(container)) { + return container[0] || null; + } + + return container || null; + }, + + relationshipConfig() { + return { + ...this.config, + type: 'asset_folder', + }; }, relationshipMeta() { diff --git a/src/Actions/MoveAsset.php b/src/Actions/MoveAsset.php index 6da070a6445..10055860154 100644 --- a/src/Actions/MoveAsset.php +++ b/src/Actions/MoveAsset.php @@ -3,8 +3,6 @@ namespace Statamic\Actions; use Statamic\Contracts\Assets\Asset; -use Statamic\Facades\AssetContainer; -use Statamic\Facades\Blink; class MoveAsset extends Action { @@ -46,21 +44,13 @@ public function run($assets, $values) protected function fieldItems() { - $options = Blink::once('action-move-asset-folders', function () { - return AssetContainer::find($this->context['container']) - ->assetFolders() - ->mapWithKeys(function ($folder) { - return [$folder->path() => $folder->path()]; - }) - ->prepend('/', '/') - ->all(); - }); - return [ 'folder' => [ 'display' => __('Folder'), - 'type' => 'select', - 'options' => $options, + 'type' => 'asset_folder', + 'container' => $this->context['container'], + 'mode' => 'select', + 'max_items' => 1, 'validate' => 'required', ], ]; diff --git a/src/Actions/MoveAssetFolder.php b/src/Actions/MoveAssetFolder.php index 12a3fc11f2a..a43e0e1f9fd 100644 --- a/src/Actions/MoveAssetFolder.php +++ b/src/Actions/MoveAssetFolder.php @@ -3,8 +3,6 @@ namespace Statamic\Actions; use Statamic\Contracts\Assets\AssetFolder; -use Statamic\Facades\AssetContainer; -use Statamic\Facades\Blink; class MoveAssetFolder extends Action { @@ -42,21 +40,13 @@ public function run($folders, $values) protected function fieldItems() { - $options = Blink::once('action-move-asset-folders', function () { - return AssetContainer::find($this->context['container']) - ->assetFolders() - ->mapWithKeys(function ($folder) { - return [$folder->path() => $folder->path()]; - }) - ->prepend('/', '/') - ->all(); - }); - return [ 'folder' => [ 'display' => __('Folder'), - 'type' => 'select', - 'options' => $options, + 'type' => 'asset_folder', + 'container' => $this->context['container'], + 'mode' => 'select', + 'max_items' => 1, 'validate' => 'required', ], ]; diff --git a/tests/Actions/MoveAssetTest.php b/tests/Actions/MoveAssetTest.php new file mode 100644 index 00000000000..5fc55f051bb --- /dev/null +++ b/tests/Actions/MoveAssetTest.php @@ -0,0 +1,69 @@ +container = tap( + (new AssetContainer)->handle('test_container')->disk('test') + )->save(); + } + + #[Test] + #[DataProvider('moveActionsProvider')] + public function move_action_folder_field_lists_all_destination_folders($action) + { + $this->container + ->makeAsset('source/one.txt') + ->upload(UploadedFile::fake()->create('one.txt')); + $this->container + ->makeAsset('destination/two.txt') + ->upload(UploadedFile::fake()->create('two.txt')); + + $field = (new $action) + ->context(['container' => 'test_container']) + ->toArray()['fields'][0]; + + $folders = $this + ->actingAs(tap(User::make()->makeSuper())->save()) + ->getJson(cp_route('relationship.index').'?'.http_build_query([ + 'config' => base64_encode(json_encode($field)), + 'container' => 'test_container', + ])) + ->assertOk() + ->collect('data') + ->pluck('id') + ->all(); + + $this->assertEqualsCanonicalizing(['/', 'destination', 'source'], $folders); + } + + public static function moveActionsProvider() + { + return [ + 'asset' => [MoveAsset::class], + 'asset folder' => [MoveAssetFolder::class], + ]; + } +}