diff --git a/Admin/Install/db.json b/Admin/Install/db.json new file mode 100644 index 0000000..a1e8ce0 --- /dev/null +++ b/Admin/Install/db.json @@ -0,0 +1,136 @@ +{ + "checklist_checklist_template": { + "name": "checklist_checklist_template", + "fields": { + "checklist_checklist_template_id": { + "name": "checklist_checklist_template_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "checklist_checklist_template_name": { + "name": "checklist_checklist_template_name", + "type": "VARCHAR(255)", + "null": false + }, + "checklist_checklist_template_description": { + "name": "checklist_checklist_template_description", + "type": "TEXT", + "null": false + }, + "checklist_checklist_template_repeat": { + "name": "checklist_checklist_template_repeat", + "type": "TINYINT(1)", + "null": false + }, + "checklist_checklist_template_interval": { + "name": "checklist_checklist_template_interval", + "type": "VARCHAR(255)", + "null": false + }, + "checklist_checklist_template_start": { + "name": "checklist_checklist_template_start", + "type": "DATETIME", + "null": false + }, + "checklist_checklist_template_end": { + "name": "checklist_checklist_template_end", + "type": "DATETIME", + "null": true, + "default": null + } + } + }, + "checklist_checklist_template_task": { + "name": "checklist_checklist_template_task", + "fields": { + "checklist_checklist_template_task_id": { + "name": "checklist_checklist_template_task_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "checklist_checklist_template_task_order": { + "name": "checklist_checklist_template_task_order", + "type": "INT", + "null": false + }, + "checklist_checklist_template_task_template": { + "name": "checklist_checklist_template_task_template", + "type": "INT", + "null": false, + "foreignTable": "checklist_checklist_template", + "foreignKey": "checklist_checklist_template_id" + }, + "checklist_checklist_template_task_task": { + "name": "checklist_checklist_template_task_task", + "type": "INT", + "null": false, + "foreignTable": "task", + "foreignKey": "task_id" + } + } + }, + "checklist_checklist": { + "name": "checklist_checklist", + "fields": { + "checklist_checklist_id": { + "name": "checklist_checklist_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "checklist_checklist_name": { + "name": "checklist_checklist_name", + "type": "VARCHAR(255)", + "null": false + }, + "checklist_checklist_template": { + "name": "checklist_checklist_template", + "type": "INT", + "null": false, + "foreignTable": "checklist_checklist_template", + "foreignKey": "checklist_checklist_template_id" + }, + "checklist_checklist_createdat": { + "name": "checklist_checklist_createdat", + "type": "DATETIME", + "null": false + } + } + }, + "checklist_checklist_task": { + "name": "checklist_checklist_task", + "fields": { + "checklist_checklist_task_id": { + "name": "checklist_checklist_task_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "checklist_checklist_task_order": { + "name": "checklist_checklist_task_order", + "type": "INT", + "null": false + }, + "checklist_checklist_task_template": { + "name": "checklist_checklist_task_template", + "type": "INT", + "null": false, + "foreignTable": "checklist_checklist", + "foreignKey": "checklist_checklist_id" + }, + "checklist_checklist_task_task": { + "name": "checklist_checklist_template_task_task", + "type": "INT", + "null": false, + "foreignTable": "task", + "foreignKey": "task_id" + } + } + } +} \ No newline at end of file diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php index b4261b2..55626f8 100755 --- a/Admin/Routes/Web/Backend.php +++ b/Admin/Routes/Web/Backend.php @@ -29,6 +29,17 @@ return [ ], ], ], + '^.*/checklist/view.*$' => [ + [ + 'dest' => '\Modules\Checklist\Controller\BackendController:viewChecklistView', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::CHECKLIST, + ], + ], + ], '^.*/checklist/template/list.*$' => [ [ 'dest' => '\Modules\Checklist\Controller\BackendController:viewChecklistTemplateList', @@ -62,4 +73,15 @@ return [ ], ], ], + '^.*/checklist/template/task.*$' => [ + [ + 'dest' => '\Modules\Checklist\Controller\BackendController:viewChecklistTemplateTaskView', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::TEMPLATE, + ], + ], + ], ]; diff --git a/Controller/ApiController.php b/Controller/ApiController.php new file mode 100644 index 0000000..884a4f2 --- /dev/null +++ b/Controller/ApiController.php @@ -0,0 +1,177 @@ +validateChecklistTemplateCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); + + return; + } + + $checklist = $this->createChecklistTemplateFromRequest($request); + $this->createModel($request->header->account, $checklist, ChecklistTemplateMapper::class, 'checklist_template', $request->getOrigin()); + $this->createStandardCreateResponse($request, $response, $checklist); + } + + /** + * Validate checklist create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateChecklistTemplateCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['name'] = !$request->hasData('name')) + ) { + return $val; + } + + return []; + } + + /** + * Method to create checklist from request. + * + * @param RequestAbstract $request Request + * + * @return ChecklistTemplate + * + * @since 1.0.0 + */ + private function createChecklistTemplateFromRequest(RequestAbstract $request) : ChecklistTemplate + { + $checklist = new ChecklistTemplate(); + $checklist->name = (string) $request->getData('name'); + $checklist->description = $request->getDataString('description') ?? ''; + $checklist->repeat = 0; + $checklist->interval = $request->getDataString('interval') ?? ''; + $checklist->start = $request->getDataDateTime('start') ?? new \DateTime('now'); + $checklist->end = $request->getDataDateTime('end'); + + return $checklist; + } + + /** + * Api method to create an checklist + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param array $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiChecklistTemplateTaskCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void + { + if (!empty($val = $this->validateChecklistTemplateTaskCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); + + return; + } + + $checklist = $this->createChecklistTemplateTaskFromRequest($request); + $this->createModel($request->header->account, $checklist, ChecklistTemplateTaskMapper::class, 'checklist_template_task', $request->getOrigin()); + $this->createStandardCreateResponse($request, $response, $checklist); + } + + /** + * Validate checklist create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateChecklistTemplateTaskCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['template'] = !$request->hasData('template')) + ) { + return $val; + } + + return []; + } + + /** + * Method to create checklist from request. + * + * @param RequestAbstract $request Request + * + * @return ChecklistTemplateTask + * + * @since 1.0.0 + */ + private function createChecklistTemplateTaskFromRequest(RequestAbstract $request) : ChecklistTemplateTask + { + $request->setData('type', TaskType::TEMPLATE, true); + + $checklistTask = new ChecklistTemplateTask(); + $checklistTask->template = (int) $request->getData('template'); + $checklistTask->task = $this->app->moduleManager->get('Tasks', 'Api')->createTaskFromRequest($request); + + return $checklistTask; + } +} diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 7561cf2..0bae666 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -14,6 +14,7 @@ declare(strict_types=1); namespace Modules\Checklist\Controller; +use Modules\Checklist\Models\ChecklistTemplateMapper; use phpOMS\Contract\RenderableInterface; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; @@ -31,7 +32,7 @@ use phpOMS\Views\View; final class BackendController extends Controller { /** - * Routing end-point for application behaviour. + * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -52,7 +53,7 @@ final class BackendController extends Controller } /** - * Routing end-point for application behaviour. + * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -69,11 +70,14 @@ final class BackendController extends Controller $view->setTemplate('/Modules/Checklist/Theme/Backend/checklist-template-list'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003601001, $request, $response); + $view->data['templates'] = ChecklistTemplateMapper::getAll() + ->execute(); + return $view; } /** - * Routing end-point for application behaviour. + * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -94,7 +98,7 @@ final class BackendController extends Controller } /** - * Routing end-point for application behaviour. + * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -111,6 +115,16 @@ final class BackendController extends Controller $view->setTemplate('/Modules/Checklist/Theme/Backend/checklist-template'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003601001, $request, $response); + $view->data['template'] = ChecklistTemplateMapper::get() + ->with('tasks') + ->with('tasks/taskElements') + ->with('tasks/taskElements/accRelation') + ->with('tasks/taskElements/accRelation/relation') + ->with('tasks/taskElements/grpRelation') + ->with('tasks/taskElements/grpRelation/relation') + ->where('id', (int) $request->getData('id')) + ->execute(); + return $view; } } diff --git a/Docs/Dev/img/er.png b/Docs/Dev/img/er.png new file mode 100644 index 0000000..8faa0c3 Binary files /dev/null and b/Docs/Dev/img/er.png differ diff --git a/Models/Checklist.php b/Models/Checklist.php new file mode 100644 index 0000000..d51d00c --- /dev/null +++ b/Models/Checklist.php @@ -0,0 +1,65 @@ +createdAt = new \DateTimeImmutable(); + } + + /** + * {@inheritdoc} + */ + public function toArray() : array + { + return [ + 'id' => $this->id, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } +} diff --git a/Models/ChecklistMapper.php b/Models/ChecklistMapper.php new file mode 100644 index 0000000..22f1cbf --- /dev/null +++ b/Models/ChecklistMapper.php @@ -0,0 +1,76 @@ + + */ +final class ChecklistMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'checklist_checklist_id' => ['name' => 'checklist_checklist_id', 'type' => 'int', 'internal' => 'id'], + 'checklist_checklist_name' => ['name' => 'checklist_checklist_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], + 'checklist_checklist_template' => ['name' => 'checklist_checklist_template', 'type' => 'int', 'internal' => 'template'], + 'checklist_checklist_createdat' => ['name' => 'checklist_checklist_createdat', 'type' => 'DateTimeImmutable', 'internal' => 'createdAt'], + ]; + + /** + * Has many relation. + * + * @var array + * @since 1.0.0 + */ + public const HAS_MANY = [ + 'tasks' => [ + 'mapper' => TaskMapper::class, + 'table' => 'checklist_checklist_task', + 'self' => 'checklist_checklist_task_task', + 'external' => null, + ], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'checklist_checklist'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'checklist_checklist_id'; +} diff --git a/Models/ChecklistTemplate.php b/Models/ChecklistTemplate.php new file mode 100644 index 0000000..e898e91 --- /dev/null +++ b/Models/ChecklistTemplate.php @@ -0,0 +1,71 @@ +start = new \DateTime(); + } + + /** + * {@inheritdoc} + */ + public function toArray() : array + { + return [ + 'id' => $this->id, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } +} diff --git a/Models/ChecklistTemplateMapper.php b/Models/ChecklistTemplateMapper.php new file mode 100644 index 0000000..1772ba4 --- /dev/null +++ b/Models/ChecklistTemplateMapper.php @@ -0,0 +1,79 @@ + + */ +final class ChecklistTemplateMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'checklist_checklist_template_id' => ['name' => 'checklist_checklist_template_id', 'type' => 'int', 'internal' => 'id'], + 'checklist_checklist_template_name' => ['name' => 'checklist_checklist_template_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], + 'checklist_checklist_template_description' => ['name' => 'checklist_checklist_template_description', 'type' => 'string', 'internal' => 'description'], + 'checklist_checklist_template_repeat' => ['name' => 'checklist_checklist_template_repeat', 'type' => 'int', 'internal' => 'repeat'], + 'checklist_checklist_template_interval' => ['name' => 'checklist_checklist_template_interval', 'type' => 'string', 'internal' => 'interval'], + 'checklist_checklist_template_start' => ['name' => 'checklist_checklist_template_start', 'type' => 'DateTime', 'internal' => 'start'], + 'checklist_checklist_template_end' => ['name' => 'checklist_checklist_template_end', 'type' => 'DateTime', 'internal' => 'end'], + ]; + + /** + * Has many relation. + * + * @var array + * @since 1.0.0 + */ + public const HAS_MANY = [ + 'tasks' => [ + 'mapper' => TaskMapper::class, + 'table' => 'checklist_checklist_template_task', + 'external' => 'checklist_checklist_template_task_task', + 'self' => 'checklist_checklist_template_task_template', + ], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'checklist_checklist_template'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'checklist_checklist_template_id'; +} diff --git a/Models/ChecklistTemplateTask.php b/Models/ChecklistTemplateTask.php new file mode 100644 index 0000000..a04356c --- /dev/null +++ b/Models/ChecklistTemplateTask.php @@ -0,0 +1,60 @@ + $this->id, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } +} diff --git a/Models/ChecklistTemplateTaskMapper.php b/Models/ChecklistTemplateTaskMapper.php new file mode 100644 index 0000000..e0ee330 --- /dev/null +++ b/Models/ChecklistTemplateTaskMapper.php @@ -0,0 +1,74 @@ + + */ +final class ChecklistTemplateTaskMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'checklist_checklist_template_task_id' => ['name' => 'checklist_checklist_template_task_id', 'type' => 'int', 'internal' => 'id'], + 'checklist_checklist_template_task_order' => ['name' => 'checklist_checklist_template_task_order', 'type' => 'int', 'internal' => 'order'], + 'checklist_checklist_template_task_template' => ['name' => 'checklist_checklist_template_task_template', 'type' => 'int', 'internal' => 'template'], + 'checklist_checklist_template_task_task' => ['name' => 'checklist_checklist_template_task_task', 'type' => 'int', 'internal' => 'task'], + ]; + + /** + * Has one relation. + * + * @var array + * @since 1.0.0 + */ + public const OWNS_ONE = [ + 'task' => [ + 'mapper' => TaskMapper::class, + 'external' => 'checklist_checklist_template_task_task', + ], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'checklist_checklist_template_task'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'checklist_checklist_template_task_id'; +} diff --git a/Models/NullChecklist.php b/Models/NullChecklist.php new file mode 100644 index 0000000..73404c8 --- /dev/null +++ b/Models/NullChecklist.php @@ -0,0 +1,47 @@ +id = $id; + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return ['id' => $this->id]; + } +} diff --git a/Models/NullChecklistTemplate.php b/Models/NullChecklistTemplate.php new file mode 100644 index 0000000..f01600e --- /dev/null +++ b/Models/NullChecklistTemplate.php @@ -0,0 +1,47 @@ +id = $id; + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return ['id' => $this->id]; + } +} diff --git a/Models/NullChecklistTemplateTask.php b/Models/NullChecklistTemplateTask.php new file mode 100644 index 0000000..3600ad1 --- /dev/null +++ b/Models/NullChecklistTemplateTask.php @@ -0,0 +1,46 @@ +id = $id; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return ['id' => $this->id]; + } +} diff --git a/Models/PermissionCategory.php b/Models/PermissionCategory.php index 45beb7f..48f9dc9 100755 --- a/Models/PermissionCategory.php +++ b/Models/PermissionCategory.php @@ -17,7 +17,7 @@ namespace Modules\Checklist\Models; use phpOMS\Stdlib\Base\Enum; /** - * Permision state enum. + * Permission category enum. * * @package Modules\Checklist\Models * @license OMS License 2.0 @@ -28,5 +28,7 @@ abstract class PermissionCategory extends Enum { public const CHECKLIST = 1; - public const TEMPLATE = 2; + public const TASK = 2; + + public const TEMPLATE = 3; } diff --git a/Theme/Backend/checklist-task.tpl.php b/Theme/Backend/checklist-task.tpl.php new file mode 100644 index 0000000..f201c00 --- /dev/null +++ b/Theme/Backend/checklist-task.tpl.php @@ -0,0 +1,98 @@ +data['nav']->render(); ?> + +
+
+
+
+
getHtml('Task'); ?>
+
+
+ + getData('accGrpSelector')->render('iReceiver', 'forward', true); ?> +
+ +
+ + getData('accGrpSelector')->render('iCC', 'cc', false); ?> +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ data['editor']->render('task-editor'); ?> +
+ +
+ data['editor']->getData('text')->render('task-editor', 'plain', 'fTask'); ?> +
+
+
+ + +
+
+
+
+ +
+
+
getHtml('Media'); ?>
+
+
+
+ +
+
+
+
+
+ +
+ + +
+
+ +
+
+
+ +getData('accGrpSelector')->getData('popup')->render(); ?> \ No newline at end of file diff --git a/Theme/Backend/checklist-template-list.tpl.php b/Theme/Backend/checklist-template-list.tpl.php index 6e0a2ea..1ef7c1e 100755 --- a/Theme/Backend/checklist-template-list.tpl.php +++ b/Theme/Backend/checklist-template-list.tpl.php @@ -15,42 +15,31 @@ declare(strict_types=1); /** * @var \phpOMS\Views\View $this */ - -$footerView = new \phpOMS\Views\PaginationView($this->l11nManager, $this->request, $this->response); -$footerView->setTemplate('/Web/Templates/Lists/Footer/PaginationBig'); - -$footerView->setPages(25); -$footerView->setPage(1); -$footerView->setResults(1); - echo $this->data['nav']->render(); ?>
-
+
+
getHtml('Templates'); ?>download
- - $value) : ++$c; - $url = \phpOMS\Uri\UriFactory::build('checklist/single?{?}&id=' . $value->id); ?> - + data['templates'] as $key => $value) : ++$c; + $url = \phpOMS\Uri\UriFactory::build('{/base}/checklist/template/view?{?}&id=' . $value->id); + ?> + -
getHtml('Templates'); ?>download
getHtml('ID', '0', '0'); ?> - getHtml('Status'); ?> getHtml('Name'); ?> - getHtml('Creator'); ?> - getHtml('Created'); ?>
id; ?> printHtml($value->name); ?> - printHtml($value->parent); ?> - printHtml($value->getUnit()); ?> - - + +
getHtml('Empty', '0', '0'); ?> - + getHtml('Empty', '0', '0'); ?> +
diff --git a/Theme/Backend/checklist-template.tpl.php b/Theme/Backend/checklist-template.tpl.php new file mode 100644 index 0000000..7230618 --- /dev/null +++ b/Theme/Backend/checklist-template.tpl.php @@ -0,0 +1,63 @@ +data['nav']->render(); ?> + +
+
+
+
getHtml('Tasks'); ?>download
+
+ + + + + data['template']->tasks as $key => $task) : ++$c; + $url = \phpOMS\Uri\UriFactory::build('{/base}/checklist/template/task?{?}&id=' . $task->id); + ?> + + +
getHtml('Due/Priority', 'Tasks', 'Backend'); ?> + getHtml('Title', 'Tasks', 'Backend'); ?> + getHtml('For', 'Tasks', 'Backend'); ?> +
getPriority() === TaskPriority::NONE) : ?> + due?->getTimestamp() - $task->createdAt?->getTimestamp()); ?> + + getHtml('P' . $task->getPriority(), 'Tasks', 'Backend'); ?> + + printHtml($task->title); ?> + taskElements); + foreach ($element->accRelation as $rel): ?> + printHtml( + \sprintf('%3$s %2$s %1$s', $rel->relation->name1, $rel->relation->name2, $rel->relation->name3) + ); ?> + + + +
getHtml('Empty', '0', '0'); ?> + +
+
+
+
+
diff --git a/info.json b/info.json index ac80c3c..ad79406 100755 --- a/info.json +++ b/info.json @@ -14,7 +14,6 @@ "name": "Jingga", "website": "jingga.app" }, - "description": "The administration module.", "directory": "Checklist", "dependencies": { "Admin": "1.0.0",