From 8bbd9829238c2d41b8c129ef2aa39b30b875e82e Mon Sep 17 00:00:00 2001 From: Brian Hanson Date: Wed, 20 May 2026 10:39:13 -0500 Subject: [PATCH 1/2] Refactor Json wrapping --- src/Cp/JsonResource.php | 11 +++++++++++ src/Entry/Resources/EntryTypeResource.php | 2 +- src/Filesystem/Resources/FsResource.php | 2 +- src/Gql/Resources/GqlTokenResource.php | 2 +- src/Http/Resources/ElementIndexResource.php | 2 +- src/Providers/AppServiceProvider.php | 2 -- src/Section/Resources/SectionResource.php | 2 +- 7 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 src/Cp/JsonResource.php diff --git a/src/Cp/JsonResource.php b/src/Cp/JsonResource.php new file mode 100644 index 00000000000..40483a9d3e1 --- /dev/null +++ b/src/Cp/JsonResource.php @@ -0,0 +1,11 @@ + Date: Wed, 20 May 2026 12:37:48 -0500 Subject: [PATCH 2/2] [WIP] convert filesystem to Inertia --- resources/js/bootstrap/cp.ts | 4 + .../Filesystems/FilesystemSettings.vue | 73 ++++++++++ .../Filesystems/LocalFsSettings.vue | 18 +++ .../js/pages/SettingsFilesystemsEditPage.vue | 130 ++++++++++++++++++ .../_components/fs/Local/settings.twig | 32 +++-- src/Filesystem/Filesystems/Local.php | 14 +- .../Settings/FilesystemsController.php | 26 +++- 7 files changed, 278 insertions(+), 19 deletions(-) create mode 100644 resources/js/components/Filesystems/FilesystemSettings.vue create mode 100644 resources/js/components/Filesystems/LocalFsSettings.vue create mode 100644 resources/js/pages/SettingsFilesystemsEditPage.vue diff --git a/resources/js/bootstrap/cp.ts b/resources/js/bootstrap/cp.ts index cd2808a7db9..3d8105c7409 100644 --- a/resources/js/bootstrap/cp.ts +++ b/resources/js/bootstrap/cp.ts @@ -15,6 +15,7 @@ import AssetIndexes from '@/components/utilities/AssetIndexes/AssetIndexes.vue'; import SystemMessages from '@/components/utilities/SystemMessages/SystemMessages.vue'; import DeprecationErrorsToolbar from '@/components/utilities/DeprecationErrors/DeprecationErrorsToolbar.vue'; import {setTranslations} from '@craftcms/cp/utilities/translate.ts.mjs'; +import LocalFsSettings from '@/components/Filesystems/LocalFsSettings.vue'; let bootedCallbacks: Array<(instance: any) => void> = []; let bootingCallbacks: Array<(instance: any) => void> = []; @@ -98,6 +99,9 @@ const Cp = { app.component('ProjectConfig', ProjectConfig); app.component('AssetIndexes', AssetIndexes); app.component('SystemMessages', SystemMessages); + app.component('LocalFsSettings', LocalFsSettings); + + // @TODO Register plugin components }, }); diff --git a/resources/js/components/Filesystems/FilesystemSettings.vue b/resources/js/components/Filesystems/FilesystemSettings.vue new file mode 100644 index 00000000000..86349c08cf2 --- /dev/null +++ b/resources/js/components/Filesystems/FilesystemSettings.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/resources/js/components/Filesystems/LocalFsSettings.vue b/resources/js/components/Filesystems/LocalFsSettings.vue new file mode 100644 index 00000000000..c30f94d82f9 --- /dev/null +++ b/resources/js/components/Filesystems/LocalFsSettings.vue @@ -0,0 +1,18 @@ + + + + + diff --git a/resources/js/pages/SettingsFilesystemsEditPage.vue b/resources/js/pages/SettingsFilesystemsEditPage.vue new file mode 100644 index 00000000000..f0fca56f7fd --- /dev/null +++ b/resources/js/pages/SettingsFilesystemsEditPage.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/resources/templates/_components/fs/Local/settings.twig b/resources/templates/_components/fs/Local/settings.twig index e790bc638ee..587bce0cfbd 100644 --- a/resources/templates/_components/fs/Local/settings.twig +++ b/resources/templates/_components/fs/Local/settings.twig @@ -1,17 +1,23 @@ {% from "_includes/forms" import autosuggestField %} + + {{ autosuggestField({ - label: "Base Path"|t('app'), - instructions: "The base folder path that should be used as the root of the filesystem."|t('app'), - id: 'path', - class: 'ltr', - name: 'path', - suggestEnvVars: true, - suggestAliases: true, - value: filesystem.path, - required: true, - placeholder: "/path/to/folder"|t('app'), - errors: filesystem.errors.get('path'), - data: {'error-key': 'path'}, - disabled: readOnly, + label: "Base Path"|t('app'), + instructions: "The base folder path that should be used as the root of the filesystem."|t('app'), + id: 'path', + class: 'ltr', + name: 'path', + suggestEnvVars: true, + suggestAliases: true, + value: filesystem.path, + required: true, + placeholder: "/path/to/folder"|t('app'), + errors: filesystem.errors.get('path'), + data: {'error-key': 'path'}, + disabled: readOnly, }) }} diff --git a/src/Filesystem/Filesystems/Local.php b/src/Filesystem/Filesystems/Local.php index f1d71e84fdb..4a43059de40 100644 --- a/src/Filesystem/Filesystems/Local.php +++ b/src/Filesystem/Filesystems/Local.php @@ -9,6 +9,7 @@ use CraftCms\Cms\Support\Env; use CraftCms\Cms\Support\Facades\Security; use CraftCms\Cms\Support\File; +use CraftCms\Cms\Support\Html; use CraftCms\Cms\View\TemplateMode; use Override; @@ -124,10 +125,17 @@ public function getReadOnlySettingsHtml(): ?string private function settingsHtml(bool $readOnly): string { - return template('_components/fs/Local/settings', [ - 'filesystem' => $this, + return Html::tag('LocalFsSettings', attributes: [ + // ':filesystem' => json_encode([ + // 'name' => $this->name, + // 'handle' => $this->handle, + // ]), 'readOnly' => $readOnly, - ], TemplateMode::Cp); + ]); + // return template('_components/fs/Local/settings', [ + // 'filesystem' => $this, + // 'readOnly' => $readOnly, + // ], TemplateMode::Cp); } #[Override] diff --git a/src/Http/Controllers/Settings/FilesystemsController.php b/src/Http/Controllers/Settings/FilesystemsController.php index 5b9b65bf611..290d48403fc 100644 --- a/src/Http/Controllers/Settings/FilesystemsController.php +++ b/src/Http/Controllers/Settings/FilesystemsController.php @@ -6,6 +6,7 @@ use CraftCms\Cms\Config\GeneralConfig; use CraftCms\Cms\Cp\Html\ContentHtml; +use CraftCms\Cms\Cp\SelectOptions; use CraftCms\Cms\Filesystem\Contracts\FsInterface; use CraftCms\Cms\Filesystem\Filesystems; use CraftCms\Cms\Filesystem\Resources\FsResource; @@ -13,6 +14,7 @@ use CraftCms\Cms\Http\Responses\CpScreenResponse; use CraftCms\Cms\Support\Arr; use CraftCms\Cms\Support\Html; +use CraftCms\Cms\Support\Str; use CraftCms\Cms\Support\Url; use Illuminate\Http\Request; use Inertia\Inertia; @@ -93,18 +95,36 @@ public function edit(?string $handle = null): CpScreenResponse $title = t('Create a new filesystem'); } + $isValidUrl = fn ($value) => Str::isUrl($value); + return new CpScreenResponse() ->title($title) ->addCrumb(t('Settings'), 'settings') ->addCrumb(t('Filesystems'), 'settings/filesystems') - ->contentTemplate('settings/filesystems/_edit.twig', [ + ->inertiaPage('SettingsFilesystemsEditPage', [ 'oldHandle' => $handle, - 'filesystem' => $filesystem, + 'filesystem' => [ + ...$filesystem, + 'type' => $filesystem::class, + 'settingsHtml' => $this->readOnly ? $filesystem->getReadOnlySettingsHtml() : $filesystem->getSettingsHtml(), + 'showHasUrlSetting' => $filesystem->getShowHasUrlSetting(), + 'showUrlSetting' => $filesystem->getShowUrlSetting(), + ], 'fsOptions' => $fsOptions, 'fsInstances' => $fsInstances, 'fsTypes' => $allFsTypes, - 'readOnly' => $this->readOnly, + + // @TODO this should probably be its own item on SelectOptions + 'baseUrlSuggestions' => SelectOptions::getEnvSuggestions(true, $isValidUrl), ]) + // ->contentTemplate('settings/filesystems/_edit.twig', [ + // 'oldHandle' => $handle, + // 'filesystem' => $filesystem, + // 'fsOptions' => $fsOptions, + // 'fsInstances' => $fsInstances, + // 'fsTypes' => $allFsTypes, + // 'readOnly' => $this->readOnly, + // ]) ->unless( $this->readOnly, function (CpScreenResponse $response) {