Skip to content

Commit

Permalink
Merge pull request #657 from getformwork/feature/new-modals-api
Browse files Browse the repository at this point in the history
New Modals API
  • Loading branch information
giuscris authored Mar 1, 2025
2 parents d9f0c1f + af6dc91 commit 72006f4
Show file tree
Hide file tree
Showing 29 changed files with 289 additions and 217 deletions.
13 changes: 4 additions & 9 deletions formwork/src/Panel/Controllers/AbstractController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
use Formwork\Cms\Site;
use Formwork\Controllers\AbstractController as BaseAbstractController;
use Formwork\Panel\Modals\Modal;
use Formwork\Panel\Modals\ModalCollection;
use Formwork\Panel\Modals\ModalFactory;
use Formwork\Panel\Modals\Modals;
use Formwork\Panel\Panel;
use Formwork\Parsers\Json;
use Formwork\Router\Router;
Expand All @@ -18,20 +17,16 @@

abstract class AbstractController extends BaseAbstractController
{
protected ModalCollection $modals;

public function __construct(
private Container $container,
protected readonly Router $router,
protected readonly CsrfToken $csrfToken,
protected readonly Translations $translations,
protected readonly ModalFactory $modalFactory,
protected readonly Modals $modals,
protected readonly Site $site,
protected readonly Panel $panel,
) {
$this->container->call(parent::__construct(...));

$this->modals = new ModalCollection();
}

/**
Expand Down Expand Up @@ -65,8 +60,8 @@ protected function hasPermission(string $permission): bool
*/
protected function modal(string $name): Modal
{
$this->modals->add($modal = $this->modalFactory->make($name));
return $modal;
$this->modals->add($name);
return $this->modals->get($name);
}

/**
Expand Down
4 changes: 0 additions & 4 deletions formwork/src/Panel/Controllers/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ public function index(Statistics $statistics): Response
return $this->forward(ErrorsController::class, 'forbidden');
}

$this->modal('newPage');

$this->modal('deletePage');

return new Response($this->view('dashboard.index', [
'title' => $this->translate('panel.dashboard.dashboard'),
'lastModifiedPages' => $this->view('pages.tree', [
Expand Down
4 changes: 0 additions & 4 deletions formwork/src/Panel/Controllers/OptionsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@ public function systemOptions(Schemes $schemes): Response

$fields->setValues($this->config->get('system'));

$this->modal('changes');

return new Response($this->view('options.system', [
'title' => $this->translate('panel.options.options'),
'tabs' => $this->view('options.tabs', [
Expand Down Expand Up @@ -111,8 +109,6 @@ public function siteOptions(Schemes $schemes): Response

$fields->setValues($this->site->data());

$this->modal('changes');

return new Response($this->view('options.site', [
'title' => $this->translate('panel.options.options'),
'tabs' => $this->view('options.tabs', [
Expand Down
20 changes: 1 addition & 19 deletions formwork/src/Panel/Controllers/PagesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ public function index(): Response
return $this->forward(ErrorsController::class, 'forbidden');
}

$this->modal('newPage');

$this->modal('deletePage');

$pages = $this->site->pages();

$indexOffset = $pages->indexOf($this->site->indexPage());
Expand Down Expand Up @@ -194,17 +190,7 @@ public function edit(RouteParams $routeParams): Response
return $this->redirect($this->generateRoute('panel.pages.edit', ['page' => $page->route()]));
}

$this->modal('images');

$this->modal('link');

$this->modal('changes');

$this->modal('deletePage');

$this->modal('deleteFile');

$this->modal('renameFile');
$this->modal('images')->setFieldsModel($page);

$contentHistory = $page->contentPath()
? new ContentHistory($page->contentPath())
Expand Down Expand Up @@ -552,10 +538,6 @@ public function file(RouteParams $routeParams): Response
return $this->redirect($this->generateRoute('panel.pages.file', ['page' => $page->route(), 'filename' => $filename]));
}

$this->modal('renameFile');
$this->modal('deleteFile');
$this->modal('changes');

return new Response($this->view('pages.file', [
'title' => $file->name(),
'page' => $page,
Expand Down
2 changes: 0 additions & 2 deletions formwork/src/Panel/Controllers/ToolsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ public function backups(): Response
'size' => FileSystem::formatSize(FileSystem::size($path)),
]);

$this->modal('deleteFile');

return new Response($this->view('tools.backups', [
'title' => $this->translate('panel.tools.backups'),
'tabs' => $this->view('tools.tabs', [
Expand Down
10 changes: 0 additions & 10 deletions formwork/src/Panel/Controllers/UsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ public function index(): Response
return $this->forward(ErrorsController::class, 'forbidden');
}

$this->modal('newUser');

$this->modal('deleteUser');

return new Response($this->view('users.index', [
'title' => $this->translate('panel.users.users'),
'users' => $this->site->users()->sortBy('username'),
Expand Down Expand Up @@ -198,12 +194,6 @@ public function profile(RouteParams $routeParams): Response

$fields = $fields->setValues($user);

$this->modal('changes');

$this->modal('deleteUser');

$this->modal('deleteUserImage');

return new Response($this->view('users.profile', [
'title' => $this->translate('panel.users.userProfile', $user->username()),
'user' => $user,
Expand Down
18 changes: 18 additions & 0 deletions formwork/src/Panel/Modals/Modal.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Formwork\Data\Traits\DataArrayable;
use Formwork\Fields\FieldCollection;
use Formwork\Fields\FieldFactory;
use Formwork\Model\Model;
use Formwork\Translations\Translation;
use Formwork\Utils\Arr;
use Formwork\Utils\Str;
Expand All @@ -20,6 +21,11 @@ class Modal implements Arrayable
*/
protected string $id;

/**
* Fields model
*/
protected Model $fieldsModel;

/**
* Modal buttons
*/
Expand Down Expand Up @@ -96,9 +102,21 @@ public function fields(): FieldCollection
// @phpstan-ignore argument.templateType
$fieldCollection->setMultiple(Arr::map($this->data['fields'] ?? [], fn($data, $name) => $this->fieldFactory->make($this->id . '.' . $name, $data, $fieldCollection)));

if (isset($this->fieldsModel)) {
$fieldCollection->setModel($this->fieldsModel);
}

return $fieldCollection;
}

/**
* Set fields model
*/
public function setFieldsModel(Model $model): void
{
$this->fieldsModel = $model;
}

/**
* Get modal buttons
*/
Expand Down
2 changes: 2 additions & 0 deletions formwork/src/Panel/Modals/ModalCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

class ModalCollection extends AbstractCollection
{
protected bool $associative = true;

protected ?string $dataType = Modal::class;

protected bool $mutable = true;
Expand Down
22 changes: 22 additions & 0 deletions formwork/src/Panel/Modals/Modals.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Formwork\Panel\Modals;

class Modals extends ModalCollection
{
public function __construct(
private ModalFactory $modalFactory
) {}

/**
* Add a modal by name. If the modal is already present, it won't be added again
*
* @param string $name
*/
public function add(mixed $name): void
{
if (!$this->has($name)) {
$this->set($name, $this->modalFactory->make($name));
}
}
}
2 changes: 2 additions & 0 deletions formwork/src/Services/Loaders/PanelServiceLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Formwork\Log\Registry;
use Formwork\Panel\Controllers\ErrorsController;
use Formwork\Panel\Modals\ModalFactory;
use Formwork\Panel\Modals\Modals;
use Formwork\Panel\Panel;
use Formwork\Panel\Security\AccessLimiter;
use Formwork\Schemes\Schemes;
Expand Down Expand Up @@ -41,6 +42,7 @@ public function load(Container $container): Panel
$this->request->session()->setDuration($this->config->get('system.panel.sessionTimeout') * 60);

$container->define(ModalFactory::class);
$container->define(Modals::class);

return $container->build(Panel::class);
}
Expand Down
2 changes: 1 addition & 1 deletion panel/src/scss/components/_modals.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
outline: 0;
}

.modal.show {
.modal.open {
display: flex;
}

Expand Down
40 changes: 19 additions & 21 deletions panel/src/ts/components/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,15 @@ export class Form {
element.addEventListener("click", (event) => {
if (this.hasChanged()) {
event.preventDefault();
app.modals["changesModal"].show(undefined, (modal) => {

app.modals["changesModal"].onOpen((modal) => {
const continueCommand = $("[data-command=continue]", modal.element);
if (continueCommand) {
continueCommand.dataset.href = element.href;
}
});

app.modals["changesModal"].open();
}
});
});
Expand All @@ -60,34 +63,29 @@ export class Form {
registerModalExceptions();

function registerModalExceptions() {
const changesModal = document.getElementById("changesModal");
const deletePageModal = document.getElementById("deletePageModal");
const deleteUserModal = document.getElementById("deleteUserModal");
const changesModal = app.modals["changesModal"];
const deletePageModal = app.modals["deletePageModal"];
const deleteUserModal = app.modals["deleteUserModal"];

if (changesModal) {
const continueCommand = $("[data-command=continue]", changesModal);
if (continueCommand) {
continueCommand.addEventListener("click", function () {
removeBeforeUnload();
if (this.dataset.href) {
window.location.href = this.dataset.href;
}
});
}
changesModal.onCommand("continue", (_, button) => {
removeBeforeUnload();
if (button?.dataset.href) {
window.location.href = button.dataset.href;
}
});
}

if (deletePageModal) {
const deleteCommand = $("[data-command=delete]", deletePageModal);
if (deleteCommand) {
deleteCommand.addEventListener("click", removeBeforeUnload);
}
deletePageModal.onCommand("delete", () => {
removeBeforeUnload();
});
}

if (deleteUserModal) {
const deleteCommand = $("[data-command=delete]", deleteUserModal);
if (deleteCommand) {
deleteCommand.addEventListener("click", removeBeforeUnload);
}
deleteUserModal.onCommand("delete", () => {
removeBeforeUnload();
});
}
}
}
Expand Down
Loading

0 comments on commit 72006f4

Please sign in to comment.