Skip to content

Commit

Permalink
Merge pull request #63 from systopia/add-vertical-tabs
Browse files Browse the repository at this point in the history
Add support for vertical tabs in remote forms
  • Loading branch information
dontub authored Dec 2, 2024
2 parents ad24066 + 5602b13 commit 0429965
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 5 deletions.
16 changes: 11 additions & 5 deletions Civi/RemoteTools/Form/FormSpec/AbstractFormElementContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,21 @@
use Civi\RemoteTools\Form\FormSpec\Button\SubmitButton;

/**
* @template T of FormElementInterface
*
* @api
*/
abstract class AbstractFormElementContainer {

private string $title;

/**
* @phpstan-var array<FormElementInterface>
* @phpstan-var array<T>
*/
private array $elements = [];

/**
* @phpstan-param array<FormElementInterface> $elements
* @phpstan-param array<T> $elements
*/
public function __construct(string $title, array $elements = []) {
$this->title = $title;
Expand All @@ -55,6 +57,8 @@ public function setTitle(string $title): self {
}

/**
* @phpstan-param T $element
*
* @return $this
*/
public function addElement(FormElementInterface $element): self {
Expand All @@ -64,7 +68,7 @@ public function addElement(FormElementInterface $element): self {
}

/**
* @phpstan-return array<FormElementInterface>
* @phpstan-return array<T>
*/
public function getElements(): array {
return $this->elements;
Expand All @@ -75,6 +79,8 @@ public function hasElements(): bool {
}

/**
* @phpstan-param T $element
*
* @return $this
*/
public function insertElement(FormElementInterface $element, int $index): self {
Expand All @@ -84,7 +90,7 @@ public function insertElement(FormElementInterface $element, int $index): self {
}

/**
* @phpstan-param array<FormElementInterface> $elements
* @phpstan-param array<T> $elements
*/
public function setElements(array $elements): self {
$this->elements = $elements;
Expand All @@ -102,7 +108,7 @@ public function getFields(): array {
if ($element instanceof AbstractFormField) {
$fields[$element->getName()] = $element;
}
elseif ($element instanceof FormElementContainer) {
elseif ($element instanceof AbstractFormElementContainer) {
$containerFields = $element->getFields();
$nonUniqueFields = array_keys(array_intersect_key($fields, $containerFields));
if ([] !== $nonUniqueFields) {
Expand Down
2 changes: 2 additions & 0 deletions Civi/RemoteTools/Form/FormSpec/FormElementContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
/**
* @codeCoverageIgnore
*
* @extends AbstractFormElementContainer<FormElementInterface>
*
* @api
*/
class FormElementContainer extends AbstractFormElementContainer implements FormElementInterface {
Expand Down
2 changes: 2 additions & 0 deletions Civi/RemoteTools/Form/FormSpec/FormSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
namespace Civi\RemoteTools\Form\FormSpec;

/**
* @extends AbstractFormElementContainer<FormElementInterface>
*
* @api
*/
final class FormSpec extends AbstractFormElementContainer {
Expand Down
50 changes: 50 additions & 0 deletions Civi/RemoteTools/Form/FormSpec/FormTab.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
/*
* Copyright (C) 2024 SYSTOPIA GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

declare(strict_types = 1);

namespace Civi\RemoteTools\Form\FormSpec;

/**
* @codeCoverageIgnore
*
* @api
*/
class FormTab extends AbstractFormElementContainer implements FormElementInterface {

public ?string $description;

public function __construct(string $title, array $elements = [], ?string $description = NULL) {
parent::__construct($title, $elements);
$this->description = $description;
}

public function getType(): string {
return 'tab';
}

public function getDescription(): ?string {
return $this->description;
}

public function setDescription(?string $description): self {
$this->description = $description;

return $this;
}

}
39 changes: 39 additions & 0 deletions Civi/RemoteTools/Form/FormSpec/VerticalTabsContainer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
/*
* Copyright (C) 2024 SYSTOPIA GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

declare(strict_types = 1);

namespace Civi\RemoteTools\Form\FormSpec;

/**
* @codeCoverageIgnore
*
* @extends AbstractFormElementContainer<FormTab>
*
* @api
*/
class VerticalTabsContainer extends AbstractFormElementContainer implements FormElementInterface {

public function __construct(array $elements = []) {
parent::__construct('', $elements);
}

public function getType(): string {
return 'vertical_tabs';
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
/*
* Copyright (C) 2024 SYSTOPIA GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

declare(strict_types = 1);

namespace Civi\RemoteTools\JsonForms\FormSpec\Factory\Layout;

use Civi\RemoteTools\Form\FormSpec\FormElementInterface;
use Civi\RemoteTools\Form\FormSpec\VerticalTabsContainer;
use Civi\RemoteTools\JsonForms\FormSpec\ElementUiSchemaFactoryInterface;
use Civi\RemoteTools\JsonForms\FormSpec\Factory\AbstractConcreteElementUiSchemaFactory;
use Civi\RemoteTools\JsonForms\JsonFormsElement;
use Civi\RemoteTools\JsonForms\Layout\JsonFormsCategorization;
use Webmozart\Assert\Assert;

final class CategorizationFactory extends AbstractConcreteElementUiSchemaFactory {

public function createSchema(
FormElementInterface $element,
ElementUiSchemaFactoryInterface $factory
): JsonFormsElement {
Assert::isInstanceOf($element, VerticalTabsContainer::class);
/** @var \Civi\RemoteTools\Form\FormSpec\VerticalTabsContainer $element */
$elements = array_map([$factory, 'createSchema'], $element->getElements());

return new JsonFormsCategorization($elements);
}

public function supportsElement(FormElementInterface $element): bool {
return $element instanceof VerticalTabsContainer;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
/*
* Copyright (C) 2024 SYSTOPIA GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

declare(strict_types = 1);

namespace Civi\RemoteTools\JsonForms\FormSpec\Factory\Layout;

use Civi\RemoteTools\Form\FormSpec\FormElementInterface;
use Civi\RemoteTools\Form\FormSpec\FormTab;
use Civi\RemoteTools\JsonForms\FormSpec\ElementUiSchemaFactoryInterface;
use Civi\RemoteTools\JsonForms\FormSpec\Factory\AbstractConcreteElementUiSchemaFactory;
use Civi\RemoteTools\JsonForms\JsonFormsElement;
use Civi\RemoteTools\JsonForms\Layout\JsonFormsCategory;
use Webmozart\Assert\Assert;

final class CategoryFactory extends AbstractConcreteElementUiSchemaFactory {

public function createSchema(
FormElementInterface $element,
ElementUiSchemaFactoryInterface $factory
): JsonFormsElement {
Assert::isInstanceOf($element, FormTab::class);
/** @var \Civi\RemoteTools\Form\FormSpec\FormTab $element */
$elements = array_map([$factory, 'createSchema'], $element->getElements());

return new JsonFormsCategory($element->getTitle(), $elements, $element->getDescription());
}

public function supportsElement(FormElementInterface $element): bool {
return $element instanceof FormTab;
}

}

0 comments on commit 0429965

Please sign in to comment.