Skip to content

Commit

Permalink
SHIBUI-1347 Fixed issue with incomplete resolvers
Browse files Browse the repository at this point in the history
  • Loading branch information
rmathis committed Jul 2, 2019
1 parent 5e05b01 commit 0c4fc42
Show file tree
Hide file tree
Showing 33 changed files with 308 additions and 211 deletions.
33 changes: 13 additions & 20 deletions ui/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,19 @@
<translate-i18n key="action.add-new">Add New</translate-i18n>
</button>
<div ngbDropdownMenu aria-labelledby="addNewDropdown">
<a class="nav-link"
routerLink="/metadata/resolver/new"
routerLinkActive="active"
queryParamsHandling="preserve"
[attr.aria-label]="'action.add-new-source' | translate"
role="button">
<i class="fa fa-cube fa-fw" aria-hidden="true"></i>
&nbsp;
<translate-i18n key="label.metadata-source">Metadata Source</translate-i18n>
</a>
<a class="nav-link"
routerLink="/metadata/provider/wizard"
routerLinkActive="active"
[attr.aria-label]="'action.add-new-provider' | translate"
role="button"
*ngIf="isAdmin$ | async">
<i class="fa fa-cubes fa-fw" aria-hidden="true"></i>
&nbsp;
<translate-i18n key="label.metadata-provider">Metadata Provider</translate-i18n>
</a>
<ng-container *ngFor="let action of nav$ | async">
<a href=""
class="nav-link"
(click)="action.action($event)"
[attr.aria-label]="action.label | translate"
role="button">
<ng-container *ngIf="action.icon">
<i class="fa fa-fw" [ngClass]="action.icon"></i>
&nbsp;
</ng-container>
{{ action.content | translate }}
</a>
</ng-container>
</div>
</li>
<li class="nav-item">
Expand Down
5 changes: 4 additions & 1 deletion ui/src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { NotificationModule } from './notification/notification.module';
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
import { MockTranslatePipe, MockI18nService, MockI18nModule } from '../testing/i18n.stub';
import { I18nService } from './i18n/service/i18n.service';
import { NavigationService } from './core/service/navigation.service';
import { NavigationServiceStub } from '../testing/navigation-service.stub';

@Component({
template: `
Expand All @@ -30,7 +32,8 @@ describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [
{provide: I18nService, useClass: MockI18nService }
{provide: I18nService, useClass: MockI18nService },
{ provide: NavigationService, useValue: NavigationServiceStub }
],
imports: [
NgbDropdownModule,
Expand Down
27 changes: 23 additions & 4 deletions ui/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

import { Store } from '@ngrx/store';

Expand All @@ -12,6 +12,9 @@ import { SetLocale } from './i18n/action/message.action';
import { brand } from './app.brand';
import { Brand } from './core/model/brand';
import { UserLoadRequestAction } from './core/action/user.action';
import { Router } from '@angular/router';
import { NavigationService } from './core/service/navigation.service';
import { NavigationAction } from './core/model/action';

@Component({
selector: 'app-root',
Expand All @@ -26,23 +29,39 @@ export class AppComponent implements OnInit {
today = new Date();
year = new Date().getFullYear();
isAdmin$: Observable<boolean>;

brand: Brand = brand;
nav$: Observable<NavigationAction[]>;

formatter = v => v && v.build ? `${v.build.version}-${v.git.commit.id}` : '';

constructor(
private store: Store<fromRoot.State>,
private i18nService: I18nService
private i18nService: I18nService,
private router: Router,
private navService: NavigationService
) {
this.version$ = this.store.select(fromRoot.getVersionInfo);
this.formatted$ = this.version$.pipe(map(this.formatter));
this.isAdmin$ = this.store.select(fromRoot.isCurrentUserAdmin);

this.nav$ = this.navService.emitter;
}

ngOnInit(): void {
this.store.dispatch(new UserLoadRequestAction());
this.store.dispatch(new VersionInfoLoadRequestAction());
this.store.dispatch(new SetLocale(this.i18nService.getCurrentLocale()));

/*
this.router
.events
.pipe(
catchError(err => {
console.error(err);
return err;
})
)
.subscribe((ev) => console.log(ev));
*/
}
}
2 changes: 2 additions & 0 deletions ui/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { WizardModule } from './wizard/wizard.module';
import { FormModule } from './schema-form/schema-form.module';
import { environment } from '../environments/environment.prod';
import { I18nModule } from './i18n/i18n.module';
import { NavigationService } from './core/service/navigation.service';

@NgModule({
declarations: [
Expand Down Expand Up @@ -58,6 +59,7 @@ import { I18nModule } from './i18n/i18n.module';
],
providers: [
NavigatorService,
NavigationService,
{ provide: RouterStateSerializer, useClass: CustomRouterStateSerializer },
{
provide: HTTP_INTERCEPTORS,
Expand Down
7 changes: 7 additions & 0 deletions ui/src/app/core/model/action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface NavigationAction {
action: ($event: Event) => void;
category: string;
label: string;
content: string;
icon?: string;
}
31 changes: 31 additions & 0 deletions ui/src/app/core/service/navigation.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { NavigationAction } from '../model/action';

@Injectable()
export class NavigationService {

private actions: { [name: string]: NavigationAction} = {};
private subj: BehaviorSubject<NavigationAction[]>;
private obs: Observable<NavigationAction[]>;

constructor() {
this.subj = new BehaviorSubject<NavigationAction[]>(this.actionList);
this.obs = this.subj.asObservable();
}

get actionList(): NavigationAction[] {
return Object.values(this.actions);
}

get emitter(): Observable<NavigationAction[]> {
return this.obs;
}

addAction(name: string, action: NavigationAction): NavigationAction[] {
console.log(this.actions);
this.actions[name] = action;
this.subj.next(this.actionList);
return this.actionList;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,41 @@ import { HttpTestingController, HttpClientTestingModule } from '@angular/common/
import { MetadataConfigurationService } from './configuration.service';
import { FileBackedHttpMetadataProviderEditor } from '../../provider/model';
import { MetadataSourceEditor } from '../../domain/model/wizards/metadata-source-editor';
import { PATHS } from '../configuration.values';
import { ResolverService } from '../../domain/service/resolver.service';
import { of } from 'rxjs';

describe(`Configuration Service`, () => {

let resolverService: any;

describe(`Attributes Service`, () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientModule,
HttpClientTestingModule
],
providers: [
MetadataConfigurationService
MetadataConfigurationService,
{
provide: ResolverService, useValue: {
find: () => of([])
}
}
]
});

resolverService = TestBed.get(ResolverService);

});

describe('find method', () => {
it(`should send an expected GET request`, async(inject([MetadataConfigurationService, HttpTestingController],
(service: MetadataConfigurationService, backend: HttpTestingController) => {
spyOn(resolverService, 'find').and.callThrough();
const type = 'resolver';
const id = 'foo';
service.find(id, type).subscribe();
backend.expectOne((req: HttpRequest<any>) => {
return req.url === `${service.base}/${PATHS[type]}/${id}`
&& req.method === 'GET';
}, `GET metadata by id and type`);
expect(resolverService.find).toHaveBeenCalledWith(id);
}
)));
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,28 @@
[infiniteScrollThrottle]="50"
(scrolled)="onScroll($event)">
<tr *ngFor="let resolver of limited$ | async; index as i">
<td><a [routerLink]="['/', 'metadata', 'resolver', resolver.getId(), 'configuration', 'options']">{{ resolver.name }}</a></td>
<td *ngIf="!resolver.isDraft()">
<a [routerLink]="['/', 'metadata', 'resolver', resolver.getId(), 'configuration', 'options']">{{ resolver.name }}</a>
</td>
<td *ngIf="resolver.isDraft()">
<a [routerLink]="['/', 'metadata', 'resolver', 'new', 'blank', 'common']"
[queryParams]="{'id': resolver.getId()}">{{ resolver.name }}</a>
</td>
<td>{{ resolver.getDisplayId() }}</td>
<td>{{ resolver.createdBy }}</td>
<td>{{ resolver.getCreationDate() ? (resolver.getCreationDate() | customDate) : '&mdash;' }}</td>
<td class="text-right">
<span class="badge badge-warning"
*ngIf="resolver.isDraft()"
aria-label="Warning Badge: Incomplete Form"
translate="message.incomplete-form">
Incomplete Form
<span *ngIf="resolver.isDraft()">
<button class="btn btn-outline btn-sm btn-danger" (click)="deleteResolver(resolver)">
<span class="sr-only">Delete</span>
<i class="fa fa-trash"></i>
</button>
&nbsp;
<span class="badge badge-warning"
aria-label="Warning Badge: Incomplete Form"
translate="message.incomplete-form">
Incomplete Form
</span>
</span>
<span class="badge"
*ngIf="!resolver.isDraft()"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,17 +95,15 @@ describe('Dashboard Resolvers List Page', () => {
});

describe('edit method', () => {
it('should route to the edit page', () => {
spyOn(router, 'navigate');
instance.edit(resolver);
expect(router.navigate).toHaveBeenCalledWith(['metadata', 'resolver', resolver.id, 'edit']);
});
it('should route to the wizard page', () => {
const evt = new Event('a type');
spyOn(router, 'navigate');
instance.edit(draft);
spyOn(evt, 'preventDefault');
instance.edit(evt, draft);
expect(router.navigate).toHaveBeenCalledWith(['metadata', 'resolver', 'new', 'blank', 'common'], {
queryParams: { id: '1' }
});
expect(evt.preventDefault).toHaveBeenCalled();
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,13 @@ export class DashboardResolversListComponent implements OnInit {
this.loadMore(this.page + 1);
}

edit(entity: MetadataEntity): void {
if (entity.isDraft()) {
this.router.navigate(['metadata', 'resolver', 'new', 'blank', 'common'], {
queryParams: {
id: entity.getId()
}
});
} else {
this.router.navigate(['metadata', 'resolver', entity.getId(), 'edit']);
}
edit(evt: Event, entity: MetadataEntity): void {
evt.preventDefault();
this.router.navigate(['metadata', 'resolver', 'new', 'blank', 'common'], {
queryParams: {
id: entity.getId()
}
});
}

toggleEntity(entity: MetadataEntity): void {
Expand Down
10 changes: 8 additions & 2 deletions ui/src/app/metadata/manager/container/manager.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { StoreModule, combineReducers } from '@ngrx/store';

import { ManagerComponent } from './manager.component';
import { RouterModule, Router } from '@angular/router';
import { Router } from '@angular/router';
import { RouterStub, RouterLinkStubDirective, RouterOutletStubComponent } from '../../../../testing/router.stub';
import { MockI18nModule } from '../../../../testing/i18n.stub';
import * as fromDashboard from '../reducer';

describe('Metadata Manager Parent Page', () => {
let fixture: ComponentFixture<ManagerComponent>;
Expand All @@ -16,7 +19,10 @@ describe('Metadata Manager Parent Page', () => {
],
imports: [
NoopAnimationsModule,
MockI18nModule
MockI18nModule,
StoreModule.forRoot({
manager: combineReducers(fromDashboard.reducers),
})
],
declarations: [
ManagerComponent,
Expand Down
13 changes: 12 additions & 1 deletion ui/src/app/metadata/manager/container/manager.component.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { LoadResolverRequest } from '../../resolver/action/collection.action';
import { LoadDraftRequest } from '../../resolver/action/draft.action';
import * as fromRoot from '../../../app.reducer';
import { LoadProviderRequest } from '../../provider/action/collection.action';

@Component({
selector: 'manager-page',
templateUrl: './manager.component.html',
styleUrls: ['./manager.component.scss']
})
export class ManagerComponent {
constructor() {}
constructor(
private store: Store<fromRoot.State>
) {
this.store.dispatch(new LoadResolverRequest());
this.store.dispatch(new LoadDraftRequest());
this.store.dispatch(new LoadProviderRequest());
}
}
2 changes: 0 additions & 2 deletions ui/src/app/metadata/manager/reducer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { createSelector, createFeatureSelector } from '@ngrx/store';
import * as fromRoot from '../../../core/reducer';
import * as fromDashboard from './manager.reducer';
import * as fromSearch from './search.reducer';
import { MetadataEntity } from '../../domain/model';
import { Metadata } from '../../domain/domain.type';

export interface DashboardState {
manager: fromDashboard.State;
Expand Down
1 change: 0 additions & 1 deletion ui/src/app/metadata/metadata.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,5 @@ describe('Metadata Root Component', () => {

it('should load metadata objects', async(() => {
expect(app).toBeTruthy();
expect(store.dispatch).toHaveBeenCalledTimes(3);
}));
});
10 changes: 1 addition & 9 deletions ui/src/app/metadata/metadata.component.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { Store } from '@ngrx/store';

import { LoadResolverRequest } from './resolver/action/collection.action';
import { LoadDraftRequest } from './resolver/action/draft.action';
import * as fromRoot from '../app.reducer';
import { LoadProviderRequest } from './provider/action/collection.action';

@Component({
selector: 'metadata-page',
Expand All @@ -13,12 +10,7 @@ import { LoadProviderRequest } from './provider/action/collection.action';
styleUrls: []
})
export class MetadataPageComponent {

constructor(
private store: Store<fromRoot.State>
) {
this.store.dispatch(new LoadResolverRequest());
this.store.dispatch(new LoadDraftRequest());
this.store.dispatch(new LoadProviderRequest());
}
) {}
}
Loading

0 comments on commit 0c4fc42

Please sign in to comment.