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

Section visibility #199

Merged
merged 17 commits into from
Oct 29, 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
573 changes: 288 additions & 285 deletions composer.lock

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions database/migrations/add_options_to_section.php.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?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::table('sections', function (Blueprint $table) {
$table->text('options')->nullable();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('sections', function (Blueprint $table) {
$table->dropColumn('options');
});
}
};
2 changes: 1 addition & 1 deletion docs/advanced/add-datasource.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Custom Datasource
weight: 6
weight: 5
---

## Create Custom Datasource
Expand Down
2 changes: 1 addition & 1 deletion docs/advanced/add-fields.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Custom Fields
weight: 6
weight: 4
---

## Create Custom Fields
Expand Down
25 changes: 25 additions & 0 deletions docs/advanced/custom-designer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
title: Custom Designer
weight: 7
---

## Use Custom Designer

the trait `Designer` is the one responsible for presenting the form in the frontend, and now you can customize it to your liking.

> **Note**\
> This is an advanced feature; please use it only when necessary since you have to mainline it manually with every update for Bolt.

### First, copy the trait to your app:

copy the trait from `\LaraZeus\Bolt\Concerns` to your app, let say: `\App\Zeus\Bolt\Concerns`

### call the trait in a service provider

in your register method of your `AppServiceProvider` add the following:

```php
\LaraZeus\Bolt\Filament\Resources\FormResource::getBoltFormSchemaUsing(fn(): array => \App\Zeus\Bolt\Concerns\Designer::getMainFormSchema());
```

You're done. Customize the form builder to fit your needs. Remember to keep an eye on any changes in future updates so that you will avoid breaking changes.
6 changes: 4 additions & 2 deletions docs/advanced/custom-schemata.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
---
title: Custom Schemata
weight: 7
weight: 6
---

## Use Custom Schemata

the trait `Schemata` is the heart of the form builder, and now you can customize it to your liking.

> **Note**\
Expand All @@ -17,7 +19,7 @@ copy the trait from `\LaraZeus\Bolt\Concerns` to your app, let say: `\App\Zeus\B
in your register method of your `AppServiceProvider` add the following:

```php
\LaraZeus\Bolt\Filament\Resources\FormResource::getBoltFormSchemaUsing(fn(): array => \App\Zeus\Bolt\Concerns\Schemata::getMainFormSchema());
\LaraZeus\Bolt\Livewire\FillForms::getBoltFormDesignerUsing(\App\Zeus\Bolt\Concerns\Designer::class);
```

You're done. Customize the form builder to fit your needs. Remember to keep an eye on any changes in future updates so that you will avoid breaking changes.
2 changes: 1 addition & 1 deletion docs/advanced/events.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Events
weight: 7
weight: 1
---

## Available Events
Expand Down
2 changes: 1 addition & 1 deletion docs/advanced/extension.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Extensions
weight: 9
weight: 3
---

## Extensions
Expand Down
2 changes: 1 addition & 1 deletion docs/advanced/render-hooks.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Render hooks
weight: 8
weight: 2
---

## Render Hooks
Expand Down
29 changes: 29 additions & 0 deletions docs/getting-started/loading.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: Loading indicator
weight: 7
---

## Frontend loading indicator

by default there is a loading indicator on the top left next to the breadcrumbs, but you can customize it as you want.

### the loading blade:

create the file `resources/views/vendor/zeus/themes/zeus/bolt/loading.blade.php`
the default content :

```html
<div>
@teleport('.bolt-loading')
<div wire:loading class="px-4">
@svg('iconpark-loading-o', 'text-primary-600 w-8 h-8 animate-spin')
</div>
@endteleport
</div>
```

in your app layout add the following where you want the loader to show

```html
<div class="bolt-loading"></div>
```
7 changes: 6 additions & 1 deletion resources/lang/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -186,5 +186,10 @@
"Hint Color" :"لون التلميحة",
"Textarea": "نص مطول",
"Paragraph": "فقرة نصية",
"Color Picker": "اختيار اللون"
"Color Picker": "اختيار اللون",
"Entries Report": "تقرير السجلات",
"List Entries": "عرض السجلات",
"notes": "ملاحظات",
"Open": "عرض",
"Preset": "القوالب"
}
3 changes: 3 additions & 0 deletions resources/views/themes/zeus/bolt/fill-forms.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
@endphp

<div class="not-prose" style="{{ $colors }}">

@include($boltTheme.'.loading')

@if(class_exists(\LaraZeus\Bolt\BoltProServiceProvider::class) && optional($zeusForm->options)['logo'] !== null && optional($zeusForm)->options['cover'] !== null)
<div style="background-image: url('{{ \Illuminate\Support\Facades\Storage::disk(config('zeus-bolt.uploadDisk'))->url($zeusForm->options['cover']) }}')"
class="flex justify-start items-center px-4 py-6 gap-4 rounded-lg bg-clip-border bg-origin-border bg-cover bg-center">
Expand Down
8 changes: 8 additions & 0 deletions resources/views/themes/zeus/bolt/loading.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div>
<div class="bolt-loading"></div>
@teleport('.bolt-loading')
<div wire:loading class="px-4">
@svg('iconpark-loading-o', 'text-primary-600 w-8 h-8 animate-spin')
</div>
@endteleport
</div>
1 change: 1 addition & 0 deletions src/BoltServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ protected function getMigrations(): array
'add_extension_item_responses',
'alter_tables_constraints',
'add_compact_to_section',
'add_options_to_section',
];
}
}
141 changes: 141 additions & 0 deletions src/Concerns/Designer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<?php

namespace LaraZeus\Bolt\Concerns;

use Filament\Forms\Components\Section;
use Filament\Forms\Components\Tabs;
use Filament\Forms\Components\Tabs\Tab;
use Filament\Forms\Components\Wizard;
use Filament\Forms\Components\Wizard\Step;
use Filament\Forms\Get;
use LaraZeus\Bolt\Facades\Bolt;
use LaraZeus\Bolt\Facades\Extensions;
use LaraZeus\Bolt\Models\Form;
use LaraZeus\Bolt\Models\Section as ZeusSection;

trait Designer
{
public static function ui(Form $zeusForm, bool $inline = false): array
{
$sections = self::drawExt($zeusForm);

foreach ($zeusForm->sections->sortBy('ordering') as $section) {
$sections[] = self::drawSections(
$zeusForm,
$section,
self::drawFields($section, $inline)
);
}

if (optional($zeusForm->options)['show-as'] === 'tabs') {
return [Tabs::make('tabs')->live()->tabs($sections)];
}

if (optional($zeusForm->options)['show-as'] === 'wizard') {
return [
Wizard::make($sections)
->live(),
//->skippable() // todo still not working
];
}

return $sections;
}

private static function drawExt(Form $zeusForm): Section | array
{
$getExtComponent = Extensions::init($zeusForm, 'formComponents');

if ($getExtComponent === null) {
return [];
}

return Section::make('extensions')
->heading(function () use ($zeusForm) {
$class = $zeusForm->extensions;
if (class_exists($class)) {
return (new $class)->label();
}

return __('Extension');
})
->schema($getExtComponent);
}

private static function drawFields(ZeusSection $section, bool $inline): array
{
$fields = [];

if (! $inline) {
$fields[] = Bolt::renderHook('zeus-form-section.before');
}

foreach ($section->fields->sortBy('ordering') as $zeusField) {
if (! $inline) {
$fields[] = Bolt::renderHook('zeus-form-field.before');
}

$fieldClass = new $zeusField->type;
$component = $fieldClass->renderClass::make('zeusData.' . $zeusField->id);

$fields[] = $fieldClass->appendFilamentComponentsOptions($component, $zeusField);

if (! $inline) {
$fields[] = Bolt::renderHook('zeus-form-field.after');
}
}

if (! $inline) {
$fields[] = Bolt::renderHook('zeus-form-section.after');
}

return $fields;
}

private static function drawSections(Form $zeusForm, ZeusSection $section, array $fields): Tab | Step | Section
{
$component = Section::make($section->name)
->description($section->description)
->aside(fn () => $section->aside)
->compact(fn () => $section->compact)
->collapsible();

if (optional($zeusForm->options)['show-as'] === 'tabs') {
$component = Tab::make($section->name)
->icon($section->icon ?? null);
}

if (optional($zeusForm->options)['show-as'] === 'wizard') {
$component = Step::make($section->name)
->live()
->description($section->description)
->icon($section->icon ?? null);
}

$component->visible(function ($record, Get $get) use ($section) {

if (! isset($section->options['visibility']) || ! $section->options['visibility']['active']) {
return true;
}

$relatedField = $section->options['visibility']['fieldID'];
$relatedFieldValues = $section->options['visibility']['values'];

if (empty($relatedField) || empty($relatedFieldValues)) {
return true;
}

if (is_array($get('zeusData.' . $relatedField))) {
return in_array($relatedFieldValues, $get('zeusData.' . $relatedField));
}

return $relatedFieldValues === $get('zeusData.' . $relatedField);
});

return $component
->id(str($section->name)->slug() . '-' . $section->id)
->schema($fields)
->live()
->columns($section->columns);
}
}
12 changes: 8 additions & 4 deletions src/Concerns/HasOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

trait HasOptions
{
public static function visibility(): Grid
public static function visibility(string $type = 'field'): Grid
{
return Grid::make()
->schema([
Expand All @@ -30,15 +30,19 @@ public static function visibility(): Grid
->live()
->visible(fn (Get $get): bool => ! empty($get('options.visibility.active')))
->required(fn (Get $get): bool => ! empty($get('options.visibility.active')))
->options(function ($livewire, $record) {
->options(function ($livewire, $record) use ($type) {
if ($record === null) {
return [];
}

return $livewire->record
->fields()
->where('fields.id', '!=', $record->id ?? null)
->where('fields.options', '!=', $record->id ?? null)
->when($type === 'field', function ($query) use ($record) {
return $query->where('fields.id', '!=', $record->id);
})
->when($type === 'section', function ($query) use ($record) {
return $query->where('section_id', '!=', $record->id);
})
->where(function ($query) {
$query->whereNotNull('fields.options->dataSource');
$query->orWhere('type', '\LaraZeus\Bolt\Fields\Classes\Toggle');
Expand Down
4 changes: 3 additions & 1 deletion src/Concerns/Schemata.php
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,8 @@ public static function getTabsSchema(): array

Tabs\Tab::make('design')
->label(__('Design'))
->visible(fn (): bool => class_exists(\LaraZeus\BoltPro\BoltProServiceProvider::class) && config('zeus-bolt.allow_design'))
->visible(fn (
): bool => class_exists(\LaraZeus\BoltPro\BoltProServiceProvider::class) && config('zeus-bolt.allow_design'))
->schema([
ViewField::make('options.primary_color')
->view('zeus::filament.components.color-picker'),
Expand Down Expand Up @@ -295,6 +296,7 @@ public static function getSectionsSchema(): array
->inline(false)
->visible(fn (Get $get) => $get('../../options.show-as') === 'page')
->label(__('compact section')),
self::visibility('section'),
]),
]),
]),
Expand Down
Loading