diff --git a/app/MoonShine/Pages/UI/JsonPage.php b/app/MoonShine/Pages/UI/JsonPage.php
index 3ff9ca2..e5990f9 100644
--- a/app/MoonShine/Pages/UI/JsonPage.php
+++ b/app/MoonShine/Pages/UI/JsonPage.php
@@ -9,10 +9,12 @@
use MoonShine\Contracts\Core\DependencyInjection\CrudRequestContract;
use MoonShine\Contracts\UI\FieldContract;
use MoonShine\Crud\JsonResponse;
+use MoonShine\Laravel\Collections\Fields;
use MoonShine\Laravel\Pages\Page;
use MoonShine\MenuManager\Attributes\Group;
use MoonShine\MenuManager\Attributes\Order;
use MoonShine\Support\Attributes\AsyncMethod;
+use MoonShine\UI\Components\ActionButton;
use MoonShine\UI\Components\FormBuilder;
use MoonShine\UI\Components\Layout\Box;
use MoonShine\UI\Components\Layout\Column;
@@ -28,7 +30,6 @@
use MoonShine\UI\Fields\Select;
use MoonShine\UI\Fields\Switcher;
use MoonShine\UI\Fields\Text;
-use MoonShine\Laravel\Collections\Fields;
#[Group('UI')]
#[Order(6)]
@@ -69,6 +70,8 @@ public function apply(CrudRequestContract $request): JsonResponse
'key-value' => $this->keyValueFields(),
'only-value' => $this->onlyValueFields(),
'object' => $this->objectFields(),
+ 'create-button-options' => $this->createButtonOptionsFields(),
+ 'display-options' => $this->displayOptionsFields(),
'mixed-object' => $this->mixedObjectFields(),
'mixed-default' => $this->mixedDefaultFields(),
default => $this->defaultFields(),
@@ -88,7 +91,7 @@ public function apply(CrudRequestContract $request): JsonResponse
return JsonResponse::make()
->html([
- '.after-apply-json' => "" . json_encode($data->getAttributes(), JSON_THROW_ON_ERROR) . ""
+ '.after-apply-json' => ''.json_encode($data->getAttributes(), JSON_THROW_ON_ERROR).'',
]);
}
@@ -153,6 +156,31 @@ public function components(): array
]),
])->columnSpan(6),
+ Column::make([
+ Box::make('Table (Preview)', [
+ $this->tableFields()
+ ->findByColumn('data')
+ ?->fillData($this->tableFill()),
+ ]),
+ ])->columnSpan(6),
+
+ Column::make([
+ Box::make('Create Button Options', [
+ $this->form(
+ $this->createButtonOptionsFields(),
+ ),
+ ]),
+ ])->columnSpan(6),
+
+ Column::make([
+ Box::make('Display Options', [
+ $this->form(
+ $this->displayOptionsFields(),
+ $this->displayOptionsFill(),
+ ),
+ ]),
+ ])->columnSpan(12),
+
Column::make([
Box::make('Mixed Object', [
$this->form(
@@ -172,9 +200,9 @@ public function components(): array
$this->mixedObjectFields()
->findByColumn('data')
?->previewMode()
- ?->fillData($this->mixedObjectFill())
+ ?->fillData($this->mixedObjectFill()),
]),
- ])->columnSpan(12),
+ ])->columnSpan(6),
Column::make([
Box::make('Mixed Default', [
@@ -189,19 +217,215 @@ public function components(): array
]),
])->columnSpan(12),
+ Column::make([
+ Box::make('Nested Table (Preview)', [
+
+ $this->nestedTableFields()
+ ->findByColumn('data')
+ ?->fillData($this->nestedTableFill()),
+ ]),
+ ])->columnSpan(12),
+
Column::make([
Box::make('Mixed Default (Preview)', [
$this->mixedDefaultFields()
->findByColumn('data')
?->previewMode()
- ?->fillData($this->mixedDefaultFill())
+ ?->fillData($this->mixedDefaultFill()),
]),
])->columnSpan(12),
]),
];
}
+ private function displayOptionsFields(): Fields
+ {
+ return Fields::make([
+ Hidden::make('_type')->setValue('display-options'),
+
+ Json::make('Vertical orientation', 'vertical_orientation')
+ ->fields([
+ Text::make('Title'),
+ Text::make('Value'),
+ ], 'vertical'),
+
+ Json::make('Reorderable', 'reorderable')
+ ->fields([
+ Text::make('Title'),
+ Text::make('Value'),
+ ])
+ ->reorderable(),
+
+ Json::make('Custom buttons', 'custom_buttons')
+ ->fields([
+ Text::make('Title'),
+ Text::make('Value'),
+ ])
+ ->buttons([
+ ActionButton::make('Remove')
+ ->icon('trash')
+ ->onClick(fn (): string => 'remove()', 'prevent')
+ ->error()
+ ->showInLine(),
+ ]),
+
+ Json::make('Custom empty message', 'custom_empty_message')
+ ->fields([
+ Text::make('Title'),
+ Text::make('Value'),
+ ])
+ ->emptyMessage('No demo rows'),
+ ]);
+ }
+
+ private function displayOptionsFill(): array
+ {
+ return [
+ 'vertical_orientation' => [
+ [
+ 'title' => 'Vertical row',
+ 'value' => 'Fields are stacked',
+ ],
+ ],
+ 'reorderable' => [
+ [
+ 'title' => 'First',
+ 'value' => 'Drag me',
+ ],
+ [
+ 'title' => 'Second',
+ 'value' => 'Drag me too',
+ ],
+ ],
+ 'custom_buttons' => [
+ [
+ 'title' => 'Custom action',
+ 'value' => 'Uses custom row button',
+ ],
+ ],
+ 'custom_empty_message' => [],
+ ];
+ }
+
+ private function createButtonOptionsFields(): Fields
+ {
+ return Fields::make([
+ Hidden::make('_type')->setValue('create-button-options'),
+
+ Json::make('Icon only with Limit', 'icon_only')
+ ->fields([
+ Text::make('Title'),
+ Text::make('Value'),
+ ])
+ ->creatable(limit: 2, showButtonText: false),
+
+ Json::make('Text only', 'text_only')
+ ->fields([
+ Text::make('Title'),
+ Text::make('Value'),
+ ])
+ ->creatable(showButtonIcon: false),
+
+ Json::make('Hidden add button', 'hidden_add_button')
+ ->fields([
+ Text::make('Title'),
+ Text::make('Value'),
+ ])
+ ->creatable(hideButton: true),
+ ]);
+ }
+
+ private function tableFields(): Fields
+ {
+ return Fields::make([
+ Json::make('Data')
+ ->fields([
+ Text::make('Title'),
+ Select::make('Status')->options([
+ 'draft' => 'Draft',
+ 'published' => 'Published',
+ ]),
+ Number::make('Stock')->nullable(),
+ Switcher::make('Active'),
+ ])
+ ->table(),
+ ]);
+ }
+
+ private function tableFill(): array
+ {
+ return [
+ 'data' => [
+ [
+ 'title' => 'First product',
+ 'status' => 'draft',
+ 'stock' => 10,
+ 'active' => true,
+ ],
+ [
+ 'title' => 'Second product',
+ 'status' => 'published',
+ 'stock' => 25,
+ 'active' => false,
+ ],
+ ],
+ ];
+ }
+
+ private function nestedTableFields(): Fields
+ {
+ return Fields::make([
+ Json::make('Data')
+ ->fields([
+ Text::make('Name'),
+
+ Json::make('Prices')
+ ->fields([
+ Number::make('Wholesale price'),
+ Number::make('Retail price'),
+ Switcher::make('Tax included'),
+ ])
+ ->object()
+ ->table(),
+
+ Json::make('Links')
+ ->fields([
+ Text::make('Label'),
+ Text::make('Url'),
+ ])
+ ->table(),
+ ])
+ ->table(),
+ ]);
+ }
+
+ private function nestedTableFill(): array
+ {
+ return [
+ 'data' => [
+ [
+ 'name' => 'Product 1',
+ 'prices' => [
+ 'wholesale_price' => 1000,
+ 'retail_price' => 1200,
+ 'tax_included' => true,
+ ],
+ 'links' => [
+ [
+ 'label' => 'Docs',
+ 'url' => 'https://moonshine-laravel.com',
+ ],
+ [
+ 'label' => 'GitHub',
+ 'url' => 'https://github.com/moonshine-software',
+ ],
+ ],
+ ],
+ ],
+ ];
+ }
+
private function defaultFields(): Fields
{
return Fields::make([
@@ -221,7 +445,7 @@ private function defaultFill(): array
'data' => [
['title' => 'Title 1', 'value' => 'Value 1'],
['title' => 'Title 2', 'value' => 'Value 2'],
- ]
+ ],
];
}
@@ -241,7 +465,7 @@ private function keyValueFill(): array
'key 1' => 'value 1',
'key 2' => 'value 2',
'key 3' => 'value 3',
- ]
+ ],
];
}
@@ -261,7 +485,7 @@ private function onlyValueFill(): array
'value 1',
'value 2',
'value 3',
- ]
+ ],
];
}
@@ -278,7 +502,7 @@ private function objectFields(): Fields
Text::make('One'),
Text::make('Two'),
Number::make('Number')->step(0.1)->nullable(),
- Switcher::make('Active')
+ Switcher::make('Active'),
])->object(),
])->object(),
]);
@@ -293,8 +517,8 @@ private function objectFill(): array
'inner' => [
'one' => 'One',
'two' => 'Two',
- ]
- ]
+ ],
+ ],
];
}
@@ -330,9 +554,9 @@ private function mixedObjectFill(): array
'key 1' => 'value 1',
'key 2' => 'value 2',
'key 3' => 'value 3',
- ]
- ]
- ]
+ ],
+ ],
+ ],
];
}
@@ -353,7 +577,7 @@ private function mixedDefaultFields(): Fields
Flex::make([
Text::make('One'),
Text::make('Two'),
- ])
+ ]),
]),
Select::make('Multiple')->options([1 => 1, 2 => 2, 3 => 3])->multiple(),
@@ -361,7 +585,7 @@ private function mixedDefaultFields(): Fields
Json::make('KV')->keyValue(),
])->object(),
])->object(),
- ])
+ ]),
]);
}
@@ -381,9 +605,9 @@ private function mixedDefaultFill(): array
'key 1' => 'value 1',
'key 2' => 'value 2',
'key 3' => 'value 3',
- ]
- ]
- ]
+ ],
+ ],
+ ],
],
[
'title' => 'Title 2',
@@ -397,11 +621,11 @@ private function mixedDefaultFill(): array
'key 1 2' => 'value 1 2',
'key 2 2' => 'value 2 2',
'key 3 2' => 'value 3 2',
- ]
- ]
- ]
- ]
- ]
+ ],
+ ],
+ ],
+ ],
+ ],
];
}