Skip to content

Commit

Permalink
feat (ui): WIP add warnings (#744)
Browse files Browse the repository at this point in the history
  • Loading branch information
sguiheux authored and yesnault committed Jun 20, 2017
1 parent d47cd45 commit 2873a18
Show file tree
Hide file tree
Showing 18 changed files with 275 additions and 99 deletions.
1 change: 0 additions & 1 deletion ui/src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ describe('App: CDS', () => {
expect(compiled.querySelector('#navbar.connected')).toBeFalsy('Nav bar must have connected css class');
}));

// FIXME CACHE NOT INITIALIZE
it('should update cache', fakeAsync(() => {
// Create cache
projectStore.getProjects('key1').subscribe(() => {}).unsubscribe();
Expand Down
3 changes: 2 additions & 1 deletion ui/src/app/app.routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ const routes: Routes = [
{ path: 'home', loadChildren: 'app/views/home/home.module#HomeModule' },
{ path: 'account', loadChildren: 'app/views/account/account.module#AccountModule' },
{ path: 'project', loadChildren: 'app/views/project/project.module#ProjectModule' },
{ path: 'settings', loadChildren: 'app/views/settings/settings.module#SettingsModule' }
{ path: 'settings', loadChildren: 'app/views/settings/settings.module#SettingsModule' },
{ path: 'warnings', loadChildren: 'app/views/warnings/warnings.module#WarningsModule' }
];

export const routing: ModuleWithProviders = RouterModule.forRoot(routes, {
Expand Down
41 changes: 8 additions & 33 deletions ui/src/app/app.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import {NotificationService} from './service/notification/notification.service';
import {AuthentificationStore} from './service/auth/authentification.store';
import {TranslateService} from 'ng2-translate';
import {PipelineStore} from './service/pipeline/pipeline.store';
import {RouterService} from './service/router/router.service';

@Injectable()
export class AppService {

constructor(private _projStore: ProjectStore, private _routeActivated: ActivatedRoute, private _router: Router,
constructor(private _projStore: ProjectStore, private _routeActivated: ActivatedRoute,
private _appStore: ApplicationStore, private _notif: NotificationService, private _authStore: AuthentificationStore,
private _translate: TranslateService, private _pipStore: PipelineStore) {
private _translate: TranslateService, private _pipStore: PipelineStore, private _routerService: RouterService) {
}

updateCache(lastUpdates: Array<ProjectLastUpdates>) {
Expand All @@ -22,7 +23,7 @@ export class AppService {
}

// Get current route params
let params = this.getRouteParams({}, this._routeActivated);
let params = this._routerService.getRouteParams({}, this._routeActivated);

// Get all projects
this._projStore.getProjects().first().subscribe(projects => {
Expand Down Expand Up @@ -104,18 +105,18 @@ export class AppService {
return;
}

plu.pipelines.forEach( p => {
plu.pipelines.forEach(p => {
let pipKey = plu.name + '-' + p.name;
if (!pips.get(pipKey)) {
return;
}

if ( pips.get(pipKey).last_modified < p.last_modified ) {
if (params['key'] && params['key'] === plu.name && params['pipName'] === p.name ) {
if (pips.get(pipKey).last_modified < p.last_modified) {
if (params['key'] && params['key'] === plu.name && params['pipName'] === p.name) {
this._pipStore.externalModification(pipKey);

if (p.username !== this._authStore.getUser().username) {
this._notif.create(this._translate.instant('pipeline_modification', { username: plu.username}));
this._notif.create(this._translate.instant('pipeline_modification', {username: plu.username}));
}

if (params['buildNumber'] || p.username === this._authStore.getUser().username) {
Expand All @@ -129,30 +130,4 @@ export class AppService {
});

}

getRouteParams(params: {}, activatedRoute: ActivatedRoute): {} {
if (activatedRoute) {
if (activatedRoute.snapshot.params) {
if (activatedRoute.snapshot.params['key']) {
params['key'] = activatedRoute.snapshot.params['key'];
}
if (activatedRoute.snapshot.params['pipName']) {
params['pipName'] = activatedRoute.snapshot.params['pipName'];
}
if (activatedRoute.snapshot.params['appName']) {
params['appName'] = activatedRoute.snapshot.params['appName'];
}
if (activatedRoute.snapshot.params['buildNumber']) {
params['buildNumber'] = activatedRoute.snapshot.params['buildNumber'];
}
}

if (activatedRoute.children) {
activatedRoute.children.forEach(c => {
params = this.getRouteParams(params, c);
});
}
}
return params;
}
}
29 changes: 7 additions & 22 deletions ui/src/app/model/warning.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,20 @@ import {Application} from './application.model';
import {Environment} from './environment.model';
import {Pipeline} from './pipeline.model';

export class WarningsUI {
[key: string]: WarningUI;
}

export class WarningUI {
pipelines: WarningsPipeline;
applications: WarningsApplication;
environments: WarningsEnvironment; // Not implemented
pipelines: Map<string, WarningPipeline>;
applications: Map<string, WarningApplication>;
environments: Map<string, WarningEnvironment>; // Not implemented
variables: WarningAPI[]; // Not implemented

constructor() {
this.pipelines = new WarningsPipeline();
this.applications = new WarningsApplication();
this.environments = new WarningsEnvironment();
this.pipelines = new Map<string, WarningPipeline>();
this.applications = new Map<string, WarningApplication>();
this.environments = new Map<string, WarningEnvironment>();
this.variables = new Array<WarningAPI>();
}
}

export class WarningsPipeline {
[name: string]: WarningPipeline;
}

export class WarningPipeline {
parameters: WarningAPI[]; // Not implemented
jobs: WarningAPI[];
Expand All @@ -35,10 +28,6 @@ export class WarningPipeline {
}
}

export class WarningsApplication {
[name: string]: WarningApplication;
}

export class WarningApplication {
variables: WarningAPI[]; // Not implemented
actions: WarningAPI[];
Expand All @@ -49,10 +38,6 @@ export class WarningApplication {
}
}

export class WarningsEnvironment {
[name: string]: WarningEnvironment;
}

export class WarningEnvironment {
variables: WarningAPI[]; // Not implemented

Expand Down
31 changes: 31 additions & 0 deletions ui/src/app/service/router/router.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {Injectable} from '@angular/core';
import {ActivatedRoute} from '@angular/router';

@Injectable()
export class RouterService {

getRouteParams(params: {}, activatedRoute: ActivatedRoute): {} {
if (activatedRoute) {
if (activatedRoute.snapshot.params) {
if (activatedRoute.snapshot.params['key']) {
params['key'] = activatedRoute.snapshot.params['key'];
}
if (activatedRoute.snapshot.params['pipName']) {
params['pipName'] = activatedRoute.snapshot.params['pipName'];
}
if (activatedRoute.snapshot.params['appName']) {
params['appName'] = activatedRoute.snapshot.params['appName'];
}
if (activatedRoute.snapshot.params['buildNumber']) {
params['buildNumber'] = activatedRoute.snapshot.params['buildNumber'];
}
}
if (activatedRoute.children) {
activatedRoute.children.forEach(c => {
params = this.getRouteParams(params, c);
});
}
}
return params;
}
}
3 changes: 3 additions & 0 deletions ui/src/app/service/services.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {NotificationService} from './notification/notification.service';
import {WorkflowService} from './workflow/workflow.service';
import {WorkflowStore} from './workflow/workflow.store';
import {WorkflowRunService} from './workflow/run/workflow.run.service';
import {RouterService} from './router/router.service';

@NgModule({})
export class ServicesModule {
Expand Down Expand Up @@ -73,6 +74,7 @@ export class ServicesModule {
RepoManagerService,
RequirementStore,
RequirementService,
RouterService,
UserService,
VariableService,
WarningStore,
Expand Down Expand Up @@ -123,6 +125,7 @@ export {
ProjectAuditService,
RepoManagerService,
RequirementStore,
RouterService,
UserService,
VariableService,
WarningStore,
Expand Down
24 changes: 12 additions & 12 deletions ui/src/app/service/warning/warning.store.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,23 @@ describe('CDS: Warning Store', () => {

let haveWarnings = false;
warnStore.getWarnings().subscribe( res => {
expect(res['key1']).toBeTruthy('Must have warnings on project key1');
expect(res['key1'].applications['app1']).toBeTruthy('Must have warnings on application app1');
expect(res['key1'].applications['app1'].actions.length).toBe(3, 'App1 must have 3 warnings on jobs');
expect(res.get('key1')).toBeTruthy('Must have warnings on project key1');
expect(res.get('key1').applications.get('app1')).toBeTruthy('Must have warnings on application app1');
expect(res.get('key1').applications.get('app1').actions.length).toBe(3, 'App1 must have 3 warnings on jobs');

expect(res['key1'].pipelines['pip1']).toBeTruthy('Must have warnings on pipeline pip1');
expect(res['key1'].pipelines['pip1'].jobs.length).toBe(1, 'Pip1 must have 1 warning on jobs');
expect(res.get('key1').pipelines.get('pip1')).toBeTruthy('Must have warnings on pipeline pip1');
expect(res.get('key1').pipelines.get('pip1').jobs.length).toBe(1, 'Pip1 must have 1 warning on jobs');

expect(res['key1'].pipelines['pip2']).toBeTruthy('Must have warnings on pipeline pip2');
expect(res['key1'].pipelines['pip2'].jobs.length).toBe(2, 'Pip2 must have 2 warning on jobs');
expect(res.get('key1').pipelines.get('pip2')).toBeTruthy('Must have warnings on pipeline pip2');
expect(res.get('key1').pipelines.get('pip2').jobs.length).toBe(2, 'Pip2 must have 2 warning on jobs');


expect(res['key2']).toBeTruthy('Must have warnings on project key2');
expect(res['key2'].applications['app2']).toBeTruthy('Must have warnings on application app2');
expect(res['key2'].applications['app2'].actions.length).toBe(1, 'App2 must have 1 warning on actions');
expect(res.get('key2')).toBeTruthy('Must have warnings on project key2');
expect(res.get('key2').applications.get('app2')).toBeTruthy('Must have warnings on application app2');
expect(res.get('key2').applications.get('app2').actions.length).toBe(1, 'App2 must have 1 warning on actions');

expect(res['key2'].pipelines['pip3']).toBeTruthy('Must have warnings on pipeline pip2');
expect(res['key2'].pipelines['pip3'].jobs.length).toBe(2, 'Pip3 must have 2 warnings on jobs');
expect(res.get('key2').pipelines.get('pip3')).toBeTruthy('Must have warnings on pipeline pip2');
expect(res.get('key2').pipelines.get('pip3').jobs.length).toBe(2, 'Pip3 must have 2 warnings on jobs');

haveWarnings = true;
});
Expand Down
34 changes: 16 additions & 18 deletions ui/src/app/service/warning/warning.store.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Injectable} from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs/Rx';
import {
WarningsUI, WarningAPI, WarningUI, WarningPipeline, WarningApplication,
WarningAPI, WarningUI, WarningPipeline, WarningApplication,
WarningEnvironment
} from '../../model/warning.model';

Expand All @@ -10,59 +10,57 @@ import {
export class WarningStore {

// List of all project. Use by Navbar
private _warningCache: BehaviorSubject<WarningsUI> = new BehaviorSubject(null);
private _warningCache: BehaviorSubject<Map<string, WarningUI>> = new BehaviorSubject(new Map<string, WarningUI>());

/**
* Get a WarningsUI Observable
* @returns {Observable<WarningsUI>}
*/
getWarnings(): Observable<WarningsUI> {
return new Observable<WarningsUI>(fn => this._warningCache.subscribe(fn));
getWarnings(): Observable<Map<string, WarningUI>> {
return new Observable<Map<string, WarningUI>>(fn => this._warningCache.subscribe(fn));
}

/**
* Update warning Store.
*/
updateWarnings(warnings: WarningAPI[]): void {
let updatedWarnings: WarningsUI = new WarningsUI();
let updatedWarnings: Map<string, WarningUI> = new Map<string, WarningUI>();
warnings.forEach(function (w) {
if (w.project && w.project.key) {

// if not in list, create new warning on the current project
if (!updatedWarnings[w.project.key]) {
updatedWarnings[w.project.key] = new WarningUI();
if (!updatedWarnings.get(w.project.key)) {
updatedWarnings.set(w.project.key, new WarningUI);
}

let warningUI = updatedWarnings[w.project.key];
let warningUI = updatedWarnings.get(w.project.key);

// If warning on pipeline
if (w.pipeline && w.pipeline.name) {
if (!warningUI.pipelines[w.pipeline.name]) {
warningUI.pipelines[w.pipeline.name] = new WarningPipeline();
if (!warningUI.pipelines.get(w.pipeline.name)) {
warningUI.pipelines.set(w.pipeline.name, new WarningPipeline());
}
}

// If warning on application
if (w.application && w.application.name) {
if (!warningUI.applications[w.application.name]) {
warningUI.applications[w.application.name] = new WarningApplication();
if (!warningUI.applications.get(w.application.name)) {
warningUI.applications.set(w.application.name, new WarningApplication());
}
}

// If warning on an action
if (w.action && w.action.name) {
warningUI.pipelines[w.pipeline.name].jobs.push(w);
warningUI.pipelines.get(w.pipeline.name).jobs.push(w);

// If action link to an application
if (w.application && w.application.name) {
warningUI.applications[w.application.name].actions.push(w);
warningUI.applications.get(w.application.name).actions.push(w);
}
}

// If Warning on environment
if (w.environment && w.environment.name) {
if (!warningUI.environments[w.environment.name]) {
warningUI.environments[w.environment.name] = new WarningEnvironment();
if (!warningUI.environments.get(w.environment.name)) {
warningUI.environments.set(w.environment.name, new WarningEnvironment());
}
}

Expand Down
12 changes: 12 additions & 0 deletions ui/src/app/shared/pipes/map.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {Pipe, PipeTransform} from '@angular/core';

@Pipe({name: 'forMap'})
export class ForMapPipe implements PipeTransform {
transform(m: Map<any, any>): Array<{key, value}> {
let listkeyValue = new Array<{key, value}>();
m.forEach((v, k) => {
listkeyValue.push({key: k, value: v});
});
return listkeyValue;
}
}
3 changes: 3 additions & 0 deletions ui/src/app/shared/shared.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import {WorkflowDeleteJoinComponent} from './workflow/join/delete/workflow.join.
import {WorkflowTriggerJoinComponent} from './workflow/join/trigger/trigger.join.component';
import {WorkflowJoinTriggerSrcComponent} from './workflow/join/trigger/src/trigger.src.component';
import {RouterModule} from '@angular/router';
import {ForMapPipe} from './pipes/map.pipe';

@NgModule({
imports: [ CommonModule, NgSemanticModule, FormsModule, TranslateModule, DragulaModule, MomentModule,
Expand All @@ -69,6 +70,7 @@ import {RouterModule} from '@angular/router';
CommitListComponent,
CutPipe,
DeleteButtonComponent,
ForMapPipe,
GroupFormComponent,
HistoryComponent,
KeysPipe,
Expand Down Expand Up @@ -124,6 +126,7 @@ import {RouterModule} from '@angular/router';
CutPipe,
DeleteButtonComponent,
DragulaModule,
ForMapPipe,
FormsModule,
GroupFormComponent,
HistoryComponent,
Expand Down
4 changes: 4 additions & 0 deletions ui/src/app/views/navbar/navbar.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {ApplicationStore} from '../../service/application/application.store';
import {ApplicationService} from '../../service/application/application.service';
import {Project} from '../../model/project.model';
import {LanguageStore} from '../../service/language/language.store';
import {RouterService} from '../../service/router/router.service';
import {WarningStore} from '../../service/warning/warning.store';

describe('CDS: Navbar Component', () => {

Expand All @@ -32,6 +34,8 @@ describe('CDS: Navbar Component', () => {
TranslateLoader,
ProjectStore,
ProjectService,
RouterService,
WarningStore,
AuthentificationStore,
ApplicationStore,
ApplicationService,
Expand Down
Loading

0 comments on commit 2873a18

Please sign in to comment.