* 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">
|
||||
<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
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 { 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,
|
||||
|
||||
@ -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
2
src/app/display/settings/settings.component.html
Normal file → Executable 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
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 {
|
||||
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