* watcher slide type implementation, not yet in the loop

* min slide duration adjusted to 5seconds
This commit is contained in:
Dávid Danyi 2018-09-12 17:18:53 +02:00
parent 57f85768eb
commit 80dc5b54e8
12 changed files with 291 additions and 4 deletions

View File

@ -1,5 +1,5 @@
<div class="ui main wide-container dark">
<table *ngIf="commits?.length" class="ui large padded inverted celled2 table">
<table *ngIf="commits?.length" class="ui large padded inverted table">
<thead>
<tr>
<th class="collapsing"><i class="user icon"></i>Owner</th>
@ -43,4 +43,4 @@
</tr>
</tbody>
</table>
</div>
</div>

22
src/app/display/display-routing.module.ts Normal file → Executable file
View File

@ -9,6 +9,8 @@ import { SlideShowComponent } from './slide-show/slide-show.component';
import { SlideResolverService } from '../admin/slide-resolver.service';
import { KanbanBoardComponent } from './kanban-board/kanban-board.component';
import { KanbanService } from './shared';
import {WatchersComponent} from './watchers/watchers.component';
import {WatcherService} from './shared/watcher.service';
const routes: Routes = [
{
@ -78,6 +80,26 @@ const routes: Routes = [
data: {
autoSwitchable: false
}
}, {
path: 'watchers',
component: WatchersComponent,
// canActivate: [AuthGuardService, RoleGuardService],
resolve: {
watchers: WatcherService,
},
data: {
autoSwitchable: true
}
}, {
path: 'watchers-fixed',
component: WatchersComponent,
// canActivate: [AuthGuardService, RoleGuardService],
resolve: {
watchers: WatcherService,
},
data: {
autoSwitchable: false
}
}, {
path: 'settings',
component: SettingsComponent,

View File

@ -17,6 +17,7 @@ import { PriorityColorPipe } from './shared/priority-color.pipe';
import { ShortenTextPipe } from './shared/shorten-text.pipe';
import { KanbanService } from './shared';
import { SlideIframeComponent } from './slide-iframe/slide-iframe.component';
import { WatchersComponent } from './watchers/watchers.component';
@NgModule({
imports: [
@ -39,6 +40,7 @@ import { SlideIframeComponent } from './slide-iframe/slide-iframe.component';
PriorityColorPipe,
ShortenTextPipe,
SlideIframeComponent,
WatchersComponent,
],
providers: [
SlideShowService,

2
src/app/display/settings/settings.component.html Normal file → Executable file
View File

@ -18,7 +18,7 @@
<div class="four wide field">
<label for="slide_interval">Slide duration: {{slideInterval}}ms</label>
<input id="slide_interval" name="slide_interval"
type="range" min="1000" max="120000" step="100"
type="range" min="5000" max="120000" step="250"
[(ngModel)]="slideInterval">
</div>
</div>

2
src/app/display/shared/kanban-board.model.ts Normal file → Executable file
View File

@ -1,4 +1,4 @@
import {KanbanEntry} from "./kanban-entry.model";
import {KanbanEntry} from './kanban-entry.model';
export class KanbanBoard {
public inbox: Array<KanbanEntry>;

View File

@ -0,0 +1,13 @@
export class WatchedIssue {
public issue = '';
public summary = '';
public assignee = '';
public comment: WatchedIssueComment;
}
export class WatchedIssueComment {
public signum = '';
public name = '';
public content = '';
public date = '';
}

View File

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { WatcherService } from './watcher.service';
describe('WatcherService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [WatcherService]
});
});
it('should be created', inject([WatcherService], (service: WatcherService) => {
expect(service).toBeTruthy();
}));
});

View File

@ -0,0 +1,62 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { environment } from '../../../environments/environment';
import { KanbanBoard } from './kanban-board.model';
import { SettingsService } from '../../shared/service/settings.service';
import { TeamService } from '../../shared/service/team.service';
import { flatMap } from 'rxjs/operators';
import {WatchedIssue} from './watched-issue.model';
@Injectable({
providedIn: 'root'
})
export class WatcherService {
private url = environment.apiUrl + '/api/watched';
private cachedWatchers: Array<WatchedIssue> = [];
constructor(private httpService: HttpClient,
private teamService: TeamService,
private settingService: SettingsService) {
}
/**
* Returns an observable instance to the kanban board api
* Reloads team data before, to refresh team config
*
* @returns {Observable<KanbanBoard>}
*/
public getList(): Observable<Array<WatchedIssue>> {
return this.teamService.get(this.settingService.team.id).pipe(
flatMap(() => this.httpService.get<Array<WatchedIssue>>(`${this.url}/${this.settingService.team.id}`))
);
}
/**
* Route preload resolver
*
* @param {ActivatedRouteSnapshot} route
* @returns {Promise<KanbanBoard>}
*/
public resolve(route: ActivatedRouteSnapshot): Promise<Array<WatchedIssue> | boolean> {
return this.getList().toPromise().then(result => result ? result : false);
}
/**
* Reload the board
*/
public reload() {
this.getList().subscribe(result => this.cachedWatchers = result);
}
get watchers(): Array<WatchedIssue> {
return this.cachedWatchers;
}
set watchers(kanbanBoard: Array<WatchedIssue>) {
this.cachedWatchers = kanbanBoard;
}
}

View File

@ -0,0 +1,52 @@
:host {
background-color: #444;
}
/* avatar */
.ui.jira-avatar.image {
width: 45px;
height: auto;
/*font-size: 1em;*/
margin-right: 4px;
margin-bottom: 0;
}
.ui.jira-avatar.image > img {
border-radius: 4px;
max-width: 45px;
height: auto;
}
/* items */
.ui.items .item .header {
color: white;
}
.ui.items .item .meta {
color: lightgray;
}
/* comments */
.ui.comments .comment .metadata {
color: lightgray;
}
.ui.comments .comment .text {
color: white;
}
.ui.comments .comment .author {
color: white;
}
/* header */
h1.massive {
font-size: 72px;
position: absolute;
top: calc(50% - 157px);
left: calc(50% - 541px);
}
.ui.comments {
max-width: initial;
}

View File

@ -0,0 +1,48 @@
<div class="ui main wide-container dark">
<table class="ui large padded inverted celled2 table" *ngIf="watchers.length">
<thead>
<tr>
<th class="collapsing"><i class="user icon"></i>Assignee</th>
<th><i class="clock outline icon"></i>Issue</th>
<th><i class="sticky note outline icon"></i>Last comment</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let issue of watchers">
<td class="collapsing">
<div class="ui jira-avatar image">
<img src="{{avatarUrl(issue.assignee)}}" [title]="issue.assignee">
</div>
</td>
<td class="five wide">
<div class="ui items">
<div class="item">
<div class="content">
<a class="header">{{issue.issue}}</a>
<div class="meta">{{issue.summary}}</div>
</div>
</div>
</div>
</td>
<td>
<div class="ui fluid comments">
<div class="comment">
<a class="avatar"><img src="{{avatarUrl(issue.comment.signum)}}"></a>
<div class="content">
<span class="author">{{issue.comment.name}}</span>
<div class="metadata"><span class="date">{{issue.comment.date}}</span></div>
<div class="text">{{issue.comment.content}}</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
<div *ngIf="!watchers.length">
<h1 class="ui massive green center aligned icon header">
<i class="ui massive check circle outline icon"></i>
<div class="content">No watched item needs attention.</div>
</h1>
</div>
</div>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { WatchersComponent } from './watchers.component';
describe('WatchersComponent', () => {
let component: WatchersComponent;
let fixture: ComponentFixture<WatchersComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ WatchersComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(WatchersComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,48 @@
import {Component, HostBinding, OnInit} from '@angular/core';
import { Title } from '@angular/platform-browser';
import { ActivatedRoute } from '@angular/router';
import { SettingsService } from '../../shared/service/settings.service';
import {slideInOutAnimation} from '../../shared/slide-in-out-animation';
import {WatcherService} from '../shared/watcher.service';
import {WatchedIssue} from '../shared/watched-issue.model';
import {environment} from '../../../environments/environment';
const DEFAULT_AVATAR = '/assets/riddler.png';
@Component({
selector: 'app-watchers',
templateUrl: './watchers.component.html',
styleUrls: ['./watchers.component.css'],
animations: [slideInOutAnimation]
})
export class WatchersComponent implements OnInit {
@HostBinding('@slideInOutAnimation')
slideIn = true;
constructor(private titleService: Title,
private route: ActivatedRoute,
private watcherService: WatcherService,
private settingService: SettingsService) { }
ngOnInit() {
this.titleService.setTitle(`${this.settingService.team.name} : Watched issue activity`);
this.route.data.subscribe((data: {
watchers: Array<WatchedIssue>,
}) => {
this.watchers = data.watchers;
});
}
get watchers(): Array<WatchedIssue> {
return this.watcherService.watchers;
}
set watchers(watchers: Array<WatchedIssue>) {
this.watcherService.watchers = watchers;
}
public avatarUrl(signum: string): string {
return environment.apiUrl + (signum ? `/avatars/${signum}` : DEFAULT_AVATAR);
}
}