diff --git a/resources/js/bootstrap/components.js b/resources/js/bootstrap/components.js index 626ef0d368..091fb442b5 100644 --- a/resources/js/bootstrap/components.js +++ b/resources/js/bootstrap/components.js @@ -57,6 +57,7 @@ import Modal from '../components/Modal.vue'; import ConfirmationModal from '../components/modals/ConfirmationModal.vue'; import FavoriteCreator from '../components/FavoriteCreator.vue'; import KeyboardShortcutsModal from '../components/modals/KeyboardShortcutsModal.vue'; +import FieldActionModal from '../components/field-actions/FieldActionModal.vue'; import ResourceDeleter from '../components/ResourceDeleter.vue'; import Stack from '../components/stacks/Stack.vue'; import StackTest from '../components/stacks/StackTest.vue'; @@ -142,6 +143,7 @@ Vue.component('confirmation-modal', ConfirmationModal); Vue.component('favorite-creator', FavoriteCreator); Vue.component('keyboard-shortcuts-modal', KeyboardShortcutsModal); Vue.component('resource-deleter', ResourceDeleter); +Vue.component('field-action-modal', FieldActionModal); Vue.component('stack', Stack); Vue.component('stack-test', StackTest); diff --git a/resources/js/components/field-actions/FieldAction.js b/resources/js/components/field-actions/FieldAction.js index fce724c9ac..e0578a335f 100644 --- a/resources/js/components/field-actions/FieldAction.js +++ b/resources/js/components/field-actions/FieldAction.js @@ -26,7 +26,7 @@ export default class FieldAction { return typeof this.#icon === 'function' ? this.#icon(this.#payload) : this.#icon; } - run() { + async run() { this.#run(this.#payload); } } diff --git a/resources/js/components/field-actions/FieldActionModal.vue b/resources/js/components/field-actions/FieldActionModal.vue new file mode 100644 index 0000000000..658da8092a --- /dev/null +++ b/resources/js/components/field-actions/FieldActionModal.vue @@ -0,0 +1,160 @@ + + + diff --git a/resources/js/components/field-actions/FieldActions.js b/resources/js/components/field-actions/FieldActions.js index 1e3b27fbff..68c6d1e8bb 100644 --- a/resources/js/components/field-actions/FieldActions.js +++ b/resources/js/components/field-actions/FieldActions.js @@ -16,6 +16,31 @@ class FieldActions { get(name) { return this.actions[name] || []; } + + modal(props) { + const name = props.fields ? 'field-action-modal' : 'confirmation-modal'; + return new Promise((resolve) => { + const component = Statamic.$components.append(name, { props }); + component.on('confirm', (data = {}) => { + if (props.keepOpen) { + resolve({ + ...data, + confirmed: true, + close: () => Statamic.$components.destroy(component.id), + }); + } else { + resolve(data); + Statamic.$components.destroy(component.id); + } + }); + component.on('cancel', () => { + resolve({ + confirmed: false, + }); + Statamic.$components.destroy(component.id); + }); + }); + } } export default FieldActions; diff --git a/routes/cp.php b/routes/cp.php index 19f8743826..34dac73184 100644 --- a/routes/cp.php +++ b/routes/cp.php @@ -42,6 +42,7 @@ use Statamic\Http\Controllers\CP\CpController; use Statamic\Http\Controllers\CP\DashboardController; use Statamic\Http\Controllers\CP\DuplicatesController; +use Statamic\Http\Controllers\CP\FieldActionModalController; use Statamic\Http\Controllers\CP\Fields\BlueprintController; use Statamic\Http\Controllers\CP\Fields\FieldsController; use Statamic\Http\Controllers\CP\Fields\FieldsetController; @@ -319,6 +320,11 @@ Route::get('dictionaries/{dictionary}', DictionaryFieldtypeController::class)->name('dictionary-fieldtype'); }); + Route::group(['prefix' => 'field-action-modal'], function () { + Route::post('resolve', [FieldActionModalController::class, 'resolve'])->name('resolve'); + Route::post('process', [FieldActionModalController::class, 'process'])->name('process'); + }); + Route::group(['prefix' => 'api', 'as' => 'api.'], function () { Route::resource('addons', AddonsApiController::class)->only('index'); Route::resource('templates', TemplatesController::class)->only('index'); diff --git a/src/Http/Controllers/CP/FieldActionModalController.php b/src/Http/Controllers/CP/FieldActionModalController.php new file mode 100644 index 0000000000..4e5cd97188 --- /dev/null +++ b/src/Http/Controllers/CP/FieldActionModalController.php @@ -0,0 +1,48 @@ +getFields($request->fields) + ->preProcess(); + + return [ + 'fieldset' => $fields->toPublishArray(), + 'values' => $fields->values(), + 'meta' => $fields->meta(), + ]; + } + + public function process(Request $request) + { + $fields = $this->getFields($request->fields) + ->addValues($request->values); + + $fields->validate(); + + $raw = $fields->process()->values(); + + $fields->preProcess(); + + return [ + 'values' => $fields->values(), + 'meta' => $fields->meta(), + 'raw' => $raw, + ]; + } + + protected function getFields($fieldItems) + { + $fields = collect($fieldItems)->map(function ($field, $handle) { + return compact('handle', 'field'); + }); + + return new Fields($fields); + } +}