Skip to content

Commit

Permalink
feat: indent and dedent action
Browse files Browse the repository at this point in the history
  • Loading branch information
saade committed Feb 14, 2024
1 parent 5932e2d commit 1c49c31
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 5 deletions.
8 changes: 8 additions & 0 deletions resources/lang/en/adjacency-list.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@
'reorder' => [
'label' => 'Click and drag to reorder',
],

'indent' => [
'label' => 'Indent',
],

'dedent' => [
'label' => 'Dedent',
],
],

'items' => [
Expand Down
8 changes: 8 additions & 0 deletions resources/lang/pt_BR/adjacency-list.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@
'reorder' => [
'label' => 'Clique e arraste para reordenar',
],

'indent' => [
'label' => 'Indentar',
],

'dedent' => [
'label' => 'Desindentar',
],
],

'items' => [
Expand Down
6 changes: 5 additions & 1 deletion resources/views/builder.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ class="filament-navigation"
$isDeletable = $isDeletable();
$isDisabled = $isDisabled();
$isEditable = $isEditable();
$isIndentable = $isIndentable();
$isReorderable = $isReorderable();
$isCollapsible = $isCollapsible();
$isCollapsed = $isCollapsed();
$maxDepth = $getMaxDepth();
$addAction = $getAction('add');
$itemActions = [$getAction('addChild'), $getAction('delete'), $getAction('edit'), $getAction('reorder')];
$itemActions = [$getAction('addChild'), $getAction('delete'), $getAction('edit'), $getAction('reorder'), $getAction('indent'), $getAction('dedent')];
@endphp

<div wire:key="tree-items-wrapper">
Expand All @@ -47,12 +48,15 @@ class="filament-navigation"
:actions="$itemActions"
:addable="$isAddable"
:children-key="$getChildrenKey()"
:dedentable="$isIndentable && false"
:deletable="$isDeletable"
:disabled="$isDisabled"
:editable="$isEditable"
:indentable="$isIndentable && (!$loop->first && $loop->count > 1)"
:has-rulers="$hasRulers"
:is-collapsed="$isCollapsed"
:is-collapsible="$isCollapsible"
:is-indentable="$isIndentable"
:item="$item"
:item-state-path="$getStatePath() . '.' . $uuid"
:label-key="$getLabelKey()"
Expand Down
14 changes: 10 additions & 4 deletions resources/views/components/item.blade.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@props(['uuid', 'treeId', 'actions', 'addable', 'childrenKey', 'hasRulers', 'isCollapsible', 'isCollapsed', 'deletable', 'disabled', 'editable', 'item', 'itemStatePath', 'labelKey', 'reorderable', 'statePath'])
@props(['uuid', 'treeId', 'actions', 'addable', 'childrenKey', 'dedentable', 'hasRulers', 'indentable', 'isCollapsible', 'isCollapsed', 'isIndentable', 'deletable', 'disabled', 'editable', 'item', 'itemStatePath', 'labelKey', 'reorderable', 'statePath'])

<div
{{-- hover:bg-gray-950/5 --}}
Expand All @@ -9,7 +9,7 @@ class="pb-3 rounded-lg"
wire:key="{{ $itemStatePath }}"
>
@php
[$addChildAction, $deleteAction, $editAction, $reorderAction] = $actions;
[$addChildAction, $deleteAction, $editAction, $reorderAction, $indentAction, $dedentAction] = $actions;
$hasChildren = count($item[$childrenKey] ?? []) > 0;
Expand Down Expand Up @@ -63,8 +63,11 @@ class="px-2 text-gray-500 appearance-none"
@if ($addable)
{{ $addChildAction($mountArgs) }}
@endif
@if ($editable)
{{ $editAction($mountArgs) }}
@if ($dedentable)
{{ $dedentAction($mountArgs) }}
@endif
@if ($indentable)
{{ $indentAction($mountArgs) }}
@endif
@if ($deletable)
{{ $deleteAction($mountArgs) }}
Expand Down Expand Up @@ -100,10 +103,13 @@ class="px-2 text-gray-500 appearance-none"
:children-key="$childrenKey"
:deletable="$deletable"
:disabled="$disabled"
:dedentable="$isIndentable && true"
:editable="$editable"
:indentable="$isIndentable && (!$loop->first && $loop->count > 1)"
:has-rulers="$hasRulers"
:is-collapsed="$isCollapsed"
:is-collapsible="$isCollapsible"
:is-indentable="$isIndentable"
:item="$child"
:item-state-path="$itemStatePath . '.' . $childrenKey . '.' . $uuid"
:label-key="$labelKey"
Expand Down
59 changes: 59 additions & 0 deletions src/Forms/Components/Actions/DedentAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace Saade\FilamentAdjacencyList\Forms\Components\Actions;

use Filament\Forms\Components\Actions\Action;
use Filament\Support\Enums\ActionSize;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Saade\FilamentAdjacencyList\Forms\Components\Component;

class DedentAction extends Action
{
public static function getDefaultName(): ?string
{
return 'dedent';
}

protected function setUp(): void
{
parent::setUp();

$this->iconButton()->icon('heroicon-o-arrow-left')->color('gray');

$this->label(fn (): string => __('filament-adjacency-list::adjacency-list.actions.dedent.label'));

$this->size(ActionSize::ExtraSmall);

$this->action(
function (Component $component, array $arguments): void {
$statePath = $component->getRelativeStatePath($arguments['statePath']);
$state = $component->getState();

$item = data_get($state, $statePath);
$uuid = (string) Str::afterLast($statePath, '.');

$parentPath = (string) Str::beforeLast($statePath, '.');
$parent = data_get($state, $parentPath);

$pathToMoveInto = (string) Str::of($statePath)->beforeLast('.')->rtrim('.children')->beforeLast('.');
$pathToMoveIntoData = data_get($state, $pathToMoveInto);

if (array_key_exists($pathToMoveInto, $state) || ! str_contains($pathToMoveInto, '.children')) {
data_set($state, $uuid, $item);
} else {
$pathToMoveIntoData[$uuid] = $item;
data_set($state, $pathToMoveInto, $pathToMoveIntoData);
}

data_set($state, $parentPath, Arr::except($parent, $uuid));

$component->state($state);
}
);

$this->visible(
fn (Component $component): bool => $component->isIndentable()
);
}
}
69 changes: 69 additions & 0 deletions src/Forms/Components/Actions/IndentAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

namespace Saade\FilamentAdjacencyList\Forms\Components\Actions;

use Filament\Forms\Components\Actions\Action;
use Filament\Support\Enums\ActionSize;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Saade\FilamentAdjacencyList\Forms\Components\Component;

class IndentAction extends Action
{
public static function getDefaultName(): ?string
{
return 'indent';
}

protected function setUp(): void
{
parent::setUp();

$this->iconButton()->icon('heroicon-o-arrow-right')->color('gray');

$this->label(fn (): string => __('filament-adjacency-list::adjacency-list.actions.indent.label'));

$this->size(ActionSize::ExtraSmall);

$this->action(
function (Component $component, array $arguments): void {
$statePath = $component->getRelativeStatePath($arguments['statePath']);
$state = $component->getState();

$item = data_get($state, $statePath);
$uuid = Str::afterLast($statePath, '.');

$parentPath = Str::beforeLast($statePath, '.');
$parent = data_get($state, $parentPath);

if ($parentPath === $uuid) {
$parent = $state;
}

$keys = array_keys($parent);
$position = array_search($uuid, $keys);

$previous = $parent[$keys[$position - 1]];

if (! isset($previous['children'])) {
$previous['children'] = [];
}

$previous['children'][$uuid] = $item;
$parent[$keys[$position - 1]] = $previous;

if ($parentPath === $uuid) {
$state = Arr::except($parent, $uuid);
} else {
data_set($state, $parentPath, Arr::except($parent, $uuid));
}

$component->state($state);
}
);

$this->visible(
fn (Component $component): bool => $component->isIndentable()
);
}
}
2 changes: 2 additions & 0 deletions src/Forms/Components/Component.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ protected function setUp(): void
fn (Component $component): Action => $component->getDeleteAction(),
fn (Component $component): Action => $component->getEditAction(),
fn (Component $component): Action => $component->getReorderAction(),
fn (Component $component): Action => $component->getIndentAction(),
fn (Component $component): Action => $component->getDedentAction(),
]);

$this->registerListeners([
Expand Down
64 changes: 64 additions & 0 deletions src/Forms/Components/Concerns/HasActions.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
use Filament\Forms\Components\Actions\Action;
use Saade\FilamentAdjacencyList\Forms\Components\Actions\AddAction;
use Saade\FilamentAdjacencyList\Forms\Components\Actions\AddChildAction;
use Saade\FilamentAdjacencyList\Forms\Components\Actions\DedentAction;
use Saade\FilamentAdjacencyList\Forms\Components\Actions\DeleteAction;
use Saade\FilamentAdjacencyList\Forms\Components\Actions\EditAction;
use Saade\FilamentAdjacencyList\Forms\Components\Actions\IndentAction;
use Saade\FilamentAdjacencyList\Forms\Components\Actions\ReorderAction;

trait HasActions
Expand All @@ -20,6 +22,8 @@ trait HasActions

protected bool | Closure $isReorderable = true;

protected bool | Closure $isIndentable = true;

protected ?Closure $modifyAddActionUsing = null;

protected ?Closure $modifyAddChildActionUsing = null;
Expand All @@ -30,6 +34,10 @@ trait HasActions

protected ?Closure $modifyReorderActionUsing = null;

protected ?Closure $modifyIndentActionUsing = null;

protected ?Closure $modifyDedentActionUsing = null;

public function getAddAction(): Action
{
$action = AddAction::make();
Expand Down Expand Up @@ -135,6 +143,46 @@ public function reorderAction(?Closure $callback): static
return $this;
}

public function getIndentAction(): Action
{
$action = IndentAction::make();

if ($this->modifyIndentActionUsing) {
$action = $this->evaluate($this->modifyIndentActionUsing, [
'action' => $action,
]) ?? $action;
}

return $action;
}

public function indentAction(?Closure $callback): static
{
$this->modifyIndentActionUsing = $callback;

return $this;
}

public function getDedentAction(): Action
{
$action = DedentAction::make();

if ($this->modifyDedentActionUsing) {
$action = $this->evaluate($this->modifyDedentActionUsing, [
'action' => $action,
]) ?? $action;
}

return $action;
}

public function dedentAction(?Closure $callback): static
{
$this->modifyDedentActionUsing = $callback;

return $this;
}

public function addable(bool | Closure $condition = true): static
{
$this->isAddable = $condition;
Expand Down Expand Up @@ -198,4 +246,20 @@ public function isReorderable(): bool

return (bool) $this->evaluate($this->isReorderable);
}

public function indentable(bool | Closure $condition = true): static
{
$this->isIndentable = $condition;

return $this;
}

public function isIndentable(): bool
{
if ($this->isDisabled()) {
return false;
}

return (bool) $this->evaluate($this->isIndentable);
}
}

0 comments on commit 1c49c31

Please sign in to comment.