diff --git a/.scss-lint.yml b/.scss-lint.yml index 53bc1cd..e393282 100644 --- a/.scss-lint.yml +++ b/.scss-lint.yml @@ -6,7 +6,7 @@ linters: width: 4 NestingDepth: - max_depth: 4 + max_depth: 5 SelectorDepth: max_depth: 4 diff --git a/README.md b/README.md index eb45eb4..b8962af 100644 --- a/README.md +++ b/README.md @@ -151,11 +151,11 @@ Because I like seeing the numbers. Language | Files | Blank | Comment | Code -------------|--------:|---------:|--------:|---------: -TypeScript | 60 | 711 | 30 | 3294 -PHP | 18 | 562 | 19 | 1755 -HTML | 19 | 137 | 0 | 1193 -SASS | 14 | 225 | 12 | 1029 -__SUM:__ | __111__ | __1635__ | __61__ | __7271__ +TypeScript | 60 | 728 | 30 | 3352 +PHP | 18 | 562 | 19 | 1756 +HTML | 19 | 138 | 0 | 1223 +SASS | 14 | 231 | 12 | 1057 +__SUM:__ | __111__ | __1659__ | __61__ | __7388__ Command: `cloc --exclude-dir=vendor --exclude-ext=json src/` diff --git a/src/api/controllers/Columns.php b/src/api/controllers/Columns.php index c86eb39..c03accd 100644 --- a/src/api/controllers/Columns.php +++ b/src/api/controllers/Columns.php @@ -26,7 +26,7 @@ class Columns extends BaseController { } $this->apiJson->setSuccess(); - $this->apiJson->addData($column); + $this->apiJson->addData(R::exportAll($column)); return $this->jsonResponse($response); } @@ -108,6 +108,7 @@ class Columns extends BaseController { $this->apiJson->setSuccess(); $this->apiJson->addAlert('success', 'Column ' . $update->name . ' updated.'); + $this->apiJson->addData(R::exportAll($update)); return $this->jsonResponse($response); } diff --git a/src/app/board/board.component.html b/src/app/board/board.component.html index 4a51e80..89e46c0 100644 --- a/src/app/board/board.component.html +++ b/src/app/board/board.component.html @@ -2,10 +2,12 @@
diff --git a/src/app/board/column/column.component.ts b/src/app/board/column/column.component.ts index 819c003..58b7cea 100644 --- a/src/app/board/column/column.component.ts +++ b/src/app/board/column/column.component.ts @@ -29,10 +29,11 @@ import { BoardService } from '../board.service'; templateUrl: 'app/board/column/column.component.html' }) export class ColumnDisplay implements OnInit { + private strings: any; private templateElement: any; private collapseTasks: boolean; private saving: boolean; - private hasTaskLimit: boolean; + private showLimitEditor: boolean; private activeUser: User; private activeBoard: Board; @@ -47,6 +48,7 @@ export class ColumnDisplay implements OnInit { private quickAdd: Task; private modalProps: Task; private taskToRemove: number; + private taskLimit: number; @Input('column') columnData: Column; @Input('boards') boards: Array; @@ -61,17 +63,21 @@ export class ColumnDisplay implements OnInit { this.tasks = []; this.collapseTasks = false; - this.contextMenuItems = [ - new ContextMenuItem('Add Task', - this.getShowModalFunction()) - ]; - this.MODAL_ID = 'add-task-form-'; this.MODAL_CONFIRM_ID = 'task-remove-confirm'; this.quickAdd = new Task(); this.modalProps = new Task(); + stringsService.stringsChanged.subscribe(newStrings => { + this.strings = newStrings; + + this.contextMenuItems = [ + new ContextMenuItem(this.strings.boards_addTask, + this.getShowModalFunction()) + ]; + }); + boardService.activeBoardChanged.subscribe((board: Board) => { this.activeBoard = board; }); @@ -108,6 +114,8 @@ export class ColumnDisplay implements OnInit { if (isCollapsed) { this.templateElement.classList.add('collapsed'); } + + this.taskLimit = this.columnData.task_limit; } toggleCollapsed() { @@ -169,6 +177,8 @@ export class ColumnDisplay implements OnInit { this.boardService.updateActiveBoard(response.data[2][0]); this.modal.close(this.MODAL_ID + this.columnData.id); + + this.boardService.refreshToken(); }); } @@ -185,6 +195,41 @@ export class ColumnDisplay implements OnInit { }); } + beginLimitEdit() { + this.taskLimit = this.columnData.task_limit; + this.showLimitEditor = true; + } + + cancelLimitChanges() { + this.showLimitEditor = false; + } + + saveLimitChanges() { + let originalLimit = this.columnData.task_limit; + + this.columnData.task_limit = this.taskLimit; + + this.boardService.updateColumn(this.columnData) + .subscribe((response: ApiResponse) => { + response.alerts.forEach(note => this.notes.add(note)); + + if (response.status !== 'success') { + this.columnData.task_limit = originalLimit; + return; + } + + let colData = response.data[1][0]; + this.columnData = new Column(colData.id, + colData.name, + colData.position, + colData.board_id, + colData.task_limit, + colData.ownTask); + }); + + this.showLimitEditor = false; + } + private validateTask(task: Task) { if (task.title === '') { this.notes.add( @@ -206,7 +251,9 @@ export class ColumnDisplay implements OnInit { return () => { this.showModal(taskId); }; } - private quickAddClicked() { + private quickAddClicked(event: any) { + this.preventEnter(event); + if (this.quickAdd.title === '') { this.showModal(); return; diff --git a/src/app/board/task/task.component.html b/src/app/board/task/task.component.html index 43f5c41..299bd31 100644 --- a/src/app/board/task/task.component.html +++ b/src/app/board/task/task.component.html @@ -6,10 +6,13 @@ [style.color]="getTextColor(taskData.color)" [ngClass]="{ 'icon-minus-squared-alt': !isCollapsed, 'icon-plus-squared-alt': isCollapsed }" - title="{{ isCollapsed ? 'Expand' : 'Collapse' }} Task" + [title]="isCollapsed + ? strings['boards_expandTask'] + : strings['boards_collapseTask']" (click)="isCollapsed = !isCollapsed"> {{ taskData.title }} - + {{ taskData.points }} @@ -18,25 +21,27 @@
- Assigned To: + {{ strings['boards_taskAssignedTo'] }}: {{ assignee.username }} - Unassigned + {{ strings['boards_taskUnassigned'] }} - Due: {{ taskData.due_date }} + {{ strings['boards_taskDue'] }}: {{ taskData.due_date }} + [title]="taskData.comments.length + + strings['boards_taskComments']"> - + [title]="taskData.attachments.length + + strings['boards_taskAttachments']"> + {{ category.name }} diff --git a/src/app/board/task/task.component.ts b/src/app/board/task/task.component.ts index 2b63d75..42c36dd 100644 --- a/src/app/board/task/task.component.ts +++ b/src/app/board/task/task.component.ts @@ -19,7 +19,8 @@ import { UserOptions, AuthService, ModalService, - NotificationsService + NotificationsService, + StringsService } from '../../shared/index'; import { BoardService } from '../board.service'; @@ -28,6 +29,7 @@ import { BoardService } from '../board.service'; templateUrl: 'app/board/task/task.component.html' }) export class TaskDisplay implements OnInit { + private strings: any; private userOptions: UserOptions; private contextMenuItems: Array; private selectMenuItem: ContextMenuItem; @@ -55,12 +57,21 @@ export class TaskDisplay implements OnInit { private sanitizer: DomSanitizer, private boardService: BoardService, private modal: ModalService, - private notes: NotificationsService) { + private notes: NotificationsService, + private stringsService: StringsService) { this.totalTasks = 0; this.completeTasks = 0; this.percentComplete = 0; this.contextMenuItems = []; + stringsService.stringsChanged.subscribe(newStrings => { + this.strings = newStrings; + + if (this.taskData) { + this.generateContextMenuItems(); + } + }); + auth.userChanged.subscribe(() => { this.userOptions = auth.userOptions; }); @@ -98,7 +109,9 @@ export class TaskDisplay implements OnInit { } getPercentTitle() { - return 'Task ' + (this.percentComplete * 100) + '% Complete'; + return this.strings.boards_task + ' ' + + (this.percentComplete * 100).toFixed(0) + '% ' + + this.strings.boards_taskComplete; } // Expects a color in full HEX with leading #, e.g. #ffffe0 @@ -112,7 +125,8 @@ export class TaskDisplay implements OnInit { } private getMoveMenuItem() { - let menuText = 'Move to Column: '; this.activeBoard.columns.forEach((column: Column) => { menuText += ''; @@ -161,29 +175,28 @@ export class TaskDisplay implements OnInit { private generateContextMenuItems() { this.contextMenuItems = [ - new ContextMenuItem('View Task'), - new ContextMenuItem('Edit Task', this.editTask), - new ContextMenuItem('Remove Task', this.removeTask), + new ContextMenuItem(this.strings.boards_viewTask), + new ContextMenuItem(this.strings.boards_editTask, this.editTask), + new ContextMenuItem(this.strings.boards_removeTask, this.removeTask), new ContextMenuItem('', null, true), this.getMoveMenuItem(), new ContextMenuItem('', null, true), - new ContextMenuItem('Add Task', this.addTask) + new ContextMenuItem(this.strings.boards_addTask, this.addTask) ]; if (this.boardsList.length > 1) { this.contextMenuItems .splice(3, 0, new ContextMenuItem('', null, true), - this.getMenuItem('Copy'), - this.getMenuItem('Move')); + this.getMenuItem(this.strings.boards_copyTaskTo), + this.getMenuItem(this.strings.boards_moveTaskTo)); } } private getMenuItem(text: string): ContextMenuItem { - let menuText = text + ' to Board: ' + + let menuText = text + ': ' + ' ' + + 'data-help="' + this.strings.boards_copyMoveHelp + '"> ' + '