* watcher slide type implementation, not yet in the loop
* min slide duration adjusted to 5seconds
This commit is contained in:
parent
57f85768eb
commit
80dc5b54e8
4
src/app/display/commit-tracker/commit-tracker.component.html
Normal file → Executable file
4
src/app/display/commit-tracker/commit-tracker.component.html
Normal file → Executable file
@ -1,5 +1,5 @@
|
|||||||
<div class="ui main wide-container dark">
|
<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>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="collapsing"><i class="user icon"></i>Owner</th>
|
<th class="collapsing"><i class="user icon"></i>Owner</th>
|
||||||
@ -43,4 +43,4 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
22
src/app/display/display-routing.module.ts
Normal file → Executable file
22
src/app/display/display-routing.module.ts
Normal file → Executable file
@ -9,6 +9,8 @@ import { SlideShowComponent } from './slide-show/slide-show.component';
|
|||||||
import { SlideResolverService } from '../admin/slide-resolver.service';
|
import { SlideResolverService } from '../admin/slide-resolver.service';
|
||||||
import { KanbanBoardComponent } from './kanban-board/kanban-board.component';
|
import { KanbanBoardComponent } from './kanban-board/kanban-board.component';
|
||||||
import { KanbanService } from './shared';
|
import { KanbanService } from './shared';
|
||||||
|
import {WatchersComponent} from './watchers/watchers.component';
|
||||||
|
import {WatcherService} from './shared/watcher.service';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
@ -78,6 +80,26 @@ const routes: Routes = [
|
|||||||
data: {
|
data: {
|
||||||
autoSwitchable: false
|
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',
|
path: 'settings',
|
||||||
component: SettingsComponent,
|
component: SettingsComponent,
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import { PriorityColorPipe } from './shared/priority-color.pipe';
|
|||||||
import { ShortenTextPipe } from './shared/shorten-text.pipe';
|
import { ShortenTextPipe } from './shared/shorten-text.pipe';
|
||||||
import { KanbanService } from './shared';
|
import { KanbanService } from './shared';
|
||||||
import { SlideIframeComponent } from './slide-iframe/slide-iframe.component';
|
import { SlideIframeComponent } from './slide-iframe/slide-iframe.component';
|
||||||
|
import { WatchersComponent } from './watchers/watchers.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@ -39,6 +40,7 @@ import { SlideIframeComponent } from './slide-iframe/slide-iframe.component';
|
|||||||
PriorityColorPipe,
|
PriorityColorPipe,
|
||||||
ShortenTextPipe,
|
ShortenTextPipe,
|
||||||
SlideIframeComponent,
|
SlideIframeComponent,
|
||||||
|
WatchersComponent,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
SlideShowService,
|
SlideShowService,
|
||||||
|
|||||||
2
src/app/display/settings/settings.component.html
Normal file → Executable file
2
src/app/display/settings/settings.component.html
Normal file → Executable file
@ -18,7 +18,7 @@
|
|||||||
<div class="four wide field">
|
<div class="four wide field">
|
||||||
<label for="slide_interval">Slide duration: {{slideInterval}}ms</label>
|
<label for="slide_interval">Slide duration: {{slideInterval}}ms</label>
|
||||||
<input id="slide_interval" name="slide_interval"
|
<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">
|
[(ngModel)]="slideInterval">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
2
src/app/display/shared/kanban-board.model.ts
Normal file → Executable file
2
src/app/display/shared/kanban-board.model.ts
Normal file → Executable file
@ -1,4 +1,4 @@
|
|||||||
import {KanbanEntry} from "./kanban-entry.model";
|
import {KanbanEntry} from './kanban-entry.model';
|
||||||
|
|
||||||
export class KanbanBoard {
|
export class KanbanBoard {
|
||||||
public inbox: Array<KanbanEntry>;
|
public inbox: Array<KanbanEntry>;
|
||||||
|
|||||||
13
src/app/display/shared/watched-issue.model.ts
Executable file
13
src/app/display/shared/watched-issue.model.ts
Executable 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 = '';
|
||||||
|
}
|
||||||
15
src/app/display/shared/watcher.service.spec.ts
Normal file
15
src/app/display/shared/watcher.service.spec.ts
Normal 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();
|
||||||
|
}));
|
||||||
|
});
|
||||||
62
src/app/display/shared/watcher.service.ts
Executable file
62
src/app/display/shared/watcher.service.ts
Executable 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
52
src/app/display/watchers/watchers.component.css
Executable file
52
src/app/display/watchers/watchers.component.css
Executable 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;
|
||||||
|
}
|
||||||
48
src/app/display/watchers/watchers.component.html
Executable file
48
src/app/display/watchers/watchers.component.html
Executable 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>
|
||||||
25
src/app/display/watchers/watchers.component.spec.ts
Normal file
25
src/app/display/watchers/watchers.component.spec.ts
Normal 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();
|
||||||
|
});
|
||||||
|
});
|
||||||
48
src/app/display/watchers/watchers.component.ts
Executable file
48
src/app/display/watchers/watchers.component.ts
Executable 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user