diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 83c138f..d7f20f2 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -20,6 +20,7 @@ import { InlineEdit, TopNav } from './shared/index'; +import { BoardService } from './board/board.service'; @NgModule({ imports: [ @@ -36,7 +37,8 @@ import { AuthService, NotificationsService, ModalService, - Constants + Constants, + BoardService ], declarations: [ AppComponent, diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index cc5ea66..9dca517 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -2,7 +2,7 @@ import { Routes, RouterModule } from '@angular/router'; import { AuthGuard } from './shared/index'; import { Login } from './login/login.component'; -import { Board } from './board/board.component'; +import { BoardDisplay } from './board/board.component'; import { Settings, UserAdmin, @@ -19,7 +19,12 @@ const ROUTES: Routes = [ }, { path: 'boards', - component: Board, + component: BoardDisplay, + canActivate: [ AuthGuard ] + }, + { + path: 'boards/:id', + component: BoardDisplay, canActivate: [ AuthGuard ] }, { @@ -36,7 +41,7 @@ const ROUTES: Routes = [ export const ROUTE_COMPONENTS = [ Login, - Board, + BoardDisplay, Settings, UserAdmin, BoardAdmin, diff --git a/src/app/board/board.component.html b/src/app/board/board.component.html index 8eb5b5a..e3cd46e 100644 --- a/src/app/board/board.component.html +++ b/src/app/board/board.component.html @@ -3,11 +3,16 @@
-
+
-
+
+

No Boards

+ +

{{ noBoardsMessage }}

+
+ +
+

No Default Board

+ +

+ You have not selected a default board. You may select a + default board in your Settings. +

+

Until then, select a board from the list above.

+
+ +

@@ -173,5 +195,7 @@

+
{{ activeUser | json }}
+
{{ activeBoard | json }}
diff --git a/src/app/board/board.component.ts b/src/app/board/board.component.ts index 6661bc2..f049fee 100644 --- a/src/app/board/board.component.ts +++ b/src/app/board/board.component.ts @@ -1,15 +1,123 @@ import { Component } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; import { Title } from '@angular/platform-browser'; -import { TopNav } from '../shared/index'; +import { DragulaService } from 'ng2-dragula/ng2-dragula'; + +import { + TopNav, + ApiResponse, + Board, + Column, + User, + InlineEdit, + Modal, + Notification, + AuthService, + ModalService, + NotificationsService +} from '../shared/index'; +import { BoardService } from './board.service'; @Component({ selector: 'tb-board', templateUrl: 'app/board/board.component.html' }) -export class Board { - constructor(private title: Title) { +export class BoardDisplay { + private activeUser: User; + private activeBoard: Board; + private boards: Array; + + private boardNavId: number; + private noBoardsMessage: string; + + constructor(private title: Title, + private router: Router, + private active: ActivatedRoute, + private auth: AuthService, + private modal: ModalService, + private boardService: BoardService, + private notes: NotificationsService, + private dragula: DragulaService) { title.setTitle('TaskBoard - Kanban App'); + this.boardNavId = null; + + active.params.subscribe(params => { + let id = +params['id']; // tslint:disable-line + + this.boardNavId = id ? id : null; + this.updateActiveBoard(); + }); + + boardService.getBoards().subscribe((response: ApiResponse) => { + this.updateBoardsList(response.data[1]); + }); + + auth.userChanged.subscribe((user: User) => { + this.updateActiveUser(user); + }); + } + + goToBoard(): void { + if (this.boardNavId === null) { + return; + } + + this.router.navigate(['/boards/' + this.boardNavId]); + } + + private updateBoardsList(boards: Array): void { + let activeBoards: Array = []; + + boards.forEach((board: any) => { + let currentBoard = new Board(+board.id, board.name, + board.is_active === '1', board.ownColumn, + board.ownCategory, board.ownAutoAction, + board.ownIssuetracker, board.sharedUser); + if (currentBoard.is_active) { + activeBoards.push(currentBoard); + } + }); + + this.boards = activeBoards; + + this.boards.forEach(board => { + board.columns.sort((a: Column, b: Column) => { + return +a.position - +b.position; + }); + }); + + this.updateActiveBoard(); + } + + private updateActiveBoard(): void { + if (!this.boardNavId || !this.boards) { + return; + } + + this.boards.forEach(board => { + if (board.id === this.boardNavId) { + this.activeBoard = board; + } + }); + } + + private updateActiveUser(activeUser: User) { + this.activeUser = new User(+activeUser.default_board_id, + activeUser.email, + +activeUser.id, + activeUser.last_login, + +activeUser.security_level, + +activeUser.user_option_id, + activeUser.username, + activeUser.board_access); + + this.noBoardsMessage = 'You are not assigned to any boards. ' + + 'Contact an admin user to be added to a board.'; + + if (+activeUser.security_level === 1) { + this.noBoardsMessage = 'Go to Settings to create a board.'; + } } } diff --git a/src/app/settings/auto-actions/auto-actions.component.ts b/src/app/settings/auto-actions/auto-actions.component.ts index 4651c8c..21cb501 100644 --- a/src/app/settings/auto-actions/auto-actions.component.ts +++ b/src/app/settings/auto-actions/auto-actions.component.ts @@ -1,4 +1,5 @@ import { Component } from '@angular/core'; +import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { ApiResponse, @@ -48,7 +49,8 @@ export class AutoActions { private modal: ModalService, private settings: SettingsService, private actions: AutoActionsService, - private notes: NotificationsService) { + private notes: NotificationsService, + private sanitizer: DomSanitizer) { this.newAction = new AutoAction(); this.boards = []; this.autoActions = []; @@ -230,7 +232,7 @@ export class AutoActions { return desc; } - getTypeDescription(action: AutoAction): string { + getTypeDescription(action: AutoAction): SafeHtml { let desc = '', board = this.getBoard(action.board_id); @@ -267,7 +269,7 @@ export class AutoActions { break; } - return desc; + return this.sanitizer.bypassSecurityTrustHtml(desc); } removeAutoAction(): void { diff --git a/src/app/settings/board-admin/board-admin.component.html b/src/app/settings/board-admin/board-admin.component.html index 004f0d8..e0337fe 100644 --- a/src/app/settings/board-admin/board-admin.component.html +++ b/src/app/settings/board-admin/board-admin.component.html @@ -169,9 +169,10 @@
@@ -198,12 +199,13 @@
@@ -242,12 +244,14 @@
diff --git a/src/app/settings/board-admin/board-admin.component.ts b/src/app/settings/board-admin/board-admin.component.ts index 4ef176b..9d44535 100644 --- a/src/app/settings/board-admin/board-admin.component.ts +++ b/src/app/settings/board-admin/board-admin.component.ts @@ -130,6 +130,11 @@ export class BoardAdmin { this.boardService.removeBoard(this.boardToRemove.id) .subscribe((response: ApiResponse) => { this.handleResponse(response); + + this.settings.getActions() + .subscribe((res: ApiResponse) => { + this.settings.updateActions(res.data[1]); + }); }); } @@ -176,30 +181,24 @@ export class BoardAdmin { this.sortBoards(); } + private cancelEnterKey(event: any): void { + if (event.stopPropagation) { + event.stopPropagation(); + } else { + event.cancelBubble = true; + } + } + private sortBoards(): void { switch (this.sortFilter) { case 'name-asc': this.displayBoards.sort((a: Board, b: Board) => { - let nameA = a.name.toUpperCase(), - nameB = b.name.toUpperCase(); - - return nameA < nameB - ? -1 - : nameA > nameB - ? 1 - : 0; + return a.name.localeCompare(b.name); }); break; case 'name-desc': this.displayBoards.sort((a: Board, b: Board) => { - let nameA = a.name.toUpperCase(), - nameB = b.name.toUpperCase(); - - return nameB < nameA - ? -1 - : nameB > nameA - ? 1 - : 0; + return b.name.localeCompare(a.name); }); break; case 'id-desc': diff --git a/src/app/settings/settings.service.ts b/src/app/settings/settings.service.ts index 3c20dd9..15dd4a2 100644 --- a/src/app/settings/settings.service.ts +++ b/src/app/settings/settings.service.ts @@ -44,7 +44,10 @@ export class SettingsService { } updateBoards(boards: Array): void { - this.boards.next(boards); + this.getActions().subscribe((response: ApiResponse) => { + this.actions.next(response.data[1]); + this.boards.next(boards); + }); } getBoards(): Observable { diff --git a/src/scss/_board.scss b/src/scss/_board.scss index 4332254..dd85d6f 100644 --- a/src/scss/_board.scss +++ b/src/scss/_board.scss @@ -11,6 +11,16 @@ } } +.no-boards { + @include shadow-low; + + background-color: $white; + margin: 1em auto; + padding: 1em; + padding-bottom: .1em; + width: 45%; +} + .board { display: flex; height: calc(100% - 96px);