Skip to content

Commit 2efb9cf

Browse files
committed
feat: add readonly infolist component
1 parent 9b27eb3 commit 2efb9cf

10 files changed

+258
-77
lines changed

resources/views/forms/page-builder-preview.blade.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
77
@if (!$shouldRenderWithIframe)
88
@if ($singleItemPreview)
9-
@component($getViewForBlock($pageBuilderData['block_type']), ['data' => $pageBuilderData['data']])
9+
@component($getViewForBlock($pageBuilderData['block_type']), ['block' => $pageBuilderData])
1010
@endcomponent
1111
@else
1212
@foreach ($pageBuilderData as $block)
13-
@component($getViewForBlock($block['block_type']), ['data' => $block['data']])
13+
@component($getViewForBlock($block['block_type']), ['data' => $block['data'], 'id' => $block['id']])
1414
@endcomponent
1515
@endforeach
1616
@endif
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@php
2+
$blocks = $getBlocks();
3+
$state = $getState();
4+
@endphp
5+
6+
<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry">
7+
@if (count($blocks) && $state)
8+
<ul>
9+
<x-filament::grid class="items-start gap-4">
10+
@foreach ($state as $item)
11+
<li
12+
class="fi-fo-repeater-item divide-y divide-gray-100 rounded-xl bg-white shadow-sm ring-1 ring-gray-950/5 dark:divide-white/10 dark:bg-white/5 dark:ring-white/10">
13+
<div class ='fi-fo-repeater-item-header flex items-center gap-x-3 overflow-hidden px-4 py-3 '>
14+
<div class="flex justify-between w-full items-center">
15+
{{ $item['block_type']::getBlockLabel($item, $loop->index) }}
16+
</div>
17+
</div>
18+
</li>
19+
@endforeach
20+
</x-filament::grid>
21+
</ul>
22+
@endif
23+
</x-dynamic-component>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
@php
2+
$blocks = $getBlocks();
3+
$shouldRenderWithIframe = $getRenderWithIframe();
4+
$state = $getState();
5+
@endphp
6+
7+
<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry">
8+
@if (count($blocks) && $state)
9+
@if ($shouldRenderWithIframe)
10+
<iframe
11+
src="{{ $getIframeUrl() }}"
12+
x-data="{
13+
data: @js($state),
14+
ready: $wire.entangle('{{ $getStatePath() }}.ready'),
15+
init() {
16+
if (this.ready) {
17+
$root.contentWindow.postMessage(JSON.stringify(this.data), '*');
18+
}
19+
}
20+
}"
21+
@message.window="() => {
22+
if (!$data.ready) {
23+
$data.ready = $event.data === 'readyForData';
24+
$root.contentWindow.postMessage(JSON.stringify($data.data), '*');
25+
}
26+
}"
27+
class="w-full h-screen"
28+
frameborder="0"
29+
allowfullscreen
30+
>
31+
</iframe>
32+
@else
33+
@foreach ($state as $block)
34+
@component($getViewForBlock($block['block_type']), ['block' => $block])
35+
@endcomponent
36+
@endforeach
37+
@endif
38+
@endif
39+
</x-dynamic-component>

src/Components/Forms/PageBuilder.php

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
use RedberryProducts\PageBuilderPlugin\Components\Forms\Actions\EditPageBuilderBlockAction;
1919
use RedberryProducts\PageBuilderPlugin\Components\Forms\Actions\ReoraderPageBuilderBlockAction;
2020
use RedberryProducts\PageBuilderPlugin\Components\Forms\Actions\SelectBlockAction;
21+
use RedberryProducts\PageBuilderPlugin\Traits\ComponentLoadsPageBuilderBlocks;
2122

22-
// TODO: make this reorder-able
2323
class PageBuilder extends Field
2424
{
25-
public ?string $relationship = null;
25+
use ComponentLoadsPageBuilderBlocks;
2626

2727
public bool | Closure $reorderable = false;
2828

@@ -42,7 +42,6 @@ class PageBuilder extends Field
4242

4343
protected ?Closure $renderReorderActionButtonUsing = null;
4444

45-
public array | Closure $blocks = [];
4645

4746
public string $view = 'page-builder-plugin::forms.page-builder';
4847

@@ -293,14 +292,6 @@ public function reorderAction(
293292
return $this;
294293
}
295294

296-
public function blocks(
297-
array | Closure $blocks,
298-
) {
299-
$this->blocks = $blocks;
300-
301-
return $this;
302-
}
303-
304295
public function reorderable(
305296
bool | Closure $reorderable = true,
306297
) {
@@ -314,18 +305,6 @@ public function getReorderable(): bool
314305
return (bool) $this->evaluate($this->reorderable);
315306
}
316307

317-
#[Computed(true)]
318-
public function getBlocks(): array
319-
{
320-
$evaluated = $this->evaluate($this->blocks);
321-
322-
if (is_array($evaluated)) {
323-
return $evaluated;
324-
}
325-
326-
return [];
327-
}
328-
329308
public function getBlockSchema(string $blockType, ?Model $record, Component $component, Page $livewire): array
330309
{
331310
return $blockType::getBlockSchema(
@@ -389,11 +368,12 @@ public function relationship(
389368
}
390369

391370
public function renderPreviewWithIframes(
392-
bool | Closure $value,
371+
bool | Closure $condition = true,
393372
string | Closure $createUrl,
373+
// TODO: make one of them optional
394374
string | Closure $updateUrl,
395375
) {
396-
$value = (bool) $this->evaluate($value);
376+
$condition = (bool) $this->evaluate($condition);
397377

398378
$this->createAction(function (CreatePageBuilderBlockAction $action) use ($createUrl) {
399379
return $action->pageBuilderPreviewField(function (PageBuilderPreview $field) use ($createUrl) {
@@ -409,10 +389,4 @@ public function renderPreviewWithIframes(
409389

410390
return $this;
411391
}
412-
413-
public function getConstrainAppliedQuery(Model $record)
414-
{
415-
return $record->{$this->relationship}()
416-
->whereIn('block_type', $this->getBlocks());
417-
}
418392
}

src/Components/Forms/PageBuilderPreview.php

Lines changed: 9 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@
22

33
namespace RedberryProducts\PageBuilderPlugin\Components\Forms;
44

5-
use Closure;
65
use Filament\Forms\Components\Field;
76
use Filament\Forms\Components\Hidden;
7+
use RedberryProducts\PageBuilderPlugin\Traits\ListPreviewRendersWithIframe;
8+
use RedberryProducts\PageBuilderPlugin\Traits\PreviewRendersWithBlade;
89

910
class PageBuilderPreview extends Field
1011
{
11-
public ?string $pageBuilderField = null;
12-
13-
public bool $renderWithIframe = false;
12+
use ListPreviewRendersWithIframe, PreviewRendersWithBlade;
1413

15-
public string | Closure $iframeUrl = '';
14+
public ?string $pageBuilderField = null;
1615

1716
public bool $singleItemPreview = false;
1817

@@ -48,47 +47,11 @@ public function singleItemPreview(bool $singleItemPreview = true): static
4847
return $this;
4948
}
5049

51-
public function renderWithIframe(bool $renderWithIframe = true): static
52-
{
53-
$this->renderWithIframe = $renderWithIframe;
54-
55-
return $this;
56-
}
57-
58-
public function iframeUrl(string | Closure $iframeUrl): static
59-
{
60-
$this->iframeUrl = $iframeUrl;
61-
$this->renderWithIframe();
62-
63-
return $this;
64-
}
65-
66-
public function getIframeUrl(): string
67-
{
68-
return (string) $this->evaluate($this->iframeUrl);
69-
}
70-
71-
public function getRenderWithIframe(): bool
72-
{
73-
return $this->renderWithIframe;
74-
}
75-
7650
public function getSingleItemPreview(): bool
7751
{
7852
return $this->singleItemPreview;
7953
}
8054

81-
public function getViewForBlock(string $class)
82-
{
83-
$view = $class::getView();
84-
85-
if ($view) {
86-
return $view;
87-
}
88-
89-
throw new \Exception('View not found for block ' . $class . ' if you want to use view method of rendering you need to declare view for a block.');
90-
}
91-
9255
public function getPageBuilderData(): array
9356
{
9457
if (! $this->pageBuilderField) {
@@ -102,9 +65,10 @@ public function getPageBuilderData(): array
10265

10366
if ($blockType) {
10467
$formatted = $blockType::formatForSinglePreview($data['data']);
105-
10668
return [
107-
'block_type' => $blockType,
69+
'id' => app(config('page-builder-plugin.block_model_class'))->newUniqueId(),
70+
...$data,
71+
'block_name' => $blockType::getBlockName(),
10872
'data' => $formatted,
10973
];
11074
}
@@ -121,7 +85,8 @@ public function getPageBuilderData(): array
12185
$formatted = $blockType::formatForSinglePreview($item['data']);
12286

12387
return [
124-
'block_type' => $blockType,
88+
...$item,
89+
'block_name' => $blockType::getBlockName(),
12590
'data' => $formatted,
12691
];
12792
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace RedberryProducts\PageBuilderPlugin\Components\Infolist;
4+
5+
6+
use Filament\Infolists\Components\Entry;
7+
use RedberryProducts\PageBuilderPlugin\Traits\ComponentLoadsPageBuilderBlocks;
8+
9+
class PageBuilderEntry extends Entry
10+
{
11+
use ComponentLoadsPageBuilderBlocks;
12+
13+
public string $view = 'page-builder-plugin::infolist.page-builder-entry';
14+
15+
protected function setUp(): void
16+
{
17+
parent::setUp();
18+
19+
$this->columnSpanFull();
20+
21+
$this->relationship('pageBuilderBlocks');
22+
}
23+
24+
public function relationship(
25+
string $relationship,
26+
) {
27+
$this->relationship = $relationship;
28+
29+
$this->getStateUsing(function () {
30+
return $this->getConstrainAppliedQuery($this->getRecord())->get()->toArray();
31+
});
32+
}
33+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace RedberryProducts\PageBuilderPlugin\Components\Infolist;
4+
5+
use Filament\Infolists\Components\Entry;
6+
use Illuminate\Database\Eloquent\Collection;
7+
use RedberryProducts\PageBuilderPlugin\Contracts\BaseBlock;
8+
use RedberryProducts\PageBuilderPlugin\Traits\ComponentLoadsPageBuilderBlocks;
9+
use RedberryProducts\PageBuilderPlugin\Traits\ListPreviewRendersWithIframe;
10+
use RedberryProducts\PageBuilderPlugin\Traits\PreviewRendersWithBlade;
11+
12+
class PageBuilderPreviewEntry extends Entry
13+
{
14+
use ComponentLoadsPageBuilderBlocks;
15+
use ListPreviewRendersWithIframe;
16+
use PreviewRendersWithBlade;
17+
18+
public string $view = 'page-builder-plugin::infolist.page-builder-preview-entry';
19+
20+
protected function setUp(): void
21+
{
22+
parent::setUp();
23+
24+
$this->columnSpanFull();
25+
26+
$this->relationship('pageBuilderBlocks');
27+
}
28+
29+
public function relationship(
30+
string $relationship,
31+
) {
32+
$this->relationship = $relationship;
33+
34+
$this->getStateUsing(function () {
35+
/** @var Collection */
36+
$state = $this->getConstrainAppliedQuery($this->getRecord())->get();
37+
38+
$state->transform(function ($item) {
39+
/** @var BaseBlock */
40+
$blockClass = $item->block_type;
41+
return [
42+
...$item->toArray(),
43+
'data' => $blockClass::formatForListing($item->data),
44+
];
45+
});
46+
47+
return $state;
48+
});
49+
}
50+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace RedberryProducts\PageBuilderPlugin\Traits;
4+
5+
use Closure;
6+
use Illuminate\Database\Eloquent\Model;
7+
use Livewire\Attributes\Computed;
8+
9+
trait ComponentLoadsPageBuilderBlocks
10+
{
11+
public ?string $relationship = null;
12+
13+
public array | Closure $blocks = [];
14+
15+
public function getConstrainAppliedQuery(Model $record)
16+
{
17+
// TODO: refactor this to not use relationship function
18+
return $record->{$this->relationship}()
19+
->whereIn('block_type', $this->getBlocks());
20+
}
21+
22+
public function blocks(
23+
array | Closure $blocks,
24+
) {
25+
$this->blocks = $blocks;
26+
27+
return $this;
28+
}
29+
30+
#[Computed(true)]
31+
public function getBlocks(): array
32+
{
33+
$evaluated = $this->evaluate($this->blocks);
34+
35+
if (is_array($evaluated)) {
36+
return $evaluated;
37+
}
38+
39+
return [];
40+
}
41+
42+
}

0 commit comments

Comments
 (0)