Context Menu - Task and Column initial functionality

This commit is contained in:
kiswa 2017-05-02 21:06:38 +00:00
parent c0322d9ed9
commit 13b9bd5034
13 changed files with 73 additions and 19 deletions

View File

@ -150,11 +150,11 @@ Because I like seeing the numbers.
Language | Files | Blank | Comment | Code Language | Files | Blank | Comment | Code
-------------|--------:|---------:|--------:|---------: -------------|--------:|---------:|--------:|---------:
TypeScript | 57 | 610 | 25 | 2855 TypeScript | 58 | 629 | 26 | 2939
PHP | 18 | 559 | 19 | 1743 PHP | 18 | 558 | 19 | 1740
HTML | 19 | 130 | 9 | 1157 HTML | 19 | 131 | 9 | 1160
SASS | 14 | 215 | 12 | 976 SASS | 14 | 221 | 12 | 1005
__SUM:__ | __108__ | __1514__ | __65__ | __6731__ __SUM:__ | __109__ | __1539__ | __66__ | __6848__
Command: `cloc --exclude-dir=vendor --exclude-ext=json src/` Command: `cloc --exclude-dir=vendor --exclude-ext=json src/`

View File

@ -18,6 +18,7 @@ import {
Notifications, Notifications,
TopNav, TopNav,
AuthService, AuthService,
ContextMenuService,
ModalService, ModalService,
NotificationsService, NotificationsService,
StringsService StringsService
@ -39,6 +40,7 @@ import { BoardService } from './board/board.service';
Title, Title,
AuthService, AuthService,
BoardService, BoardService,
ContextMenuService,
ModalService, ModalService,
NotificationsService, NotificationsService,
StringsService StringsService

View File

@ -12,6 +12,7 @@ import {
User, User,
Notification, Notification,
AuthService, AuthService,
ContextMenuService,
NotificationsService, NotificationsService,
StringsService StringsService
} from '../shared/index'; } from '../shared/index';
@ -38,6 +39,7 @@ export class BoardDisplay implements OnInit {
private active: ActivatedRoute, private active: ActivatedRoute,
private auth: AuthService, private auth: AuthService,
private boardService: BoardService, private boardService: BoardService,
private menuService: ContextMenuService,
private notes: NotificationsService, private notes: NotificationsService,
private stringsService: StringsService, private stringsService: StringsService,
private dragula: DragulaService) { private dragula: DragulaService) {

View File

@ -29,7 +29,7 @@
<div class="tasks"> <div class="tasks">
<tb-task class="task-container" *ngFor="let task of columnData.ownTask" <tb-task class="task-container" *ngFor="let task of columnData.ownTask"
[task]="task"></tb-task> [task]="task" [add-task]="getShowModalFunction()"></tb-task>
</div> </div>
<tb-context-menu [menu-items]="contextMenuItems"></tb-context-menu> <tb-context-menu [menu-items]="contextMenuItems"></tb-context-menu>

View File

@ -37,7 +37,7 @@ export class ColumnDisplay implements OnInit {
private userOptions: UserOptions; private userOptions: UserOptions;
private tasks: Array<Task>; private tasks: Array<Task>;
private contextMenuItems: Array<ContextMenuItem> = []; private contextMenuItems: Array<ContextMenuItem>;
private MODAL_ID: string; private MODAL_ID: string;
private modalProps: Task; private modalProps: Task;
@ -54,7 +54,10 @@ export class ColumnDisplay implements OnInit {
this.tasks = []; this.tasks = [];
this.collapseTasks = false; this.collapseTasks = false;
this.contextMenuItems.push(new ContextMenuItem('Add New Task')); this.contextMenuItems = [
new ContextMenuItem('Add New Task',
this.getShowModalFunction())
];
this.MODAL_ID = 'add-task-form-'; this.MODAL_ID = 'add-task-form-';
this.modalProps = new Task(); this.modalProps = new Task();
@ -142,6 +145,10 @@ export class ColumnDisplay implements OnInit {
}); });
} }
private getShowModalFunction(): Function {
return () => { this.showModal(); };
}
private showModal() { private showModal() {
this.modalProps = new Task(); this.modalProps = new Task();
this.modalProps.column_id = this.columnData.id; this.modalProps.column_id = this.columnData.id;

View File

@ -39,5 +39,6 @@
</span> </span>
</span> </span>
</div> </div>
<tb-context-menu [menu-items]="contextMenuItems"></tb-context-menu>
</div> </div>

View File

@ -1,10 +1,16 @@
import { Component, Input } from '@angular/core'; import {
Component,
Input,
OnInit
} from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import * as Marked from 'marked'; import * as Marked from 'marked';
import * as hljs from 'highlight.js'; import * as hljs from 'highlight.js';
import { import {
ContextMenu,
ContextMenuItem,
Task, Task,
UserOptions, UserOptions,
AuthService AuthService
@ -14,10 +20,12 @@ import {
selector: 'tb-task', selector: 'tb-task',
templateUrl: 'app/board/task/task.component.html' templateUrl: 'app/board/task/task.component.html'
}) })
export class TaskDisplay { export class TaskDisplay implements OnInit {
private userOptions: UserOptions; private userOptions: UserOptions;
private contextMenuItems: Array<ContextMenuItem>;
@Input('task') taskData: Task; @Input('task') taskData: Task;
@Input('add-task') addTask: Function;
constructor(private auth: AuthService, constructor(private auth: AuthService,
private sanitizer: DomSanitizer) { private sanitizer: DomSanitizer) {
@ -28,6 +36,18 @@ export class TaskDisplay {
this.initMarked(); this.initMarked();
} }
ngOnInit() {
this.contextMenuItems = [
new ContextMenuItem('View Task'),
new ContextMenuItem('Edit Task'),
new ContextMenuItem('Delete Task'),
new ContextMenuItem('', null, true),
new ContextMenuItem('Move to Column:', null, false, false),
new ContextMenuItem('', null, true),
new ContextMenuItem('Add New Task', this.addTask)
];
}
getTaskDescription(): SafeHtml { getTaskDescription(): SafeHtml {
return this.sanitizer.bypassSecurityTrustHtml( return this.sanitizer.bypassSecurityTrustHtml(
Marked(this.taskData.description)); Marked(this.taskData.description));

View File

@ -1,7 +1,8 @@
export class ContextMenuItem { export class ContextMenuItem {
constructor(public text: string = '', constructor(public text: string = '',
public action: Function = null, public action: Function = null,
public isSeparator: boolean = false) { public isSeparator: boolean = false,
public canHighlight: boolean = true) {
} }
} }

View File

@ -1,12 +1,15 @@
<div class="context-menu-container" <div class="context-menu-container"
[ngClass]="{ animated: animate, 'menu-open': isOpen }"> [ngClass]="{ animated: animate, 'menu-open': isOpen }">
<div class="menu-item" *ngFor="let item of menuItems"> <div class="menu-item" *ngFor="let item of menuItems"
[ngClass]="{ 'no-highlight': item.isSeparator || !item.canHighlight }"
(click)="callAction(item.action)">
<hr *ngIf="item.isSeparator"> <hr *ngIf="item.isSeparator">
<div *ngIf="!item.isSeparator"> <div *ngIf="!item.isSeparator">
{{ item.text }} {{ item.text }}
</div> </div>
</div> </div>
</div> </div>

View File

@ -5,6 +5,7 @@ import {
} from '@angular/core'; } from '@angular/core';
import { ContextMenuItem } from './context-menu-item.model'; import { ContextMenuItem } from './context-menu-item.model';
import { ContextMenuService } from './context-menu.service';
@Component({ @Component({
selector: 'tb-context-menu', selector: 'tb-context-menu',
@ -16,20 +17,28 @@ export class ContextMenu {
isOpen = false; isOpen = false;
animate = true; animate = true;
constructor(private el: ElementRef) { constructor(private el: ElementRef,
let parentElement = el.nativeElement.parentElement; private menuService: ContextMenuService) {
menuService.registerMenu(this);
el.nativeElement.ownerDocument.addEventListener('click', () => { let parentElement = el.nativeElement.parentElement;
this.isOpen = false;
});
parentElement.oncontextmenu = (event: MouseEvent) => { parentElement.oncontextmenu = (event: MouseEvent) => {
event.preventDefault(); event.preventDefault();
event.stopPropagation();
this.onParentContextMenu(event); this.onParentContextMenu(event);
}; };
} }
callAction(action: Function) {
if (action) {
action();
}
}
private onParentContextMenu(event: MouseEvent) { private onParentContextMenu(event: MouseEvent) {
this.menuService.closeAllMenus();
this.isOpen = true; this.isOpen = true;
let edgeBuffer = 10; let edgeBuffer = 10;

View File

@ -18,7 +18,7 @@ export class ContextMenuService {
this.menus.push(newMenu); this.menus.push(newMenu);
} }
private closeAllMenus() { closeAllMenus() {
this.menus.forEach(menu => { this.menus.forEach(menu => {
menu.isOpen = false; menu.isOpen = false;
}); });

View File

@ -1,2 +1,3 @@
export * from './context-menu.component'; export * from './context-menu.component';
export * from './context-menu-item.model'; export * from './context-menu-item.model';
export * from './context-menu.service';

View File

@ -9,7 +9,7 @@
.context-menu-container { .context-menu-container {
@include shadow-high; @include shadow-high;
background-color: #fff; background-color: $white;
border-radius: 3px; border-radius: 3px;
display: none; display: none;
margin: 2px 0 0; margin: 2px 0 0;
@ -30,6 +30,14 @@
&:hover { &:hover {
background-color: lighten($color-background, 5%); background-color: lighten($color-background, 5%);
} }
&.no-highlight {
cursor: default;
&:hover {
background-color: $white;
}
}
} }
} }