From ac6808ffa7d1122fae080f8a4ff6097ed9995763 Mon Sep 17 00:00:00 2001 From: kiswa Date: Sun, 26 Feb 2017 17:25:39 +0000 Subject: [PATCH] WIP - Persist collapsed columns and start Task addition --- src/api/controllers/Auth.php | 6 ++ src/api/controllers/Users.php | 37 ++++++++++++ src/api/helpers/BeanLoader.php | 58 ++++++++++++------ src/api/index.php | 1 + src/app/board/board.component.html | 3 +- src/app/board/board.component.ts | 4 +- src/app/board/board.service.ts | 23 +++++++ src/app/board/column/column.component.html | 34 ++++++++++- src/app/board/column/column.component.ts | 70 +++++++++++++++++----- src/app/shared/models/column.model.ts | 4 +- src/app/shared/models/index.ts | 1 + src/app/shared/models/task.model.ts | 19 ++++++ src/app/shared/models/user.model.ts | 3 +- test/api/controllers/AuthTest.php | 5 ++ test/api/controllers/ColumnsTest.php | 1 + test/api/controllers/TasksTest.php | 6 +- test/api/controllers/UsersTest.php | 46 ++++++++++++++ 17 files changed, 277 insertions(+), 44 deletions(-) create mode 100644 src/app/shared/models/task.model.ts diff --git a/src/api/controllers/Auth.php b/src/api/controllers/Auth.php index 8d5e858..9e24fc5 100644 --- a/src/api/controllers/Auth.php +++ b/src/api/controllers/Auth.php @@ -206,6 +206,12 @@ class Auth extends BaseController { $user = R::load('user', $payload->uid); $opts = R::load('useroption', $user->user_option_id); + $collapsed = R::find('collapsed', ' user_id = ? ', [ $user->id ]); + + $user->collapsed = []; + foreach ($collapsed as $collapse) { + $user->collapsed[] = $collapse->column_id; + } $this->apiJson->setSuccess(); $this->apiJson->addData($jwt); diff --git a/src/api/controllers/Users.php b/src/api/controllers/Users.php index 08b6ac1..9336e01 100644 --- a/src/api/controllers/Users.php +++ b/src/api/controllers/Users.php @@ -237,6 +237,43 @@ class Users extends BaseController { return $this->jsonResponse($response); } + public function toggleCollapsed($request, $response, $args) { + $status = $this->secureRoute($request, $response, SecurityLevel::USER); + if ($status !== 200) { + return $this->jsonResponse($response, $status); + } + + $user = R::load('user', (int)$args['id']); + $actor = R::load('user', Auth::GetUserId($request)); + + if ($actor->id !== $user->id) { + $this->apiJson->addAlert('error', 'Access restricted.'); + + return $this->jsonResponse($response, 403); + } + + $data = json_decode($request->getBody()); + $collapsed = R::findOne('collapsed', ' user_id = ? AND column_id = ? ', + [ $user->id, $data->id ]); + + if (!is_null($collapsed)) { + R::trash($collapsed); + } else { + $collapsed = R::dispense('collapsed'); + $collapsed->user_id = $user->id; + $collapsed->column_id = $data->id; + + R::store($collapsed); + } + + $allCollapsed = R::find('collapsed', ' user_id = ? ', [ $user->id ]); + + $this->apiJson->setSuccess(); + $this->apiJson->addData(R::exportAll($allCollapsed)); + + return $this->jsonResponse($response); + } + public function removeUser($request, $response, $args) { $status = $this->secureRoute($request, $response, SecurityLevel::ADMIN); if ($status !== 200) { diff --git a/src/api/helpers/BeanLoader.php b/src/api/helpers/BeanLoader.php index dc2cfea..eeccedb 100644 --- a/src/api/helpers/BeanLoader.php +++ b/src/api/helpers/BeanLoader.php @@ -46,17 +46,17 @@ class BeanLoader { $board->is_active = isset($data->is_active) ? $data->is_active : ''; if (isset($data->categories)) { - self::updateBoardList('category', 'LoadCategory', + self::updateObjectList('category', 'LoadCategory', $board->xownCategoryList, $data->categories); } if (isset($data->columns)) { - self::updateBoardList('column', 'LoadColumn', + self::updateObjectList('column', 'LoadColumn', $board->xownColumnList, $data->columns); } if (isset($data->issue_trackers)) { - self::updateBoardList('issuetracker', 'LoadIssueTracker', + self::updateObjectList('issuetracker', 'LoadIssueTracker', $board->xownIssueTrackerList, $data->issue_trackers); } @@ -106,6 +106,11 @@ class BeanLoader { $column->position = isset($data->position) ? $data->position : ''; $column->board_id = isset($data->board_id) ? $data->board_id : ''; + if (isset($data->tasks)) { + self::updateObjectList('task', 'LoadTask', + $column->xownTaskList, $data->tasks); + } + if (!isset($data->name) || !isset($data->position) || !isset($data->board_id)) { return false; @@ -150,15 +155,32 @@ class BeanLoader { $task->title = isset($data->title) ? $data->title : ''; $task->description = isset($data->description) ? $data->description : ''; - $task->assignee = isset($data->assignee) ? $data->assignee : ''; - $task->category_id = isset($data->category_id) - ? $data->category_id : ''; $task->color = isset($data->color) ? $data->color : ''; $task->due_date = isset($data->due_date) ? $data->due_date : ''; $task->points = isset($data->points) ? $data->points : ''; $task->position = isset($data->position) ? $data->position : ''; $task->column_id = isset($data->column_id) ? $data->column_id : ''; + if (isset($data->comments)) { + self::updateObjectList('comment', 'LoadComment', + $column->xownCommentList, $data->comments); + } + + if (isset($data->attachments)) { + self::updateObjectList('attachment', 'LoadAttachment', + $column->xownAttachmentList, $data->attachments); + } + + if (isset($data->assignees)) { + self::updateObjectList('user', 'LoadUser', + $column->xownAssigneeList, $data->assignees); + } + + if (isset($data->categories)) { + self::updateObjectList('category', 'LoadCategory', + $column->xownCategoryList, $data->categories); + } + if (!isset($data->title) || !isset($data->position) || !isset($data->column_id)) { return false; @@ -210,7 +232,7 @@ class BeanLoader { return true; } - private static function removeObjectsNotInData($type, &$dataList, &$boardList) { + private static function removeObjectsNotInData($type, &$dataList, &$objectList) { $dataIds = []; foreach ($dataList as $data) { @@ -219,7 +241,7 @@ class BeanLoader { } } - foreach ($boardList as $existing) { + foreach ($objectList as $existing) { if (!in_array((int)$existing->id, $dataIds)) { $remove = R::load($type, $existing->id); R::trash($remove); @@ -228,36 +250,36 @@ class BeanLoader { } private static function loadObjectsFromData($type, $loadFunc, &$dataList, - &$boardList) { + &$objectList) { foreach ($dataList as $obj) { $object = R::load($type, (isset($obj->id) ? $obj->id : 0)); if ((int)$object->id === 0) { call_user_func_array(array(__CLASS__, $loadFunc), array(&$object, json_encode($obj))); - $boardList[] = $object; + $objectList[] = $object; continue; } call_user_func_array(array(__CLASS__, $loadFunc), - array(&$boardList[$object->id], + array(&$objectList[$object->id], json_encode($obj))); } } - private static function updateBoardList($type, $loadFunc, - &$boardList = [], &$dataList = []) { - if (count($boardList) && count($dataList)) { - self::removeObjectsNotInData($type, $dataList, $boardList); + private static function updateObjectList($type, $loadFunc, + &$objectList = [], &$dataList = []) { + if (count($objectList) && count($dataList)) { + self::removeObjectsNotInData($type, $dataList, $objectList); } if (count($dataList)) { - self::loadObjectsFromData($type, $loadFunc, $dataList, $boardList); + self::loadObjectsFromData($type, $loadFunc, $dataList, $objectList); } // Remove all objects from existing boardlist when none in datalist - if (!count($dataList) && count($boardList)) { - foreach ($boardList as $obj) { + if (!count($dataList) && count($objectList)) { + foreach ($objectList as $obj) { R::trash($obj); } } diff --git a/src/api/index.php b/src/api/index.php index 34e68c9..9177040 100644 --- a/src/api/index.php +++ b/src/api/index.php @@ -46,6 +46,7 @@ $app->get('/users/{id}', 'Users:getUser'); // User (by board access) $app->post('/users', 'Users:addUser'); // Admin $app->post('/users/{id}', 'Users:updateUser'); // User (limited to self - Higher can edit any) $app->post('/users/{id}/opts', 'Users:updateUserOptions'); // User (limited to self) +$app->post('/users/{id}/cols', 'Users:toggleCollapsed'); // User (limited to self) $app->delete('/users/{id}', 'Users:removeUser'); // Admin $app->post('/login', 'Auth:login'); // Unsecured (creates JWT) diff --git a/src/app/board/board.component.html b/src/app/board/board.component.html index f83ff49..cd3d6af 100644 --- a/src/app/board/board.component.html +++ b/src/app/board/board.component.html @@ -60,7 +60,6 @@
+ [column]="column">
diff --git a/src/app/board/board.component.ts b/src/app/board/board.component.ts index b6c0782..b9f840c 100644 --- a/src/app/board/board.component.ts +++ b/src/app/board/board.component.ts @@ -10,7 +10,6 @@ import { Board, Column, User, - UserOptions, InlineEdit, Modal, Notification, @@ -26,7 +25,6 @@ import { BoardService } from './board.service'; }) export class BoardDisplay implements OnInit { private activeUser: User; - private userOptions: UserOptions; private activeBoard: Board; private boards: Array; @@ -60,7 +58,6 @@ export class BoardDisplay implements OnInit { auth.userChanged.subscribe((user: User) => { this.updateActiveUser(user); - this.userOptions = auth.userOptions; }); active.params.subscribe(params => { @@ -122,6 +119,7 @@ export class BoardDisplay implements OnInit { this.boards.forEach(board => { if (board.id === this.boardNavId) { this.activeBoard = board; + this.boardService.updateActiveBoard(board); this.pageName = board.name; } }); diff --git a/src/app/board/board.service.ts b/src/app/board/board.service.ts index 29ba4ec..a185769 100644 --- a/src/app/board/board.service.ts +++ b/src/app/board/board.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/observable/of'; import 'rxjs/add/operator/map'; @@ -14,9 +15,17 @@ import { @Injectable() export class BoardService { + private activeBoard = new BehaviorSubject(null); + + public activeBoardChanged = this.activeBoard.asObservable(); + constructor(private http: Http) { } + updateActiveBoard(board: Board): void { + this.activeBoard.next(board); + } + getBoards(): Observable { return this.http.get('api/boards') .map(res => { @@ -29,6 +38,20 @@ export class BoardService { }); } + toggleCollapsed(userId: number, columnId: number): Observable { + return this.http.post('api/users/' + userId + '/cols', + { id: columnId }) + .map(res => { + let response: ApiResponse = res.json(); + return response; + }) + .catch((res, caught) => { + let response: ApiResponse = res.json(); + return Observable.of(response); + }); + } + + // TODO: Determine when to use this refreshToken(): void { this.http.post('api/refresh', {}).subscribe(); } diff --git a/src/app/board/column/column.component.html b/src/app/board/column/column.component.html index 0e3bca6..30a832b 100644 --- a/src/app/board/column/column.component.html +++ b/src/app/board/column/column.component.html @@ -67,8 +67,40 @@ - + + + + + + + + + + + + + + + + + +
{{ modalProps | json }}