WIP - Close to done with add/edit board modal
This commit is contained in:
parent
af2186a1ca
commit
f0ba3956d4
@ -20,6 +20,7 @@ let gulp = require('gulp'),
|
||||
|
||||
scssLint = require('gulp-scss-lint'),
|
||||
sass = require('gulp-sass'),
|
||||
cssImport = require('gulp-cssimport'),
|
||||
cssPrefixer = require('gulp-autoprefixer'),
|
||||
cssMinify = require('gulp-cssnano'),
|
||||
|
||||
@ -84,6 +85,7 @@ gulp.task('scss', () => {
|
||||
]
|
||||
}))
|
||||
.pipe(concat('styles.css'))
|
||||
.pipe(cssImport({}))
|
||||
.pipe(cssPrefixer())
|
||||
.pipe(gulp.dest('dist/css/'));
|
||||
});
|
||||
@ -127,8 +129,11 @@ gulp.task('system-build', ['tsc'], () => {
|
||||
});
|
||||
|
||||
gulp.task('minify', () => {
|
||||
// jsMinify options object is temporary due to problem in Angular RC5
|
||||
let js = gulp.src('dist/js/**/*.js')
|
||||
.pipe(jsMinify())
|
||||
.pipe(jsMinify({
|
||||
mangle: { screw_ie8 : true, keep_fnames: true }
|
||||
}))
|
||||
.pipe(gulp.dest('dist/js/'));
|
||||
|
||||
let css = gulp.src('dist/css/styles.css')
|
||||
|
@ -42,12 +42,14 @@
|
||||
"chartist-plugin-tooltip": "git+https://github.com/Globegitter/chartist-plugin-tooltip.git",
|
||||
"core-js": "^2.4.1",
|
||||
"del": "^2.2.1",
|
||||
"dragula": "^3.7.1",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-autoprefixer": "^3.1.0",
|
||||
"gulp-chmod": "^1.3.0",
|
||||
"gulp-composer": "^0.4.0",
|
||||
"gulp-concat": "^2.6.0",
|
||||
"gulp-coverage": "^0.3.38",
|
||||
"gulp-cssimport": "^3.1.0",
|
||||
"gulp-cssnano": "^2.1.2",
|
||||
"gulp-imagemin": "^3.0.2",
|
||||
"gulp-mocha": "^3.0.0",
|
||||
@ -58,6 +60,7 @@
|
||||
"gulp-uglify": "^2.0.0",
|
||||
"gulp-util": "^3.0.7",
|
||||
"merge-stream": "^1.0.0",
|
||||
"ng2-dragula": "^1.1.10",
|
||||
"reflect-metadata": "^0.1.8",
|
||||
"rxjs": "5.0.0-beta.6",
|
||||
"scss-base": "^1.1.6",
|
||||
|
78
src/app/settings/board-settings/board-data.model.ts
Normal file
78
src/app/settings/board-settings/board-data.model.ts
Normal file
@ -0,0 +1,78 @@
|
||||
export class BoardData {
|
||||
constructor(public title = '',
|
||||
public boardName = '',
|
||||
public columns = [],
|
||||
public categories = [],
|
||||
public issueTrackers = [],
|
||||
public users = [],
|
||||
public categoryDefaultColor = '#ffffe0',
|
||||
public newColumnName = '',
|
||||
public newCategoryName = '',
|
||||
public issueTrackerUrl = '',
|
||||
public issueTrackerBugId = '') { }
|
||||
|
||||
addColumn(): void {
|
||||
if (this.newColumnName === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.columns.push({ name: this.newColumnName });
|
||||
this.newColumnName = '';
|
||||
}
|
||||
|
||||
removeColumn(column): void {
|
||||
let index = this.columns.indexOf(column);
|
||||
|
||||
if (index === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.columns.splice(index, 1);
|
||||
}
|
||||
|
||||
addCategory(): void {
|
||||
if (this.newCategoryName === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.categories.push({
|
||||
name: this.newCategoryName,
|
||||
defaultColor: this.categoryDefaultColor
|
||||
});
|
||||
this.newCategoryName = '';
|
||||
}
|
||||
|
||||
removeCategory(category): void {
|
||||
let index = this.categories.indexOf(category);
|
||||
|
||||
if (index === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.categories.splice(index, 1);
|
||||
}
|
||||
|
||||
addIssueTracker(): void {
|
||||
if (this.issueTrackerUrl === '' || this.issueTrackerBugId === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.issueTrackers.push({
|
||||
url: this.issueTrackerUrl,
|
||||
bugId: this.issueTrackerBugId
|
||||
});
|
||||
this.issueTrackerUrl = '';
|
||||
this.issueTrackerBugId = '';
|
||||
}
|
||||
|
||||
removeIssueTracker(tracker): void {
|
||||
let index = this.issueTrackers.indexOf(tracker);
|
||||
|
||||
if (index === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.issueTrackers.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
@ -63,8 +63,8 @@
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<a href=""><i class="icon icon-edit"></i></a>
|
||||
<a href=""><i class="icon icon-trash-empty"></i></a>
|
||||
<a href="" title="Edit Board"><i class="icon icon-edit color-primary"></i></a>
|
||||
<a href="" title="Remove Board"><i class="icon icon-trash-empty color-secondary"></i></a>
|
||||
<label><input type="checkbox" checked> Active</label>
|
||||
</td>
|
||||
</tr>
|
||||
@ -82,8 +82,8 @@
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<a href=""><i class="icon icon-edit"></i></a>
|
||||
<a href=""><i class="icon icon-trash-empty"></i></a>
|
||||
<a href="" title="Edit Board"><i class="icon icon-edit color-primary"></i></a>
|
||||
<a href="" title="Remove Board"><i class="icon icon-trash-empty color-secondary"></i></a>
|
||||
<label><input type="checkbox" checked> Active</label>
|
||||
</td>
|
||||
</tr>
|
||||
@ -104,27 +104,118 @@
|
||||
<input type="text" name="board-name" placeholder="Board Name"
|
||||
[(ngModel)]="modalProps.boardName">
|
||||
</label>
|
||||
|
||||
<div class="half-modal">
|
||||
<label>Columns</label>
|
||||
<p>TODO: Display existing columns</p>
|
||||
<ul class="modal-list" [hidden]="!modalProps.columns.length"
|
||||
[dragula]="'columns-bag'" [dragulaModel]="modalProps.columns">
|
||||
<li *ngFor="let column of modalProps.columns">
|
||||
<i class="icon icon-resize-vertical"></i>
|
||||
{{ column.name }}
|
||||
<span class="actions">
|
||||
<i class="icon icon-edit color-primary"></i>
|
||||
<i class="icon icon-trash-empty color-secondary"
|
||||
(click)="modalProps.removeColumn(column)"></i>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="quick-add">
|
||||
<input type="text" name="new-column"
|
||||
placeholder="Column Name" [(ngModel)]="modalProps.newColumnName">
|
||||
<button class="flat" (click)="addColumn()">
|
||||
<i class="icon icon-plus"></i>
|
||||
</button>
|
||||
<form>
|
||||
<input type="text" name="new-column"
|
||||
placeholder="Column Name"
|
||||
[(ngModel)]="modalProps.newColumnName">
|
||||
<button type="submit" class="flat" title="Add Column"
|
||||
(click)="modalProps.addColumn()">
|
||||
<i class="icon icon-plus"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="half-modal">
|
||||
<label>Categories</label>
|
||||
<p>TODO: List existing categories</p>
|
||||
<div class="quick-add">
|
||||
<input type="text" name="new-category" placeholder="Category Name"
|
||||
[(ngModel)]="modalProps.newCategoryName">
|
||||
<button class="flat" (click)="addCategory()">
|
||||
<i class="icon icon-plus"></i>
|
||||
</button>
|
||||
<ul *ngIf="modalProps.categories.length" class="modal-list">
|
||||
<li *ngFor="let category of modalProps.categories">
|
||||
{{ category.name }}
|
||||
<span class="actions">
|
||||
<span class="badge" title="Default Task Color"
|
||||
[style.background-color]="getColor(category)"></span>
|
||||
<i class="icon icon-edit color-primary"></i>
|
||||
<i class="icon icon-trash-empty color-secondary"
|
||||
(click)="modalProps.removeCategory(category)"></i>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="quick-add categories">
|
||||
<form>
|
||||
<input type="text" name="new-category"
|
||||
placeholder="Category Name"
|
||||
[(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()">
|
||||
<i class="icon icon-plus"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div class="issue-trackers">
|
||||
<label>
|
||||
Issue Trackers
|
||||
<i class="icon icon-help-circled"
|
||||
alt="Example URL: https://github.com/kiswa/TaskBoard/issues/%BUGID\1%
|
||||
Example RegExp: (?:Issue)?#(\d+)"></i>
|
||||
</label>
|
||||
<ul *ngIf="modalProps.issueTrackers.length" class="modal-list">
|
||||
<li *ngFor="let tracker of modalProps.issueTrackers">
|
||||
{{ tracker.url }} | {{ tracker.bugId }}
|
||||
<span class="actions">
|
||||
<i class="icon icon-edit color-primary"></i>
|
||||
<i class="icon icon-trash-empty color-secondary"
|
||||
(click)="modalProps.removeIssueTracker(tracker)"></i>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<form>
|
||||
<input type="text" name="issue-tracker"
|
||||
placeholder="Issue Tracker URL - use %BUGID% as placeholder"
|
||||
[(ngModel)]="modalProps.issueTrackerUrl">
|
||||
<input type="text" name="issue-tracker-bug-id"
|
||||
placeholder="BUGID RegExp"
|
||||
[(ngModel)]="modalProps.issueTrackerBugId">
|
||||
<button type="submit" class="flat" title="Add Issue Tracker"
|
||||
(click)="modalProps.addIssueTracker()">
|
||||
<i class="icon icon-plus"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="users">
|
||||
<label>Select Users</label>
|
||||
<br><strong>TODO: List users with checkboxes</strong>
|
||||
<p>
|
||||
<strong>*</strong> Including a Board Admin, makes
|
||||
them an admin of this board.<br>
|
||||
<em>Administrators have access to all boards and are
|
||||
not listed here.</em>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<button (click)="addBoard()">
|
||||
<i class="icon icon-plus"></i>
|
||||
Add Board
|
||||
</button>
|
||||
<button class="flat" (click)="modal.close(MODAL_ID)">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</tb-modal>
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import { Dragula, DragulaService } from 'ng2-dragula/ng2-dragula';
|
||||
|
||||
import {
|
||||
ApiResponse,
|
||||
User,
|
||||
@ -9,24 +11,26 @@ import {
|
||||
NotificationsService,
|
||||
AuthService
|
||||
} from '../../shared/index';
|
||||
import { BoardData } from './board-data.model';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-board-settings',
|
||||
templateUrl: 'app/settings/board-settings/board-settings.component.html',
|
||||
directives: [ Modal ]
|
||||
directives: [ Modal, Dragula ],
|
||||
viewProviders: [ DragulaService ]
|
||||
})
|
||||
export class BoardSettings {
|
||||
private activeUser: User;
|
||||
private loading = true;
|
||||
private modalProps;
|
||||
private modalProps: BoardData;
|
||||
|
||||
private MODAL_ID: string;
|
||||
|
||||
constructor(private auth: AuthService, private modal: ModalService) {
|
||||
constructor(private auth: AuthService, private modal: ModalService,
|
||||
private dragula: DragulaService) {
|
||||
this.MODAL_ID = 'board-addedit-form';
|
||||
this.modalProps = {
|
||||
boardName: ''
|
||||
};
|
||||
|
||||
this.modalProps = new BoardData();
|
||||
|
||||
auth.userChanged
|
||||
.subscribe(activeUser => {
|
||||
@ -34,11 +38,30 @@ export class BoardSettings {
|
||||
});
|
||||
}
|
||||
|
||||
ngAfterContentInit() {
|
||||
let ul = document.getElementsByClassName('modal-list')[0];
|
||||
|
||||
this.dragula.setOptions('columns-bag', {
|
||||
moves: (el, container, handle) => {
|
||||
return handle.classList.contains('icon-resize-vertical');
|
||||
},
|
||||
mirrorContainer: ul
|
||||
});
|
||||
}
|
||||
|
||||
private getColor(category: any): string {
|
||||
return category.defaultColor;
|
||||
}
|
||||
|
||||
private showModal(title: string): void {
|
||||
let isAdd = (title === 'Add');
|
||||
this.modalProps = {
|
||||
title: title
|
||||
};
|
||||
|
||||
if (isAdd) {
|
||||
this.modalProps = new BoardData(title);
|
||||
} else {
|
||||
// TODO: Load board data in constructor
|
||||
this.modalProps = new BoardData(title);
|
||||
}
|
||||
|
||||
this.modal.open(this.MODAL_ID);
|
||||
}
|
||||
|
@ -29,13 +29,21 @@
|
||||
<td>Example Board</td>
|
||||
<td>Item assigned to user: admin</td>
|
||||
<td>Set item color: #debee8</td>
|
||||
<td><a href="#"><i class="icon icon-trash-empty"></i></a></td>
|
||||
<td>
|
||||
<a href="#" title="Remove Automatic Action">
|
||||
<i class="icon icon-trash-empty color-secondary"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Example Board</td>
|
||||
<td>Item moved to column: Col3</td>
|
||||
<td>Set item color: #debee8</td>
|
||||
<td><a href="#"><i class="icon icon-trash-empty"></i></a></td>
|
||||
<td>
|
||||
<a href="#" title="Remove Automatic Action">
|
||||
<i class="icon icon-trash-empty color-secondary"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@ -86,7 +94,10 @@
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<button class="right">Add Action</button>
|
||||
<button class="right" disabled>
|
||||
<i class="icon icon-plus"></i>
|
||||
Add Action
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
@ -79,7 +79,7 @@
|
||||
<label>
|
||||
Default Board
|
||||
<i *ngIf="modalProps.title === 'Add'"
|
||||
title="Selecting a default board adds the user to that board."
|
||||
alt="Selecting a default board adds the user to that board."
|
||||
class="icon icon-help-circled"></i>
|
||||
<select>
|
||||
<option>TODO</option>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div *ngIf="isOpen">
|
||||
<div [hidden]="!isOpen">
|
||||
<div class="modal-overlay" (click)="close(true)"></div>
|
||||
|
||||
<div class="modal" [ngClass]="{ wide: wide }">
|
||||
|
@ -114,8 +114,8 @@
|
||||
|
||||
.badge {
|
||||
font-size: .5em;
|
||||
margin-right: -3px;
|
||||
margin-top: 3px;
|
||||
margin-right: -2px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,6 +90,25 @@ button {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.icon-help-circled {
|
||||
position: relative;
|
||||
|
||||
&:hover:after {
|
||||
@include shadow-high;
|
||||
|
||||
background-color: $white;
|
||||
border: 1px solid $color-border;
|
||||
content: attr(alt);
|
||||
left: 20px;
|
||||
min-width: 250px;
|
||||
padding: 7px;
|
||||
position: absolute;
|
||||
text-align: left;
|
||||
top: -1em;
|
||||
z-index: 100;
|
||||
}
|
||||
}
|
||||
|
||||
.color-primary {
|
||||
color: $color-primary;
|
||||
}
|
||||
@ -107,6 +126,10 @@ button {
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
@include clearfix;
|
||||
}
|
||||
|
||||
.row {
|
||||
@include row();
|
||||
|
||||
@ -130,6 +153,7 @@ button {
|
||||
}
|
||||
|
||||
.badge {
|
||||
border: 1px solid $color-border;
|
||||
background-color: $color-tertiary;
|
||||
border-radius: 33%;
|
||||
box-shadow: inset 1px 1px rgba(0, 0, 0, .1);
|
||||
|
@ -3,14 +3,11 @@
|
||||
|
||||
margin: 7px 1em;
|
||||
|
||||
.activity-log {
|
||||
margin: 7px;
|
||||
margin-right: 0;
|
||||
.quick-add {
|
||||
padding: 0;
|
||||
|
||||
button {
|
||||
float: right;
|
||||
font-size: .9em;
|
||||
padding: 3px 5px;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,12 +17,17 @@
|
||||
|
||||
.half-modal {
|
||||
float: left;
|
||||
margin-right: 1%;
|
||||
margin-right: 2%;
|
||||
width: 49%;
|
||||
|
||||
&:last-of-type {
|
||||
&:nth-of-type(2) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
margin-top: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.no-bottom-margin {
|
||||
@ -44,6 +46,105 @@
|
||||
}
|
||||
}
|
||||
|
||||
.categories {
|
||||
[type="text"] {
|
||||
width: calc(100% - 84px);
|
||||
}
|
||||
|
||||
[type="color"] {
|
||||
cursor: pointer;
|
||||
height: 36px;
|
||||
margin-left: 2px;
|
||||
vertical-align: bottom;
|
||||
width: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.issue-trackers {
|
||||
label {
|
||||
display: inline-block;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
[type="text"] {
|
||||
&:first-of-type {
|
||||
width: 380px;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
margin-left: 2px;
|
||||
width: 148px;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
height: 36px;
|
||||
margin-left: 2px;
|
||||
padding: 9px;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
.users {
|
||||
label {
|
||||
display: inline-block;
|
||||
margin-top: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.gu-mirror {
|
||||
@include shadow-high;
|
||||
|
||||
background: $white;
|
||||
display: block;
|
||||
// To override default opacity settings
|
||||
filter: alpha(opacity=100);
|
||||
opacity: 1;
|
||||
|
||||
.actions {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-list {
|
||||
border: 1px solid $color-border;
|
||||
border-radius: 3px;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
margin-bottom: 1em;
|
||||
padding: 0;
|
||||
|
||||
li {
|
||||
border-bottom: 1px solid $color-border;
|
||||
padding: 0 7px;
|
||||
|
||||
&:last-of-type {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.badge {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.icon-trash-empty,
|
||||
.icon-edit {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-resize-vertical {
|
||||
border-right: 1px solid $color-border;
|
||||
cursor: move;
|
||||
margin-left: -5px;
|
||||
margin-right: .5em;
|
||||
width: 1.5em;
|
||||
}
|
||||
|
||||
section {
|
||||
ul {
|
||||
border: 1px solid lighten($color-border, 10%);
|
||||
@ -66,7 +167,7 @@
|
||||
|
||||
.badge {
|
||||
float: right;
|
||||
margin-top: 4px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,9 @@
|
||||
@import 'chartist-settings';
|
||||
@import 'chartist';
|
||||
|
||||
// dragula
|
||||
@import '../../node_modules/dragula/dist/dragula.css';
|
||||
|
||||
// Local styles
|
||||
@import 'core';
|
||||
@import 'login';
|
||||
|
@ -1,13 +1,16 @@
|
||||
(function(global) {
|
||||
var map = {
|
||||
'app': 'build',
|
||||
'rxjs': 'node_modules/rxjs',
|
||||
'@angular': 'node_modules/@angular'
|
||||
'app': 'build',
|
||||
'dragula': 'node_modules/dragula/dist/dragula.js',
|
||||
'ng2-dragula': 'node_modules/ng2-dragula',
|
||||
'rxjs': 'node_modules/rxjs',
|
||||
'@angular': 'node_modules/@angular'
|
||||
};
|
||||
|
||||
var packages = {
|
||||
'app': { main: 'main.js', defaultExtension: 'js' },
|
||||
'rxjs': { defaultExtension: 'js' }
|
||||
'app': { main: 'main.js', defaultExtension: 'js' },
|
||||
'rxjs': { defaultExtension: 'js' },
|
||||
'ng2-dragula': { defaultExtension: 'js' }
|
||||
};
|
||||
|
||||
var angularPackages = [
|
||||
|
Reference in New Issue
Block a user