Skip to content

Commit

Permalink
chore: add widget fields & form elements (#123)
Browse files Browse the repository at this point in the history
  • Loading branch information
matthv authored Oct 4, 2024
1 parent 0985dcc commit 029dd7f
Show file tree
Hide file tree
Showing 31 changed files with 904 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions;

class BaseFormElement
{
public function __construct(
protected string $type,
array $extraArguments = [] // workaround like kwargs in other languages
) {
foreach ($extraArguments as $key => $value) {
$this->$key = $value;
}
}

public function isStatic(): bool
{
foreach ($this->keys() as $attribute) {
if (is_callable($this->$attribute)) {
return false;
}
}

return true;
}

public function toArray(): array
{
$result = [];
foreach ($this->keys() as $attribute) {
$result[$attribute] = $this->$attribute;
}

return $result;
}

public function keys(): array
{
return array_keys(get_object_vars($this));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

namespace ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions;

class DynamicField
class DynamicField extends BaseFormElement
{
public function __construct(
// TODO
// protected string $id,
protected string $type,
protected string $label,
protected ?string $description = null,
Expand All @@ -15,7 +17,18 @@ public function __construct(
protected \Closure|string|null $defaultValue = null,
protected \Closure|string|null $collectionName = null,
protected \Closure|array|null $enumValues = null,
// TODO
// protected ?string $placeholder = null,
array $extraArguments = [] // workaround like kwargs in other languages
) {
parent::__construct($type);
// TODO
// $this->id = $id ?? $label;
// $this->label = $label ?? $id;

foreach ($extraArguments as $argumentKey => $argumentValue) {
$this->$argumentKey = $argumentValue;
}
}

public function __set($key, $value)
Expand Down Expand Up @@ -193,6 +206,16 @@ public function setEnumValues(array|\Closure|null $enumValues): void
$this->enumValues = $enumValues;
}

public function getPlaceholder(): ?string
{
return $this->placeholder;
}

public function setPlaceholder(?string $placeholder): void
{
$this->placeholder = $placeholder;
}

public function isStatic(): bool
{
foreach ($this as $field => $value) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\FormLayoutElement;

use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\BaseFormElement;

class HtmlBlockElement extends BaseFormElement
{
public function __construct(
protected string $content,
array $extraArguments = []
) {
parent::__construct('HtmlBlock', $extraArguments);
}

public function getContent(): string
{
return $this->content;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\FormLayoutElement;

use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\BaseFormElement;

class LayoutElement extends BaseFormElement
{
public function __construct(
protected string $component,
protected ?string $ifCondition = null,
array $extraArguments = []
) {
parent::__construct('Layout', $extraArguments);
}

public function getComponent(): string
{
return $this->component;
}

public function getIfCondition(): ?string
{
return $this->ifCondition;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\FormLayoutElement;

use ForestAdmin\AgentPHP\DatasourceToolkit\Exceptions\ForestException;

class PageElement extends LayoutElement
{
protected array $elements;
protected ?string $nextButtonLabel;
protected ?string $previousButtonLabel;

public function __construct(
array $elements,
?string $nextButtonLabel = null,
?string $previousButtonLabel = null,
array $extraArguments = []
) {
parent::__construct('Page', $extraArguments);

$this->validateElementsPresence($elements);
$this->validateNoPageElements($elements);

$this->elements = $this->instantiateElements($elements);
$this->nextButtonLabel = $nextButtonLabel;
$this->previousButtonLabel = $previousButtonLabel;
}

private function validateElementsPresence(array $elements): void
{
if (empty($elements)) {
throw new ForestException("Using 'elements' in a 'Page' configuration is mandatory");
}
}

private function validateNoPageElements(array $elements): void
{
foreach ($elements as $element) {
if (isset($element['component']) && $element['component'] === 'Page') {
throw new ForestException("'Page' component cannot be used within 'elements'");
}
}
}

private function instantiateElements(array $elements): array
{
// TODO
//return FormFactory::buildElements($elements);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\FormLayoutElement;

use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\BaseFormElement;
use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\DynamicField;
use ForestAdmin\AgentPHP\DatasourceToolkit\Exceptions\ForestException;

class RowElement extends BaseFormElement
{
public function __construct(
protected array $fields,
array $extraArguments = []
) {
parent::__construct('Row', $extraArguments);
$this->validateFieldsPresence($extraArguments);
$this->validateNoLayoutSubfields($extraArguments['fields'] ?? []);
$this->fields = $this->instantiateSubfields($extraArguments['fields'] ?? []);
}

private function validateFieldsPresence(array $options): void
{
if (! array_key_exists('fields', $options)) {
throw new ForestException("Using 'fields' in a 'Row' configuration is mandatory");
}
}

private function validateNoLayoutSubfields(array $fields): void
{
foreach ($fields as $field) {
if (($field instanceof DynamicField && $field->getType() === 'Layout') ||
(is_array($field) && ($field['type'] ?? '') === 'Layout')) {
throw new ForestException("A 'Row' form element doesn't allow layout elements as subfields");
}
}
}

private function instantiateSubfields(array $fields): array
{
return array_map(fn ($field) => new DynamicField(...$field), $fields);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\FormLayoutElement;

use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\BaseFormElement;

class SeparatorElement extends BaseFormElement
{
public function __construct(array $extraArguments = [])
{
parent::__construct('Separator', $extraArguments);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ final class FieldType
public const STRING = 'String';

public const STRING_LIST = 'StringList';

public const LAYOUT = 'Layout';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace ForestAdminDatasourceCustomizer\Decorators\Action\WidgetField;

use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\DynamicField;
use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\WidgetField\Widget;

class AddressAutocompleteField extends DynamicField
{
use Widget;

public function __construct($options)
{
parent::__construct($options['type'], $options['label']);
WidgetValidator::validateArg($options, 'type', ['type' => 'contains', 'value' => ['String']]);
$this->widget = 'AddressAutocomplete';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace ForestAdminDatasourceCustomizer\Decorators\Action\WidgetField;

use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\DynamicField;
use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\Types\FieldType;
use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\WidgetField\Widget;

class CheckboxField extends DynamicField
{
use Widget;

public function __construct($options)
{
parent::__construct($options['type'], $options['label']);
WidgetValidator::validateArg($options, 'type', ['type' => 'contains', 'value' => [FieldType::BOOLEAN]]);
$this->widget = 'Checkbox';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace ForestAdminDatasourceCustomizer\Decorators\Action\WidgetField;

use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\DynamicField;
use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\Types\FieldType;
use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\WidgetField\Widget;

class CheckboxGroupField extends DynamicField
{
use Widget;

private array $options;

public function __construct($options)
{
parent::__construct($options['type'], $options['label']);
WidgetValidator::validateArg($options, 'options', ['type' => 'present']);
WidgetValidator::validateArg($options, 'type', ['type' => 'contains', 'value' => [FieldType::STRING_LIST, FieldType::NUMBER_LIST]]);
$this->widget = 'CheckboxGroup';
$this->options = $options['options'];
}

public function getOptions(): array
{
return $this->options;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace ForestAdminDatasourceCustomizer\Decorators\Action\WidgetField;

use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\DynamicField;
use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\Types\FieldType;
use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Actions\WidgetField\Widget;

class ColorPickerField extends DynamicField
{
use Widget;

private ?bool $enableOpacity;

private ?array $quickPalette;

public function __construct($options)
{
parent::__construct($options['type'], $options['label']);
WidgetValidator::validateArg($options, 'enable_opacity', ['type' => 'contains', 'value' => [FieldType::STRING]]);
$this->widget = 'ColorPicker';
$this->enableOpacity = $options['enable_opacity'] ?? null;
$this->quickPalette = $options['quick_palette'] ?? null;
}

public function getEnableOpacity(): ?bool
{
return $this->enableOpacity;
}

public function getQuickPalette(): ?array
{
return $this->quickPalette;
}
}
Loading

0 comments on commit 029dd7f

Please sign in to comment.