Builder administration area
* Page builder foundation * Form builder document type * Dashboard builder document type * Report builder document type * Menu builder document type * Email builder document type * Query builder document type * Workflow builder document type * Reusable component registry * Form-field registry * Dashboard-widget registry * Hero, heading, and rich-content components * JSON document schema * Saved builder documents * Draft, published, and archived states * Document version history * Reusable builder templates * Component rendering service * Extensible BuilderComponent contract * Authenticated Builder REST endpoints * Administration navigation * Builder permissions * Module registration and test
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace Modules\Builder\Services;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Modules\Builder\Models\BuilderDocument;
|
||||
final class BuilderDocumentService
|
||||
{
|
||||
public function save(BuilderDocument $document, array $payload, ?int $userId=null): BuilderDocument
|
||||
{
|
||||
return DB::transaction(function () use ($document,$payload,$userId) {
|
||||
if ($document->exists && $document->isDirty()) $document->versions()->create(['version'=>$document->version,'document'=>$document->getOriginal('document') ?: [],'settings'=>$document->getOriginal('settings') ?: [],'created_by'=>$userId]);
|
||||
$document->fill($payload); $document->updated_by=$userId;
|
||||
if (!$document->exists) $document->created_by=$userId; else $document->version++;
|
||||
$document->save(); return $document->refresh();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace Modules\Builder\Services;
|
||||
use InvalidArgumentException;
|
||||
use Modules\Builder\Contracts\BuilderComponent;
|
||||
use Modules\Builder\Components\ContentComponent;
|
||||
use Modules\Builder\Components\HeadingComponent;
|
||||
use Modules\Builder\Components\HeroComponent;
|
||||
final class BuilderRegistry
|
||||
{
|
||||
private array $components=[];
|
||||
private array $widgets=[];
|
||||
private array $fields=[];
|
||||
public function registerDefaults(): void
|
||||
{
|
||||
foreach ([HeroComponent::class, HeadingComponent::class, ContentComponent::class] as $component) $this->registerComponent(new $component());
|
||||
foreach (['metric','chart','table','activity','calendar'] as $widget) $this->widgets[$widget]=['type'=>$widget,'label'=>str($widget)->headline()->toString()];
|
||||
foreach (['text','textarea','email','number','select','checkbox','date','file'] as $field) $this->fields[$field]=['type'=>$field,'label'=>str($field)->headline()->toString()];
|
||||
}
|
||||
public function registerComponent(BuilderComponent $component): void { $this->components[$component->type()]=$component; }
|
||||
public function component(string $type): BuilderComponent { return $this->components[$type] ?? throw new InvalidArgumentException("Unknown builder component [$type]."); }
|
||||
public function components(): array { return array_map(fn(BuilderComponent $c)=>['type'=>$c->type(),'label'=>$c->label(),'category'=>$c->category(),'schema'=>$c->schema(),'defaults'=>$c->defaults()],array_values($this->components)); }
|
||||
public function widgets(): array { return array_values($this->widgets); }
|
||||
public function fields(): array { return array_values($this->fields); }
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace Modules\Builder\Services;
|
||||
final class BuilderRenderer
|
||||
{
|
||||
public function __construct(private BuilderRegistry $registry) {}
|
||||
public function render(array $document, array $context=[]): string
|
||||
{
|
||||
return collect($document['nodes'] ?? [])->map(function(array $node) use ($context) {
|
||||
if (($node['kind'] ?? 'component') === 'container') return '<div class="builder-container">'.$this->render($node,$context).'</div>';
|
||||
return $this->registry->component((string)($node['type'] ?? 'content'))->render($node['properties'] ?? [],$context);
|
||||
})->implode("\n");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user