* daily kanban slide lock added

This commit is contained in:
Dávid Danyi 2018-09-11 16:10:47 +02:00
parent aa995e845a
commit 57f85768eb
7 changed files with 86 additions and 15 deletions

19
package-lock.json generated
View File

@ -567,6 +567,14 @@
"semver-intersect": "^1.1.2"
}
},
"@types/date-fns": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@types/date-fns/-/date-fns-2.6.0.tgz",
"integrity": "sha1-sGLKRlYgApCb4MY6ZGftFzE2rME=",
"requires": {
"date-fns": "*"
}
},
"@types/jasmine": {
"version": "2.8.6",
"resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.6.tgz",
@ -2452,9 +2460,9 @@
}
},
"date-fns": {
"version": "2.0.0-alpha.1",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.0.0-alpha.1.tgz",
"integrity": "sha512-4gYdF1rDgv9X/0ko69pt+FgpQtDU5rgqZVmckIOhDicfCSTndwHMhUhLJw+pa4DlPdzIkEBtHg6L6VlQ6ueD1g=="
"version": "1.29.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz",
"integrity": "sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw=="
},
"date-now": {
"version": "0.1.4",
@ -6661,6 +6669,11 @@
"rxjs": "^5.0.1"
},
"dependencies": {
"date-fns": {
"version": "2.0.0-alpha.1",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.0.0-alpha.1.tgz",
"integrity": "sha512-4gYdF1rDgv9X/0ko69pt+FgpQtDU5rgqZVmckIOhDicfCSTndwHMhUhLJw+pa4DlPdzIkEBtHg6L6VlQ6ueD1g=="
},
"rxjs": {
"version": "5.5.7",
"resolved": "http://registry.npmjs.org/rxjs/-/rxjs-5.5.7.tgz",

View File

@ -20,8 +20,10 @@
"@angular/platform-browser": "^6.1.0",
"@angular/platform-browser-dynamic": "^6.1.0",
"@angular/router": "^6.1.0",
"@types/date-fns": "^2.6.0",
"@types/marked": "^0.4.1",
"core-js": "^2.5.4",
"date-fns": "^1.29.0",
"marked": "^0.5.0",
"ng2-semantic-ui": "^0.9.7",
"rxjs": "^6.0.0",

View File

@ -1,6 +1,6 @@
<div class="ui main container">
<h1 class="ui dividing header">Team editor</h1>
<form class="ui form" #teamEditorForm (ngSubmit)="saveTeam()">
<form class="ui form" #teamEditorForm (ngSubmit)="saveTeam(f)" #f="ngForm">
<div class="two fields">
<div class="six wide field" [class.error]="checkError(teamName)">
<label for="team_name">Team name</label>
@ -22,7 +22,37 @@
</div>
</div>
<h4 class="ui dividing header">Column configuration</h4>
<h3 class="ui dividing header">Kanban configuration</h3>
<h4 class="ui dividing header">Daily standup timer</h4>
<div class="three inline fields">
<div class="two wide field">
<div class="ui checkbox">
<input type="checkbox" id="daily_lock_timer" name="daily_lock_timer"
[(ngModel)]="team.dailyLockEnabled">
<label for="daily_lock_timer">Enabled</label>
</div>
</div>
<div class="four wide field" [class.error]="checkError(startTime)">
<label for="daily_start">Starts</label>
<div class="ui left icon input">
<input type="time" id="daily_start" name="daily_start"
min="9:00" max="15:00" [required]="team.dailyLockEnabled"
[(ngModel)]="team.dailyStartTime" #startTime="ngModel">
<i class="time icon"></i>
</div>
</div>
<div class="four wide field" [class.error]="checkError(endTime)">
<label for="daily_end">Ends</label>
<div class="ui left icon input">
<input type="time" id="daily_end" name="daily_end"
min="9:00" max="15:00" [required]="team.dailyLockEnabled"
[(ngModel)]="team.dailyEndTime" #endTime="ngModel">
<i class="time icon"></i>
</div>
</div>
</div>
<h4 class="ui dividing header">Columns</h4>
<div class="four fields">
<div class="six wide field">
<label>Jira status</label>
@ -119,7 +149,7 @@
(click)="removeLabel(label)"></i></span>
</div>
<h4 class="ui dividing header">Team members</h4>
<h3 class="ui dividing header">Team members</h3>
<div class="three inline fields">
<div class="two wide field">
<button type="button" class="ui fluid button"
@ -165,8 +195,8 @@
</table>
<button type="submit" class="ui button"
[class.positive]="canSave"
[class.disabled]="!canSave"><i class="save outline icon"></i>Save changes
[class.positive]="canSave(f)"
[class.disabled]="!canSave(f)"><i class="save outline icon"></i>Save changes
</button>
<a class="ui button"
[routerLink]="['/admin/teams']"><i class="left angle icon"></i>Back to teams list</a>

View File

@ -6,7 +6,7 @@ import { TeamService } from '../../shared/service/team.service';
import { Team } from '../../shared/team';
import { Member } from '../../shared/member';
import { Label } from '../../shared/label';
import {NgModel} from '@angular/forms';
import {NgForm, NgModel} from '@angular/forms';
@Component({
selector: 'app-team-editor',
@ -116,15 +116,15 @@ export class TeamEditorComponent implements OnInit {
}
}
get canSave(): boolean {
return [
public canSave(form: NgForm): boolean {
return form.valid && [
this.team.name.trim(),
this.team.members
].every(field => field.length > 0) && this.team.filterId > 0;
}
public saveTeam() {
if (this.canSave) {
public saveTeam(form: NgForm) {
if (this.canSave(form)) {
this.teamService.persist(this.team).subscribe(
() => this.router.navigate(['/admin/teams'])
);

View File

@ -27,7 +27,7 @@ export class KanbanBoardComponent implements OnInit {
* Set page title, and handle preloaded kanbanBoard data
*/
ngOnInit() {
this.titleService.setTitle('TaurusXFT : Kanban board');
this.titleService.setTitle(`${this.settingService.team.name} : Kanban board`);
this.route.data.subscribe((data: {
kanbanBoard: KanbanBoard,
}) => {

View File

@ -5,8 +5,12 @@ import { Subject, timer, Subscription } from 'rxjs';
import { ActivationStart, Router } from '@angular/router';
import { SlideShowService } from '../../display/slide-show.service';
import { filter, switchMap } from 'rxjs/operators';
import * as isWithinRange from 'date-fns/is_within_range';
import * as min from 'date-fns/min';
import * as max from 'date-fns/max';
const TIMER_UPDATE_POLL_INTERVAL = 30000;
const TIME_SEPARATOR = ':';
@Injectable()
export class TimerService implements OnDestroy {
@ -48,7 +52,10 @@ export class TimerService implements OnDestroy {
}
private changeSlide() {
if (this.autoSwitch) {
if (this.autoSwitch && this.isDuringDailyStandup()) {
this.router.navigate(['/kanban']);
}
if (this.autoSwitch && !this.isDuringDailyStandup()) {
this.slideShowService.nextSlide();
}
this.setSlideTimer(this.settings.slideInterval);
@ -57,4 +64,20 @@ export class TimerService implements OnDestroy {
public setSlideTimer(delay: number) {
this.slideTimerSubject.next(delay);
}
private isDuringDailyStandup(): boolean {
if (this.settings.team.dailyLockEnabled) {
const now = new Date();
const startsParts = this.settings.team.dailyStartTime.split(TIME_SEPARATOR).map(part => +part);
const endsParts = this.settings.team.dailyEndTime.split(TIME_SEPARATOR).map(part => +part);
const times = [
new Date(now.getFullYear(), now.getMonth(), now.getDay(), startsParts[0], startsParts[1]),
new Date(now.getFullYear(), now.getMonth(), now.getDay(), endsParts[0], endsParts[1])
];
const startsAt = min(...times);
const endsAt = max(...times);
return isWithinRange(now, startsAt, endsAt);
}
return false;
}
}

View File

@ -7,6 +7,9 @@ export class Team {
name: String = '';
members: Array<Member> = [];
filterId = 0;
dailyLockEnabled: false;
dailyStartTime: string;
dailyEndTime: string;
backlogColumn: KanbanColumn = new KanbanColumn();
inprogressColumn: KanbanColumn = new KanbanColumn();
verificationColumn: KanbanColumn = new KanbanColumn();