From be0f58b6132b18813da7ab106315c2af6da05bbc Mon Sep 17 00:00:00 2001 From: matejkrenek Date: Sat, 31 Dec 2022 17:32:25 +0100 Subject: [PATCH] actions on pages and others --- config/admin.php | 130 ++++++++++----- routes/web.php | 148 ++++++++++-------- src/Actions/Concerns/CanHandleAction.php | 6 +- src/AdminManager.php | 2 +- src/Exceptions/ActionNotFoundException.php | 23 +++ src/Exceptions/WidgetNotFoundException.php | 23 +++ .../Controllers/{ => Auth}/AuthController.php | 6 +- .../MeController.php} | 12 +- .../Controllers/Builder/ActionController.php | 32 ++++ .../Controllers/Builder/PageController.php | 24 +++ .../Controllers/Builder/WidgetController.php | 28 ++++ src/Http/Controllers/BuilderController.php | 36 ----- src/Http/Controllers/PageController.php | 51 ------ src/Http/Controllers/ResourceController.php | 38 ----- .../{ => Settings}/SettingsController.php | 5 +- src/Http/Requests/{ => Auth}/LoginRequest.php | 2 +- .../MeUpdateRequest.php} | 4 +- .../Requests/Auth/MeUploadAvatarRequest.php | 30 ++++ .../Requests/Builder/BuildPageRequest.php | 31 ++++ .../Requests/Builder/BuildWidgetRequest.php | 31 ++++ .../Requests/Builder/CallActionRequest.php | 33 ++++ .../AdminSettingsUpdateRequest.php | 2 +- src/Pages/Page.php | 35 ++++- src/Tables/Concerns/HasColumns.php | 4 +- src/Tables/Table.php | 11 +- src/Widgets/AccountWidget.php | 9 ++ src/Widgets/TableWidget.php | 122 +++++++++++++++ src/Widgets/Widget.php | 36 +++++ 28 files changed, 652 insertions(+), 262 deletions(-) create mode 100644 src/Exceptions/ActionNotFoundException.php create mode 100644 src/Exceptions/WidgetNotFoundException.php rename src/Http/Controllers/{ => Auth}/AuthController.php (92%) rename src/Http/Controllers/{AdminUserController.php => Auth/MeController.php} (84%) create mode 100644 src/Http/Controllers/Builder/ActionController.php create mode 100644 src/Http/Controllers/Builder/PageController.php create mode 100644 src/Http/Controllers/Builder/WidgetController.php delete mode 100644 src/Http/Controllers/BuilderController.php delete mode 100644 src/Http/Controllers/PageController.php delete mode 100644 src/Http/Controllers/ResourceController.php rename src/Http/Controllers/{ => Settings}/SettingsController.php (96%) rename src/Http/Requests/{ => Auth}/LoginRequest.php (98%) rename src/Http/Requests/{AdminUserUpdateRequest.php => Auth/MeUpdateRequest.php} (93%) create mode 100644 src/Http/Requests/Auth/MeUploadAvatarRequest.php create mode 100644 src/Http/Requests/Builder/BuildPageRequest.php create mode 100644 src/Http/Requests/Builder/BuildWidgetRequest.php create mode 100644 src/Http/Requests/Builder/CallActionRequest.php rename src/Http/Requests/{ => Settings}/AdminSettingsUpdateRequest.php (96%) create mode 100644 src/Widgets/TableWidget.php diff --git a/config/admin.php b/config/admin.php index 69c1c49..09023a2 100644 --- a/config/admin.php +++ b/config/admin.php @@ -9,50 +9,8 @@ 'favicon' => null, - 'prefix' => 'admin', - - 'prefix_name' => 'admin', - - 'middleware' => ['api'], - 'auth' => [ 'guard' => 'admin', - 'routes' => [ - 'login' => [ - 'url' => '/auth/login', - 'name' => 'auth.login', - 'middleware' => ['guest:admin'] - ], - 'logout' => [ - 'url' => '/auth/logout', - 'name' => 'auth.logout', - 'middleware' => ['auth:admin'] - ], - 'me' => [ - 'url' => '/auth/me', - 'name' => 'auth.me', - 'middleware' => ['auth:admin'] - ], - 'token' => [ - 'url' => '/auth/token', - 'name' => 'auth.token', - 'middleware' => [] - ] - ] - ], - - 'builder' => [ - 'url' => '/builder', - 'name' => 'builder', - 'middleware' => [ - Bengr\Admin\Http\Middleware\DispatchServingAdminEvent::class, - ] - ], - - 'resources' => [ - 'url' => '/resources', - 'name' => 'resources', - 'middleware' => [] ], 'pages' => [ @@ -74,5 +32,91 @@ 'sort_order' => 'sort_order' ] ] - ] + ], + + 'routes' => [ + 'url' => '/admin', + 'name' => 'admin', + 'middleware' => ['api'], + 'routes' => [ + 'auth' => [ + 'url' => '/auth', + 'name' => 'auth', + 'middleware' => [], + 'routes' => [ + 'login' => [ + 'url' => '/login', + 'name' => 'login', + 'middleware' => ['guest:admin'] + ], + 'logout' => [ + 'url' => '/logout', + 'name' => 'logout', + 'middleware' => ['auth:admin'] + ], + 'me' => [ + 'url' => '/me', + 'name' => 'me', + 'middleware' => ['auth:admin'] + ], + 'me-avatar' => [ + 'url' => '/me/avatar', + 'name' => 'me.avatar', + 'middleware' => ['auth:admin'] + ], + 'token' => [ + 'url' => '/token', + 'name' => 'token', + 'middleware' => [] + ] + ] + ], + 'settings' => [ + 'url' => '/settings', + 'name' => 'settings', + 'middleware' => ['auth:admin'], + 'routes' => [ + 'settings' => [ + 'url' => '/', + 'name' => 'index', + 'middleware' => [] + ], + 'socials-delete' => [ + 'url' => '/socials/{id}', + 'name' => 'socials.delete', + 'middleware' => [] + ], + 'languages-delete' => [ + 'url' => '/languages/{id}', + 'name' => 'languages.delete', + 'middleware' => [] + ] + ] + ], + 'builder' => [ + 'url' => '/builder', + 'name' => 'builder', + 'middleware' => [ + Bengr\Admin\Http\Middleware\DispatchServingAdminEvent::class, + ], + 'routes' => [ + 'pages' => [ + 'url' => '/pages', + 'name' => 'pages', + 'middleware' => [] + ], + 'widgets' => [ + 'url' => '/widgets', + 'name' => 'widgets', + 'middleware' => [] + ], + 'actions' => [ + 'url' => '/actions', + 'name' => 'actions', + 'middleware' => [] + ] + ] + ], + ] + ], ]; diff --git a/routes/web.php b/routes/web.php index b8eddaa..25e325d 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,74 +1,86 @@ middleware(config('admin.middleware')) - ->name(config('admin.prefix_name') . '.') +Route::prefix(config('admin.routes.url')) + ->name(config('admin.routes.name') . '.') + ->middleware(config('admin.routes.middleware')) ->group(function () { - Route::get(config('admin.builder.url'), BuilderController::class) - ->name(config('admin.builder.name')) - ->middleware(config('admin.builder.middleware')); - - Route::get(config('admin.resources.url'), [ResourceController::class, 'get']) - ->name(config('admin.resources.name')) - ->middleware(config('admin.resources.middleware')); - - Route::post(config('admin.auth.routes.login.url'), [AuthController::class, 'login']) - ->name(config('admin.auth.routes.login.name')) - ->middleware(config('admin.auth.routes.login.middleware')); - - Route::post(config('admin.auth.routes.logout.url'), [AuthController::class, 'logout']) - ->name(config('admin.auth.routes.logout.name')) - ->middleware(config('admin.auth.routes.logout.middleware')); - - Route::get(config('admin.auth.routes.me.url'), [AdminUserController::class, 'me']) - ->name(config('admin.auth.routes.me.name')) - ->middleware(config('admin.auth.routes.me.middleware')); - - Route::post(config('admin.auth.routes.me.url'), [AdminUserController::class, 'update']) - ->name(config('admin.auth.routes.me.name')) - ->middleware(config('admin.auth.routes.me.middleware')); - - Route::post(config('admin.auth.routes.me.url') . '/avatar', [AdminUserController::class, 'uploadAvatar']) - ->name(config('admin.auth.routes.me.name') . '.avatar') - ->middleware(config('admin.auth.routes.me.middleware')); - - Route::delete(config('admin.auth.routes.me.url') . '/avatar', [AdminUserController::class, 'deleteAvatar']) - ->name(config('admin.auth.routes.me.name') . '.avatar') - ->middleware(config('admin.auth.routes.me.middleware')); - - Route::get(config('admin.auth.routes.token.url'), [AuthController::class, 'token']) - ->name(config('admin.auth.routes.token.name')) - ->middleware(config('admin.auth.routes.token.middleware')); - - Route::get('/settings', [SettingsController::class, 'index']) - ->name('admin.settings') - ->middleware(['auth:admin']); - - Route::post('/settings', [SettingsController::class, 'update']) - ->name('admin.settings') - ->middleware(['auth:admin']); - - Route::get('/pages', [PageController::class, 'build']) - ->name('admin.pages.build') - ->middleware(); - - Route::get('/pages', [PageController::class, 'performAction']) - ->name('admin.pages.action') - ->middleware(); - - Route::delete('/settings/socials/{social}', [SettingsController::class, 'deleteSocial']) - ->name('admin.settings.socials.detail') - ->middleware(['auth:admin']); - - Route::delete('/settings/languages/{language}', [SettingsController::class, 'deleteLanguage']) - ->name('admin.settings.languages.detail') - ->middleware(['auth:admin']); + Route::prefix(config('admin.routes.routes.auth.url')) + ->name(config('admin.routes.routes.auth.name') . '.') + ->middleware(config('admin.routes.routes.auth.middleware')) + ->group(function () { + + Route::post(config('admin.routes.routes.auth.routes.login.url'), [AuthController::class, 'login']) + ->name(config('admin.routes.routes.auth.routes.login.name')) + ->middleware(config('admin.routes.routes.auth.routes.login.middleware')); + + Route::post(config('admin.routes.routes.auth.routes.logout.url'), [AuthController::class, 'logout']) + ->name(config('admin.routes.routes.auth.routes.logout.name')) + ->middleware(config('admin.routes.routes.auth.routes.logout.middleware')); + + Route::get(config('admin.routes.routes.auth.routes.token.url'), [AuthController::class, 'token']) + ->name(config('admin.routes.routes.auth.routes.token.name')) + ->middleware(config('admin.routes.routes.auth.routes.token.middleware')); + + Route::get(config('admin.routes.routes.auth.routes.me.url'), [MeController::class, 'me']) + ->name(config('admin.routes.routes.auth.routes.me.name')) + ->middleware(config('admin.routes.routes.auth.routes.me.middleware')); + + Route::put(config('admin.routes.routes.auth.routes.me.url'), [MeController::class, 'update']) + ->name(config('admin.routes.routes.auth.routes.me.name')) + ->middleware(config('admin.routes.routes.auth.routes.me.middleware')); + + Route::post(config('admin.routes.routes.auth.routes.me-avatar.url'), [MeController::class, 'uploadAvatar']) + ->name(config('admin.routes.routes.auth.routes.me-avatar.name')) + ->middleware(config('admin.routes.routes.auth.routes.me-avatar.middleware')); + + Route::delete(config('admin.routes.routes.auth.routes.me-avatar.url'), [MeController::class, 'deleteAvatar']) + ->name(config('admin.routes.routes.auth.routes.me-avatar.name')) + ->middleware(config('admin.routes.routes.auth.routes.me-avatar.middleware')); + }); + + Route::prefix(config('admin.routes.routes.settings.url')) + ->name(config('admin.routes.routes.settings.name') . '.') + ->middleware(config('admin.routes.routes.settings.middleware')) + ->group(function () { + Route::get(config('admin.routes.routes.settings.routes.settings.url'), [SettingsController::class, 'index']) + ->name(config('admin.routes.routes.settings.routes.settings.name')) + ->middleware(config('admin.routes.routes.settings.routes.settings.middleware')); + + Route::put(config('admin.routes.routes.settings.routes.settings.url'), [SettingsController::class, 'update']) + ->name(config('admin.routes.routes.settings.routes.settings.name')) + ->middleware(config('admin.routes.routes.settings.routes.settings.middleware')); + + Route::delete(config('admin.routes.routes.settings.routes.socials-delete.url'), [SettingsController::class, 'deleteSocial']) + ->name(config('admin.routes.routes.settings.routes.socials-delete.name')) + ->middleware(config('admin.routes.routes.settings.routes.socials-delete.middleware')); + + Route::delete(config('admin.routes.routes.settings.routes.languages-delete.url'), [SettingsController::class, 'deleteLanguage']) + ->name(config('admin.routes.routes.settings.routes.languages-delete.name')) + ->middleware(config('admin.routes.routes.settings.routes.languages-delete.middleware')); + }); + + Route::prefix(config('admin.routes.routes.builder.url')) + ->name(config('admin.routes.routes.builder.name') . '.') + ->middleware(config('admin.routes.routes.builder.middleware')) + ->group(function () { + Route::get(config('admin.routes.routes.builder.routes.pages.url'), [PageController::class, 'build']) + ->name(config('admin.routes.routes.builder.routes.pages.name')) + ->middleware(config('admin.routes.routes.builder.routes.pages.middleware')); + + Route::get(config('admin.routes.routes.builder.routes.widgets.url'), [WidgetController::class, 'build']) + ->name(config('admin.routes.routes.builder.routes.widgets.name')) + ->middleware(config('admin.routes.routes.builder.routes.widgets.middleware')); + + Route::post(config('admin.routes.routes.builder.routes.actions.url'), [ActionController::class, 'call']) + ->name(config('admin.routes.routes.builder.routes.actions.name')) + ->middleware(config('admin.routes.routes.builder.routes.actions.middleware')); + }); }); diff --git a/src/Actions/Concerns/CanHandleAction.php b/src/Actions/Concerns/CanHandleAction.php index 87663fc..1e598ae 100644 --- a/src/Actions/Concerns/CanHandleAction.php +++ b/src/Actions/Concerns/CanHandleAction.php @@ -4,7 +4,6 @@ trait CanHandleAction { - protected ?\Closure $handleMethod = null; public function handle(\Closure $method): static @@ -14,6 +13,11 @@ public function handle(\Closure $method): static return $this; } + public function hasHandle() + { + return $this->handleMethod ? true : false; + } + public function getHandleMethod(): ?\Closure { return $this->handleMethod; diff --git a/src/AdminManager.php b/src/AdminManager.php index a99c866..23d69ff 100644 --- a/src/AdminManager.php +++ b/src/AdminManager.php @@ -40,7 +40,7 @@ public function authUserModel(): string public function prefix(): string { - return config('admin.prefix'); + return Str::of(config('admin.routes.url'))->ltrim('/')->value(); } public function loginPage(): ?Page diff --git a/src/Exceptions/ActionNotFoundException.php b/src/Exceptions/ActionNotFoundException.php new file mode 100644 index 0000000..e7d3143 --- /dev/null +++ b/src/Exceptions/ActionNotFoundException.php @@ -0,0 +1,23 @@ +json([ + 'message' => 'Action not found', + 'redirect' => $dashboard ? [ + 'url' => $dashboard->getRouteUrl(), + 'name' => $dashboard->getRouteName() + ] : null + ])->status(404); + } +} diff --git a/src/Exceptions/WidgetNotFoundException.php b/src/Exceptions/WidgetNotFoundException.php new file mode 100644 index 0000000..24e097d --- /dev/null +++ b/src/Exceptions/WidgetNotFoundException.php @@ -0,0 +1,23 @@ +json([ + 'message' => 'Widget not found', + 'redirect' => $dashboard ? [ + 'url' => $dashboard->getRouteUrl(), + 'name' => $dashboard->getRouteName() + ] : null + ])->status(404); + } +} diff --git a/src/Http/Controllers/AuthController.php b/src/Http/Controllers/Auth/AuthController.php similarity index 92% rename from src/Http/Controllers/AuthController.php rename to src/Http/Controllers/Auth/AuthController.php index 52797db..4229e34 100644 --- a/src/Http/Controllers/AuthController.php +++ b/src/Http/Controllers/Auth/AuthController.php @@ -1,9 +1,10 @@ authenticate(); $token = $admin->createToken('bengr-admin-token'); diff --git a/src/Http/Controllers/AdminUserController.php b/src/Http/Controllers/Auth/MeController.php similarity index 84% rename from src/Http/Controllers/AdminUserController.php rename to src/Http/Controllers/Auth/MeController.php index 6d98647..7015705 100644 --- a/src/Http/Controllers/AdminUserController.php +++ b/src/Http/Controllers/Auth/MeController.php @@ -1,9 +1,11 @@ user(Admin::getGuardName()); @@ -56,7 +58,7 @@ public function update(AdminUserUpdateRequest $request) ]); } - public function uploadAvatar(Request $request) + public function uploadAvatar(MeUploadAvatarRequest $request) { if ($request->has('image')) { $request->user(Admin::getGuardName())->addMediaFromRequest('image')->usingFileName('avatar.jpg')->toMediaCollection('avatar'); diff --git a/src/Http/Controllers/Builder/ActionController.php b/src/Http/Controllers/Builder/ActionController.php new file mode 100644 index 0000000..cec13bd --- /dev/null +++ b/src/Http/Controllers/Builder/ActionController.php @@ -0,0 +1,32 @@ +get('url')); + + if (!$page) return response()->throw(PageNotFoundException::class); + + if ($request->has('widget_id')) { + $widget = $page->getWidget($request->get('widget_id')); + + if (!$widget) return response()->throw(WidgetNotFoundException::class); + + return $page->processToResponse($request, fn () => $widget->callAction($request->get('name'), $request->get('payload', []))); + } + + return $page->processToResponse($request, fn () => $page->callAction($request->get('name'), $request->get('payload', []))); + } +} diff --git a/src/Http/Controllers/Builder/PageController.php b/src/Http/Controllers/Builder/PageController.php new file mode 100644 index 0000000..324b8c6 --- /dev/null +++ b/src/Http/Controllers/Builder/PageController.php @@ -0,0 +1,24 @@ +get('url')); + + if (!$page) return response()->throw(PageNotFoundException::class); + + return $page->processToResponse($request, fn () => response()->resource(PageResource::class, $page)); + } +} diff --git a/src/Http/Controllers/Builder/WidgetController.php b/src/Http/Controllers/Builder/WidgetController.php new file mode 100644 index 0000000..0f0dd21 --- /dev/null +++ b/src/Http/Controllers/Builder/WidgetController.php @@ -0,0 +1,28 @@ +get('url')); + + if (!$page) return response()->throw(PageNotFoundException::class); + + $widget = $page->getWidget($request->get('widget_id')); + + if (!$widget) return response()->throw(WidgetNotFoundException::class); + + return $page->processToResponse($request, fn () => response()->resource(WidgetResource::class, $widget)); + } +} diff --git a/src/Http/Controllers/BuilderController.php b/src/Http/Controllers/BuilderController.php deleted file mode 100644 index c7fa48b..0000000 --- a/src/Http/Controllers/BuilderController.php +++ /dev/null @@ -1,36 +0,0 @@ -get('url')); - - if (!$page) { - return response()->throw(PageNotFoundException::class); - } - - return $page->processToResponse($request, fn () => response()->resource(PageResource::class, $page)); - } -} diff --git a/src/Http/Controllers/PageController.php b/src/Http/Controllers/PageController.php deleted file mode 100644 index cfbe272..0000000 --- a/src/Http/Controllers/PageController.php +++ /dev/null @@ -1,51 +0,0 @@ -get('url')); - - if (!$page) { - return response()->throw(PageNotFoundException::class); - } - - return $page->processToResponse($request, fn () => response()->resource(PageResource::class, $page)); - } - - /** - * Perform action on page - * - */ - public function performAction(Request $request) - { - $page = BengrAdmin::getPageByUrl($request->get('url')); - - if (!$page) { - return response()->throw(PageNotFoundException::class); - } - - return $page->callAction($request, 'create'); - } -} diff --git a/src/Http/Controllers/ResourceController.php b/src/Http/Controllers/ResourceController.php deleted file mode 100644 index d092155..0000000 --- a/src/Http/Controllers/ResourceController.php +++ /dev/null @@ -1,38 +0,0 @@ -has('url') || !$request->has('widget_id')) return response()->throw(NotFoundHttpException::class); - - $page = BengrAdmin::getPageByUrl($request->get('url')); - - if (!$page || !$page->hasWidget($request->get('widget_id'))) return response()->throw(NotFoundHttpException::class); - - - return $page->processToResponse($request, fn () => response()->resource(WidgetResource::class, $page->getWidget($request->get('widget_id')))); - } -} diff --git a/src/Http/Controllers/SettingsController.php b/src/Http/Controllers/Settings/SettingsController.php similarity index 96% rename from src/Http/Controllers/SettingsController.php rename to src/Http/Controllers/Settings/SettingsController.php index 33e3530..601f8c5 100644 --- a/src/Http/Controllers/SettingsController.php +++ b/src/Http/Controllers/Settings/SettingsController.php @@ -1,8 +1,9 @@ + */ + public function rules() + { + return [ + 'image' => ['required', 'image', 'max:1024'] + ]; + } +} diff --git a/src/Http/Requests/Builder/BuildPageRequest.php b/src/Http/Requests/Builder/BuildPageRequest.php new file mode 100644 index 0000000..247ca90 --- /dev/null +++ b/src/Http/Requests/Builder/BuildPageRequest.php @@ -0,0 +1,31 @@ + + */ + public function rules() + { + + return [ + 'url' => ['required'], + ]; + } +} diff --git a/src/Http/Requests/Builder/BuildWidgetRequest.php b/src/Http/Requests/Builder/BuildWidgetRequest.php new file mode 100644 index 0000000..832a920 --- /dev/null +++ b/src/Http/Requests/Builder/BuildWidgetRequest.php @@ -0,0 +1,31 @@ + + */ + public function rules() + { + return [ + 'url' => ['required'], + 'widget_id' => ['required', 'int'] + ]; + } +} diff --git a/src/Http/Requests/Builder/CallActionRequest.php b/src/Http/Requests/Builder/CallActionRequest.php new file mode 100644 index 0000000..79e035a --- /dev/null +++ b/src/Http/Requests/Builder/CallActionRequest.php @@ -0,0 +1,33 @@ + + */ + public function rules() + { + return [ + 'url' => ['required'], + 'widget_id' => ['nullable', 'int'], + 'name' => ['required', 'string'], + 'payload' => ['nullable', 'array'] + ]; + } +} diff --git a/src/Http/Requests/AdminSettingsUpdateRequest.php b/src/Http/Requests/Settings/AdminSettingsUpdateRequest.php similarity index 96% rename from src/Http/Requests/AdminSettingsUpdateRequest.php rename to src/Http/Requests/Settings/AdminSettingsUpdateRequest.php index bd67a8a..d42c1c1 100644 --- a/src/Http/Requests/AdminSettingsUpdateRequest.php +++ b/src/Http/Requests/Settings/AdminSettingsUpdateRequest.php @@ -1,6 +1,6 @@ getWidget($id) ? true : false; } - public function getWidget(int $id): ?Widget + public function getWidget(?int $id): ?Widget { $this->transformed_widgets = collect([]); @@ -289,12 +293,29 @@ public function hasTopbar(): bool return $this->hasTopbar; } - public function callAction(Request $request, string $name) + protected function loopActions(array $actions) { - return collect($this->getActions())->where(function ($action) use ($name) { - if (!$action instanceof ActionGroup) { - return $action->getName() === $name; + collect($actions)->map(function ($action) { + if ($action instanceof ActionGroup) { + $this->loopActions($action->getActions()); + } else { + $this->transformed_actions->push($action); } - })->first()->getHandleMethod()($request); + }); + } + + public function callAction(string $name, array $payload = []) + { + $this->transformed_actions = collect([]); + + $this->loopActions($this->getActions()); + + $action = $this->transformed_actions->where(function (Action $action) use ($name) { + return $action->getName() === $name && $action->hasHandle(); + })->first(); + + if (!$action) return response()->throw(ActionNotFoundException::class); + + return $action->getHandleMethod()($payload); } } diff --git a/src/Tables/Concerns/HasColumns.php b/src/Tables/Concerns/HasColumns.php index b3e9fb1..84346a3 100644 --- a/src/Tables/Concerns/HasColumns.php +++ b/src/Tables/Concerns/HasColumns.php @@ -10,8 +10,10 @@ trait HasColumns public function getCachedTableColumns(): array { + $this->cachedTableColumns = []; + foreach ($this->getTableColumns() as $column) { - $this->cachedTableColumns[$column->getName()] = $column; + $this->cachedTableColumns[] = $column; } return $this->cachedTableColumns; diff --git a/src/Tables/Table.php b/src/Tables/Table.php index 7eddb56..7b2a577 100644 --- a/src/Tables/Table.php +++ b/src/Tables/Table.php @@ -53,16 +53,21 @@ public function getRecordsInColumns(): SupportCollection foreach ($this->getRecords() as $record) { $record_in_column = collect([ - 'id' => $record->id + 'id' => $record->id, ]); + $columns = []; + foreach ($this->getColumns() as $column) { - $record_in_column->put($column->getName(), [ + $columns[] = [ + 'name' => $column->getName(), 'value' => Arr::get($record, $column->getName()), 'params' => [] - ]); + ]; } + $record_in_column->put('columns', $columns); + $record_in_column->put('actions', ActionGroupResource::collection($this->getActions())); diff --git a/src/Widgets/AccountWidget.php b/src/Widgets/AccountWidget.php index 0f10b07..f996e2e 100644 --- a/src/Widgets/AccountWidget.php +++ b/src/Widgets/AccountWidget.php @@ -2,6 +2,8 @@ namespace Bengr\Admin\Widgets; +use Bengr\Admin\Actions\Action; + class AccountWidget extends Widget { protected ?string $name = 'account'; @@ -16,4 +18,11 @@ public static function make(): static { return app(static::class); } + + public function getActions(): array + { + return [ + Action::make('create')->handle(fn ($payload) => dd($payload)) + ]; + } } diff --git a/src/Widgets/TableWidget.php b/src/Widgets/TableWidget.php new file mode 100644 index 0000000..aa261f7 --- /dev/null +++ b/src/Widgets/TableWidget.php @@ -0,0 +1,122 @@ +model = $model; + } + + public static function make(string $model): static + { + return app(static::class, ['model' => $model]); + } + + public function columns(array $columns): self + { + $this->columns = $columns; + + return $this; + } + + public function actions(array $actions): self + { + $this->actions = $actions; + + return $this; + } + + public function bulkActions(array $bulkActions): self + { + $this->bulkActions = $bulkActions; + + return $this; + } + + protected function getTableColumns() + { + return $this->columns ?? []; + } + + protected function getTableActions(): array + { + return $this->actions ?? []; + } + + protected function getTableBulkActions(): array + { + return $this->bulkActions ?? []; + } + + protected function getTableModel() + { + return $this->model; + } + + protected function loopActions(array $actions) + { + collect($actions)->map(function ($action) { + if ($action instanceof ActionGroup) { + $this->loopActions($action->getActions()); + } else { + $this->transformed_actions->push($action); + } + }); + } + + public function callAction(string $name, array $payload = []) + { + $this->transformed_actions = collect([]); + + $this->loopActions($this->getTableActions()); + + $action = $this->transformed_actions->where(function (Action $action) use ($name) { + return $action->getName() === $name && $action->hasHandle(); + })->first(); + + if (!$action) return response()->throw(ActionNotFoundException::class); + + Validator::make($payload, [ + 'id' => ['required', Rule::exists($this->getTableModel(), 'id')] + ])->validate(); + + return $action->getHandleMethod()(app($this->getTableModel())->find($payload['id']), $payload); + } + + + public function getData(Request $request): array + { + $table = $this->getTable($request); + return [ + 'bulkActions' => ActionGroupResource::collection($table->getBulkActions()), + 'columns' => ColumnResource::collection($table->getColumns()), + 'records' => $table->getRecordsInColumns(), + 'pagination' => $table->getPagination() + ]; + } +} diff --git a/src/Widgets/Widget.php b/src/Widgets/Widget.php index 1e9b169..5b30e08 100644 --- a/src/Widgets/Widget.php +++ b/src/Widgets/Widget.php @@ -2,9 +2,14 @@ namespace Bengr\Admin\Widgets; +use Bengr\Admin\Actions\Action; +use Bengr\Admin\Actions\ActionGroup; +use Bengr\Admin\Exceptions\ActionNotFoundException; use Illuminate\Http\Request; use Illuminate\Support\Str; +use function Bengr\Support\response; + class Widget { protected ?int $sort = null; @@ -68,6 +73,37 @@ public function getWidgets(): array return []; } + public function getActions(): array + { + return []; + } + + protected function loopActions(array $actions) + { + collect($actions)->map(function ($action) { + if ($action instanceof ActionGroup) { + $this->loopActions($action->getActions()); + } else { + $this->transformed_actions->push($action); + } + }); + } + + public function callAction(string $name, array $payload = []) + { + $this->transformed_actions = collect([]); + + $this->loopActions($this->getActions()); + + $action = $this->transformed_actions->where(function (Action $action) use ($name) { + return $action->getName() === $name && $action->hasHandle(); + })->first(); + + if (!$action) return response()->throw(ActionNotFoundException::class); + + return $action->getHandleMethod()($payload); + } + public function getData(Request $request): ?array { return null;