From 53a07fd4daf2bf4ed1767e91dac6f4dcaccd5cae Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 13 Jul 2019 20:20:35 +0200 Subject: [PATCH] Draft dashboard panels/boards/components per user --- Admin/Install/db.json | 65 +++++++ Admin/Installer.php | 15 ++ Admin/Routes/Web/Api.php | 31 ++++ Controller/ApiController.php | 168 +++++++++++++++++++ Controller/BackendController.php | 24 ++- Models/DashboardBoard.php | 252 ++++++++++++++++++++++++++++ Models/DashboardBoardMapper.php | 86 ++++++++++ Models/DashboardBoardStatus.php | 31 ++++ Models/DashboardComponent.php | 204 ++++++++++++++++++++++ Models/DashboardComponentMapper.php | 73 ++++++++ Models/NullDashboardBoard.php | 28 ++++ Models/NullDashboardComponent.php | 28 ++++ Models/PermissionState.php | 2 + 13 files changed, 1002 insertions(+), 5 deletions(-) create mode 100644 Admin/Install/db.json create mode 100644 Admin/Routes/Web/Api.php create mode 100644 Controller/ApiController.php create mode 100644 Models/DashboardBoard.php create mode 100644 Models/DashboardBoardMapper.php create mode 100644 Models/DashboardBoardStatus.php create mode 100644 Models/DashboardComponent.php create mode 100644 Models/DashboardComponentMapper.php create mode 100644 Models/NullDashboardBoard.php create mode 100644 Models/NullDashboardComponent.php diff --git a/Admin/Install/db.json b/Admin/Install/db.json new file mode 100644 index 0000000..d107bd8 --- /dev/null +++ b/Admin/Install/db.json @@ -0,0 +1,65 @@ +{ + "dashboard_board": { + "name": "dashboard_board", + "fields": { + "dashboard_board_id": { + "name": "dashboard_board_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "dashboard_board_title": { + "name": "dashboard_board_title", + "type": "VARCHAR(255)", + "null": false + }, + "dashboard_board_status": { + "name": "dashboard_board_status", + "type": "TINYINT", + "null": false + }, + "dashboard_board_account": { + "name": "dashboard_board_account", + "type": "INT", + "null": true, + "foreignTable": "account", + "foreignKey": "account_id" + } + } + }, + "dashboard_component": { + "name": "dashboard_component", + "fields": { + "dashboard_component_id": { + "name": "dashboard_component_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "dashboard_component_order": { + "name": "dashboard_component_order", + "type": "INT", + "null": false + }, + "dashboard_component_module": { + "name": "dashboard_component_module", + "type": "VARCHAR(255)", + "null": false + }, + "dashboard_component_component": { + "name": "dashboard_component_component", + "type": "VARCHAR(255)", + "null": false + }, + "dashboard_component_board": { + "name": "dashboard_component_board", + "type": "INT", + "null": false, + "foreignTable": "dashboard_board", + "foreignKey": "dashboard_board_id" + } + } + } +} \ No newline at end of file diff --git a/Admin/Installer.php b/Admin/Installer.php index 0c51b7d..bc26fa6 100644 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -14,6 +14,11 @@ declare(strict_types=1); namespace Modules\Dashboard\Admin; +use Modules\Dashboard\Models\DashboardBoard; +use Modules\Dashboard\Models\DashboardBoardMapper; +use phpOMS\DataStorage\Database\DatabasePool; + +use phpOMS\Module\InfoManager; use phpOMS\Module\InstallerAbstract; /** @@ -26,4 +31,14 @@ use phpOMS\Module\InstallerAbstract; */ class Installer extends InstallerAbstract { + /** + * {@inheritdoc} + */ + public static function install(DatabasePool $dbPool, InfoManager $info) : void + { + parent::install($dbPool, $info); + + $board = new DashboardBoard(); + DashboardBoardMapper::create($board); + } } diff --git a/Admin/Routes/Web/Api.php b/Admin/Routes/Web/Api.php new file mode 100644 index 0000000..3cb9ab8 --- /dev/null +++ b/Admin/Routes/Web/Api.php @@ -0,0 +1,31 @@ + [ + [ + 'dest' => '\Modules\Dashboard\Controller\ApiController:apiBoardCreate', + 'verb' => RouteVerb::PUT, + 'permission' => [ + 'module' => ApiController::MODULE_NAME, + 'type' => PermissionType::CREATE, + 'state' => PermissionState::BOARD, + ], + ], + ], + '^.*/dashboard/board/component(\?.*|$)' => [ + [ + 'dest' => '\Modules\Dashboard\Controller\ApiController:apiComponentAdd', + 'verb' => RouteVerb::PUT, + 'permission' => [ + 'module' => ApiController::MODULE_NAME, + 'type' => PermissionType::CREATE, + 'state' => PermissionState::COMPONENT, + ], + ], + ], +]; diff --git a/Controller/ApiController.php b/Controller/ApiController.php new file mode 100644 index 0000000..a61255b --- /dev/null +++ b/Controller/ApiController.php @@ -0,0 +1,168 @@ + Returns the validation array of the request + * + * @since 1.0.0 + */ + private function validateBoardCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['title'] = empty($request->getData('title'))) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create a board + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBoardCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void + { + if (!empty($val = $this->validateBoardCreate($request))) { + $response->set($request->getUri()->__toString(), new FormValidation($val)); + + return; + } + + $board = $this->createBoardFromRequest($request); + $this->createModel($request->getHeader()->getAccount(), $board, DashboardBoardMapper::class, 'board'); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Board', 'Board successfully created.', $board); + } + + /** + * Method to create board from request. + * + * @param RequestAbstract $request Request + * + * @return DashboardBoard Returns the created board from the request + * + * @since 1.0.0 + */ + private function createBoardFromRequest(RequestAbstract $request) : DashboardBoard + { + $board = new DashboardBoard(); + $board->setTitle((string) ($request->getData('title') ?? '')); + $board->setAccount($request->getHeader()->getAccount()); + $board->setStatus(DashboardBoardStatus::ACTIVE); + + return $board; + } + + /** + * Validate component create request + * + * @param RequestAbstract $request Request + * + * @return array Returns the validation array of the request + * + * @since 1.0.0 + */ + private function validateComponentCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['board'] = empty($request->getData('board'))) + || ($val['module'] = empty($request->getData('module'))) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create a component + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiComponentCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void + { + if (!empty($val = $this->validateComponentCreate($request))) { + $response->set($request->getUri()->__toString(), new FormValidation($val)); + + return; + } + + $component = $this->createComponentFromRequest($request); + $this->createModel($request->getHeader()->getAccount(), $component, DashboardComponentMapper::class, 'component'); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Component', 'Component successfully created.', $component); + } + + /** + * Method to create board from request. + * + * @param RequestAbstract $request Request + * + * @return DashboardComponent Returns the created board from the request + * + * @since 1.0.0 + */ + private function createComponentFromRequest(RequestAbstract $request) : DashboardComponent + { + $component = new DashboardComponent(); + $component->setBoard((int) ($request->getData('board') ?? 0)); + $component->setOrder((int) ($request->getData('order') ?? 0)); + $component->setModule((string) ($request->getData('module') ?? '')); + + return $component; + } +} diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 7bd4755..9b08cc6 100644 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -14,8 +14,11 @@ declare(strict_types=1); namespace Modules\Dashboard\Controller; +use Modules\Dashboard\Models\DashboardBoardMapper; +use Modules\Dashboard\Models\NullDashboardBoard; use phpOMS\Contract\RenderableInterface; use phpOMS\Message\RequestAbstract; + use phpOMS\Message\ResponseAbstract; use phpOMS\Views\View; @@ -45,11 +48,22 @@ final class BackendController extends Controller $view->setTemplate('/Modules/Dashboard/Theme/Backend/dashboard'); $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1000301001, $request, $response)); - $view->addData('panels', [ - //$this->app->moduleManager->get('News')->viewDashboard($request, $response, $data), - //$this->app->moduleManager->get('Tasks')->viewDashboard($request, $response, $data), - //$this->app->moduleManager->get('Calendar')->viewDashboard($request, $response, $data), - ]); + $board = DashboardBoardMapper::getFor($request->getHeader()->getAccount(), 'account'); + + if ($board instanceof NullDashboardBoard) { + $board = DashboardBoardMapper::get(1); + } + + $panels = []; + $boardComponents = $board->getComponents(); + + foreach ($boardComponents as $component) { + $panels[] = $this->app->moduleManager + ->get($component->getModule()) + ->viewDashboard($request, $response, $data); + } + + $view->addData('panels', $panels); return $view; } diff --git a/Models/DashboardBoard.php b/Models/DashboardBoard.php new file mode 100644 index 0000000..3f02014 --- /dev/null +++ b/Models/DashboardBoard.php @@ -0,0 +1,252 @@ +id; + } + + /** + * Get account + * + * @return null|int + * + * @since 1.0.0 + */ + public function getAccount() + { + return $this->account; + } + + /** + * Set account + * + * @param mixed $id Account + * + * @return void + * + * @since 1.0.0 + */ + public function setAccount($id) : void + { + $this->account = $id; + } + + /** + * Get title + * + * @return string + * + * @since 1.0.0 + */ + public function getTitle() : string + { + return $this->title; + } + + /** + * Set title + * + * @param string $title Title + * + * @return void + * + * @since 1.0.0 + */ + public function setTitle(string $title) : void + { + $this->title = $title; + } + + /** + * Get status + * + * @return int + * + * @since 1.0.0 + */ + public function getStatus() : int + { + return $this->status; + } + + /** + * Set status + * + * @param int $status Task status + * + * @return void + * + * @throws InvalidEnumValue + * + * @since 1.0.0 + */ + public function setStatus(int $status) : void + { + if (!DashboardBoardStatus::isValidValue($status)) { + throw new InvalidEnumValue((string) $status); + } + + $this->status = $status; + } + + /** + * Adding board component. + * + * @param DashboardComponent $element Task element + * + * @return int + * + * @since 1.0.0 + */ + public function addComponent(DashboardComponent $element) : int + { + $this->components[] = $element; + + \end($this->components); + $key = (int) \key($this->components); + \reset($this->components); + + return $key; + } + + /** + * Remove component from list. + * + * @param int $id Board component + * + * @return bool + * + * @since 1.0.0 + */ + public function removeComponent($id) : bool + { + if (isset($this->components[$id])) { + unset($this->components[$id]); + + return true; + } + + return false; + } + + /** + * Get board components. + * + * @return DashboardComponent[] + * + * @since 1.0.0 + */ + public function getComponents() : array + { + return $this->components; + } + + /** + * Get board component. + * + * @param int $id Component id + * + * @return DashboardComponent + * + * @since 1.0.0 + */ + public function getComponent(int $id) : DashboardComponent + { + return $this->components[$id] ?? new NullDashboardComponent(); + } + + /** + * {@inheritdoc} + */ + public function toArray() : array + { + return [ + 'id' => $this->id, + 'account' => $this->account, + 'title' => $this->title, + 'status' => $this->status, + 'components' => $this->components, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() + { + return $this->toArray(); + } +} diff --git a/Models/DashboardBoardMapper.php b/Models/DashboardBoardMapper.php new file mode 100644 index 0000000..0ec15f2 --- /dev/null +++ b/Models/DashboardBoardMapper.php @@ -0,0 +1,86 @@ +> + * @since 1.0.0 + */ + protected static $columns = [ + 'dashboard_board_id' => ['name' => 'dashboard_board_id', 'type' => 'int', 'internal' => 'id'], + 'dashboard_board_title' => ['name' => 'dashboard_board_title', 'type' => 'string', 'internal' => 'title'], + 'dashboard_board_status' => ['name' => 'dashboard_board_status', 'type' => 'int', 'internal' => 'status'], + 'dashboard_board_account' => ['name' => 'dashboard_board_account', 'type' => 'int', 'internal' => 'account'], + ]; + + /** + * Has many relation. + * + * @var array> + * @since 1.0.0 + */ + protected static $hasMany = [ + 'components' => [ + 'mapper' => DashboardComponentMapper::class, + 'table' => 'dashboard_component', + 'dst' => 'dashboard_component_board', + 'src' => null, + ], + ]; + + /** + * Belongs to. + * + * @var array> + * @since 1.0.0 + */ + protected static $belongsTo = [ + 'account' => [ + 'mapper' => AccountMapper::class, + 'src' => 'dashboard_board_account', + ], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + protected static $table = 'dashboard_board'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + protected static $primaryField = 'dashboard_board_id'; +} diff --git a/Models/DashboardBoardStatus.php b/Models/DashboardBoardStatus.php new file mode 100644 index 0000000..ffe4492 --- /dev/null +++ b/Models/DashboardBoardStatus.php @@ -0,0 +1,31 @@ +id; + } + + /** + * Get order + * + * @return int + * + * @since 1.0.0 + */ + public function getOrder() : int + { + return $this->order; + } + + /** + * Set order + * + * @param int $order Order + * + * @return void + * + * @since 1.0.0 + */ + public function setOrder(int $order) : void + { + $this->order = $order; + } + + /** + * Get component + * + * @return string + * + * @since 1.0.0 + */ + public function getComponent() : string + { + return $this->component; + } + + /** + * Set component + * + * @param string $component Component + * + * @return void + * + * @since 1.0.0 + */ + public function setComponent(string $component) : void + { + $this->component = $component; + } + + /** + * Get module + * + * @return string + * + * @since 1.0.0 + */ + public function getModule() : string + { + return $this->module; + } + + /** + * Set module + * + * @param string $module Module + * + * @return void + * + * @since 1.0.0 + */ + public function setModule(string $module) : void + { + $this->module = $module; + } + + /** + * Get board + * + * @return int|DashboardBoard + * + * @since 1.0.0 + */ + public function getBoard() + { + return $this->board; + } + + /** + * Set board + * + * @param mixed $id Board + * + * @return void + * + * @since 1.0.0 + */ + public function setBoard($id) : void + { + $this->board = $id; + } + + /** + * {@inheritdoc} + */ + public function toArray() : array + { + return [ + 'id' => $this->id, + 'board' => $this->board, + 'order' => $this->order, + 'module' => $this->module, + 'component' => $this->component, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() + { + return $this->toArray(); + } +} diff --git a/Models/DashboardComponentMapper.php b/Models/DashboardComponentMapper.php new file mode 100644 index 0000000..42323a1 --- /dev/null +++ b/Models/DashboardComponentMapper.php @@ -0,0 +1,73 @@ +> + * @since 1.0.0 + */ + protected static $columns = [ + 'dashboard_component_id' => ['name' => 'dashboard_component_id', 'type' => 'int', 'internal' => 'id'], + 'dashboard_component_order' => ['name' => 'dashboard_component_order', 'type' => 'int', 'internal' => 'order'], + 'dashboard_component_module' => ['name' => 'dashboard_component_module', 'type' => 'string', 'internal' => 'module'], + 'dashboard_component_component' => ['name' => 'dashboard_component_component', 'type' => 'string', 'internal' => 'component'], + 'dashboard_component_board' => ['name' => 'dashboard_component_board', 'type' => 'int', 'internal' => 'board'], + ]; + + /** + * Belongs to. + * + * @var array> + * @since 1.0.0 + */ + protected static $belongsTo = [ + 'board' => [ + 'mapper' => DashboardBoardMapper::class, + 'src' => 'dashboard_component_board', + ], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + protected static $table = 'dashboard_component'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + protected static $primaryField = 'dashboard_component_id'; +} diff --git a/Models/NullDashboardBoard.php b/Models/NullDashboardBoard.php new file mode 100644 index 0000000..582822e --- /dev/null +++ b/Models/NullDashboardBoard.php @@ -0,0 +1,28 @@ +