Initial boards component work.

This commit is contained in:
kiswa 2017-02-03 23:23:45 +00:00
parent 4d255af99e
commit 5c019bcaf1
9 changed files with 191 additions and 34 deletions

View File

@ -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,

View File

@ -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,

View File

@ -3,11 +3,16 @@
<div class="board-nav">
<label>
Select Board:
<select>
<option>Board Name Here</option>
<select [(ngModel)]="boardNavId"
(change)="goToBoard()">
<option [ngValue]="null">Select Board...</option>
<option *ngFor="let board of boards"
[ngValue]="board.id">
{{ board.name }}
</option>
</select>
</label>
<div class="right">
<div class="right" *ngIf="activeBoard">
<label>
Hide Filtered Items:
<input type="checkbox">
@ -27,7 +32,24 @@
</div>
</div>
<div class="board">
<div class="no-boards center" *ngIf="!boards || boards.length === 0">
<h1>No Boards</h1>
<p>{{ noBoardsMessage }}</p>
</div>
<div class="no-boards center"
*ngIf="!activeBoard && !activeUser.default_board_id">
<h1>No Default Board</h1>
<p>
You have not selected a default board. You may select a
default board in your Settings.
</p>
<p>Until then, select a board from the list above.</p>
</div>
<div class="board" *ngIf="activeBoard">
<div class="column">
<h3>
<span class="icon icon-minus-squared-alt" title="Collapse All Tasks"></span>
@ -173,5 +195,7 @@
<button class="flat"><i class="icon icon-plus"></i></button>
</div>
</div>
<pre><code>{{ activeUser | json }}</code></pre>
<pre><code>{{ activeBoard | json }}</code></pre>
</div>

View File

@ -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<Board>;
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<any>): void {
let activeBoards: Array<Board> = [];
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.';
}
}
}

View File

@ -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 {

View File

@ -169,9 +169,10 @@
<form>
<input type="text" name="new-column"
placeholder="Column Name"
(keyup.enter)="cancelEnterKey($event)"
[(ngModel)]="modalProps.newColumnName">
<button type="submit" class="flat" title="Add Column"
(click)="modalProps.addColumn()">
(click)="modalProps.addColumn($event)">
<i class="icon icon-plus"></i>
</button>
</form>
@ -198,12 +199,13 @@
<form>
<input type="text" name="new-category"
placeholder="Category Name"
(keyup.enter)="cancelEnterKey($event)"
[(ngModel)]="modalProps.newCategoryName">
<input type="color" name="category-default-color"
title="Default Task Color"
[(ngModel)]="modalProps.categoryDefaultColor">
<button type="submit" class="flat" title="Add Category"
(click)="modalProps.addCategory()">
(click)="modalProps.addCategory($event)">
<i class="icon icon-plus"></i>
</button>
</form>
@ -242,12 +244,14 @@
<form>
<input type="text" name="issue-tracker"
placeholder="Issue Tracker URL - use %BUGID% as placeholder"
(keyup.enter)="cancelEnterKey($event)"
[(ngModel)]="modalProps.issueTrackerUrl">
<input type="text" name="issue-tracker-bug-id"
placeholder="BUGID RegExp"
(keyup.enter)="cancelEnterKey($event)"
[(ngModel)]="modalProps.issueTrackerBugId">
<button type="submit" class="flat" title="Add Issue Tracker"
(click)="modalProps.addIssueTracker()">
(click)="modalProps.addIssueTracker($event)">
<i class="icon icon-plus"></i>
</button>
</form>

View File

@ -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':

View File

@ -44,7 +44,10 @@ export class SettingsService {
}
updateBoards(boards: Array<Board>): void {
this.boards.next(boards);
this.getActions().subscribe((response: ApiResponse) => {
this.actions.next(response.data[1]);
this.boards.next(boards);
});
}
getBoards(): Observable<ApiResponse> {

View File

@ -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);