From aef1fcf9c21d99dc97199c9896c73f2cef4415e4 Mon Sep 17 00:00:00 2001 From: "Mr.VACO" Date: Sun, 5 Jul 2026 00:50:29 +0500 Subject: [PATCH] Added new variations of output and control of the JSON field --- app/MoonShine/Pages/UI/JsonPage.php | 272 +++++++++++++++++++++++++--- 1 file changed, 248 insertions(+), 24 deletions(-) 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', - ] - ] - ] - ] - ] + ], + ], + ], + ], + ], ]; }