Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add navigation #174

Merged
merged 2 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
"php": "^8.1",
"ext-json": "*",
"doctrine/dbal": "^3.5.1",
"ryangjchandler/filament-navigation": "^1.0",
"filament/spatie-laravel-media-library-plugin": "^3.0",
"filament/spatie-laravel-tags-plugin": "^3.0",
"spatie/laravel-medialibrary": "^10.0.0",
Expand Down
853 changes: 391 additions & 462 deletions composer.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions config/zeus-sky.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
'PostStatus' => \LaraZeus\Sky\Models\PostStatus::class,
'Tag' => \LaraZeus\Sky\Models\Tag::class,
'Library' => \LaraZeus\Sky\Models\Library::class,
'Navigation' => \LaraZeus\Sky\Models\Navigation::class,
],

'parsers' => [
Expand Down
34 changes: 34 additions & 0 deletions database/migrations/create_navigations_table.php.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('navigations', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('handle')->unique();
$table->longText('items')->nullable();
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('navigations');
}
};
2 changes: 1 addition & 1 deletion docs/advanced/customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ php artisan vendor:publish --tag=zeus-sky-translations
to render the navigation:

```
@php $menu = RyanChandler\FilamentNavigation\Models\Navigation::fromHandle('main-header-menu'); @endphp
@php $menu = \LaraZeus\Sky\SkyPlugin::get()->getModel('Navigation')::fromHandle('main-header-menu'); @endphp
@foreach($menu->items as $item)
{!! \LaraZeus\Sky\Classes\RenderNavItem::render($item,'px-5 py-2 text-sm font-medium text-gray-600 hover:text-blue-500 dark:text-gray-400') !!}
@endforeach
Expand Down
37 changes: 37 additions & 0 deletions resources/lang/ar/filament-navigation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

return [
'attributes' => [
'external-link' => 'رابط خارجي',
'url' => 'الرابط',
'target' => 'الهدف',
'name' => 'الاسم',
'items' => 'العناصر',
'handle' => 'المعرف',
'created_at' => 'تم الإنشاء في',
'updated_at' => 'تم التحديث في',
],

'select-options' => [
'same-tab' => 'نفس علامة التبويب',
'new-tab' => 'علامة تبويب جديدة',
],

'items' => [
'empty' => 'لا يوجد عناصر.',
'add-item' => 'إضافة عنصر',
'add-child' => 'إضافة فرع',
'move-up' => 'تحريك للأعلى',
'move-down' => 'تحريك للأسفل',
'indent' => 'إزاحة للداخل',
'dedent' => 'إزاحة للخارج',
'remove' => 'إزالة',
],

'items-modal' => [
'title' => 'العنوان',
'label' => 'التسمية',
'type' => 'النوع',
'btn' => 'حفظ',
],
];
38 changes: 38 additions & 0 deletions resources/lang/en/filament-navigation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

return [
'attributes' => [
'external-link' => 'External link',
'url' => 'URL',
'target' => 'Target',
'name' => 'Name',
'items' => 'Items',
'handle' => 'Handle',
'created_at' => 'Created at',
'updated_at' => 'Updated at',

],

'select-options' => [
'same-tab' => 'Same tab',
'new-tab' => 'New tab',
],

'items' => [
'empty' => 'No items.',
'add-item' => 'Add item',
'add-child' => 'Add child',
'move-up' => 'Move up',
'move-down' => 'Move down',
'indent' => 'Indent',
'dedent' => 'Dedent',
'remove' => 'Remove',
],

'items-modal' => [
'title' => 'Item',
'label' => 'Label',
'type' => 'Type',
'btn' => 'Save',
],
];
81 changes: 81 additions & 0 deletions resources/views/components/nav-item.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
@props(['item', 'statePath'])

<div
x-data="{ open: $persist(true) }"
wire:key="{{ $statePath }}"
data-id="{{ $statePath }}"
class="space-y-2"
data-sortable-item
>
<div class="relative group">
<div @class([
'bg-white rounded-lg border border-gray-300 w-full flex',
'dark:bg-gray-700 dark:border-gray-600',
])>
<button type="button" @class([
'flex items-center bg-gray-50 ltr:rounded-l-lg rtl:rounded-r-lg ltr:border-r rtl:border-l border-gray-300 px-px',
'dark:bg-gray-800 dark:border-gray-600',
]) data-sortable-handle>
@svg('heroicon-o-ellipsis-vertical', 'text-gray-400 w-4 h-4 ltr:-mr-2 rtl:-ml-2')
@svg('heroicon-o-ellipsis-vertical', 'text-gray-400 w-4 h-4')
</button>

<button
type="button"
wire:click="editItem('{{ $statePath }}')"
class="appearance-none px-3 py-2 ltr:text-left rtl:text-right"
>
<span>{{ $item['label'] }}</span>
</button>

@if(count($item['children']) > 0)
<button type="button" x-on:click="open = !open" title="Toggle children" class="appearance-none text-gray-500">
<svg class="w-3.5 h-3.5 transition ease-in-out duration-200" x-bind:class="{
'-rotate-90': !open,
}" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
</button>
@endif
</div>

<div @class([
'absolute top-0 ltr:right-0 h-6 divide-x ltr:rounded-bl-lg ltr:rounded-tr-lg border-gray-300 border-b border-l overflow-hidden rtl:border-l-0 rtl:border-r rtl:left-0 rtl:rounded-br-lg rtl:rounded-tl-lg hidden opacity-0 group-hover:opacity-100 group-hover:flex transition ease-in-out duration-250',
'dark:border-gray-600 dark:divide-gray-600',
])>
<button
x-init
x-tooltip.raw.duration.0="{{__('zeus-sky::filament-navigation.items.add-child')}}"
type="button"
wire:click="addChild('{{ $statePath }}')"
class="p-1"
title="{{__('zeus-sky::filament-navigation.items.add-child')}}"
>
@svg('heroicon-o-plus', 'w-3 h-3 text-gray-500 hover:text-gray-900')
</button>

<button
x-init
x-tooltip.raw.duration.0="{{__('zeus-sky::filament-navigation.items.remove')}}"
type="button"
wire:click="removeItem('{{ $statePath }}')"
class="p-1"
title="{{__('zeus-sky::filament-navigation.items.remove')}}"
>
@svg('heroicon-o-trash', 'w-3 h-3 text-danger-500 hover:text-danger-900')
</button>
</div>
</div>

<div x-show="open" x-collapse class="ltr:ml-6 rtl:mr-6">
<div
class="space-y-2"
wire:key="{{ $statePath }}-children"
x-data="navigationSortableContainer({
statePath: @js($statePath . '.children')
})"
>
@foreach ($item['children'] as $uuid => $child)
<x-zeus::nav-item :statePath="$statePath . '.children.' . $uuid" :item="$child" />
@endforeach
</div>
</div>
</div>
3 changes: 3 additions & 0 deletions resources/views/filament/card-divider.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="filament-navigation">
<hr class="-mx-6 border-gray-300 dark:border-gray-600">
</div>
Empty file.
37 changes: 37 additions & 0 deletions resources/views/filament/navigation-builder.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<x-filament-forms::field-wrapper
:id="$getId()"
:label="$getLabel()"
:label-sr-only="$isLabelHidden()"
:helper-text="$getHelperText()"
:hint="$getHint()"
:hint-icon="$getHintIcon()"
:required="$isRequired()"
:state-path="$getStatePath()"
>
<div wire:key="navigation-items-wrapper">
<div
class="space-y-2"
x-data="navigationSortableContainer({
statePath: @js($getStatePath())
})"
data-sortable-container
>
@forelse($getState() as $uuid => $item)
<x-zeus::nav-item :statePath="$getStatePath() . '.' . $uuid" :item="$item" />
@empty
<div @class([
'w-full bg-white rounded-lg border border-gray-300 px-3 py-2 text-left',
'dark:bg-gray-700 dark:border-gray-600',
])>
{{__('zeus-sky::filament-navigation.items.empty')}}
</div>
@endforelse
</div>
</div>

<div class="flex justify-end">
<x-filament::button wire:click="createItem" type="button" size="sm">
{{__('zeus-sky::filament-navigation.items.add-item')}}
</x-filament::button>
</div>
</x-filament-forms::field-wrapper>
70 changes: 68 additions & 2 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
namespace LaraZeus\Sky;

use Closure;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Illuminate\Support\Str;

trait Configuration
{
Expand Down Expand Up @@ -34,8 +37,6 @@ trait Configuration

/**
* you can overwrite any model and use your own
*
* @deprecated deprecated since version 3.2
*/
protected array $skyModels = [];

Expand Down Expand Up @@ -125,6 +126,12 @@ trait Configuration

protected bool $hasTagResource = true;

protected bool $hasNavigationResource = true;

protected array $itemTypes = [];

protected array | Closure $extraFields = [];

/*
* @deprecated deprecated since version 3.2
*/
Expand Down Expand Up @@ -403,6 +410,18 @@ public function hasTagResource(): bool
return $this->hasTagResource;
}

public function navigationResource(bool $condition = true): static
{
$this->hasNavigationResource = $condition;

return $this;
}

public function hasNavigationResource(): bool
{
return $this->hasNavigationResource;
}

public function libraryTypes(array $types): static
{
$this->libraryTypes = $types;
Expand Down Expand Up @@ -438,4 +457,51 @@ public function getTagTypes(): ?array

return $this->translatedTagTypes ?? $this->tagTypes;
}

public function itemType(string $name, array | Closure $fields, string $slug = null): static
{
$this->itemTypes[$slug ?? Str::slug($name)] = [
'name' => $name,
'fields' => $fields,
];

return $this;
}

public function withExtraFields(array | Closure $schema): static
{
$this->extraFields = $schema;

return $this;
}

public function getExtraFields(): array | Closure
{
return $this->extraFields;
}

public function getItemTypes(): array
{
return array_merge(
[
'external-link' => [
'name' => __('zeus-sky::filament-navigation.attributes.external-link'),
'fields' => [
TextInput::make('url')
->label(__('zeus-sky::filament-navigation.attributes.url'))
->required(),
Select::make('target')
->label(__('zeus-sky::filament-navigation.attributes.target'))
->options([
'' => __('zeus-sky::filament-navigation.select-options.same-tab'),
'_blank' => __('zeus-sky::filament-navigation.select-options.new-tab'),
])
->default('')
->selectablePlaceholder(false),
],
],
],
$this->itemTypes
);
}
}
25 changes: 25 additions & 0 deletions src/Filament/Fields/NavigationSelect.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace LaraZeus\Sky\Filament\Fields;

use Filament\Forms\Components\Select;
use LaraZeus\Sky\SkyPlugin;

class NavigationSelect extends Select
{
protected string $optionValueProperty = 'id';

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

$this->options(function (NavigationSelect $component) {
return SkyPlugin::get()->getModel('Navigation')::pluck('name', $component->getOptionValueProperty());
});
}

public function getOptionValueProperty(): string
{
return $this->optionValueProperty;
}
}
Loading