Skip to content

Commit

Permalink
Merge branch 'master' into SHIBUI-669
Browse files Browse the repository at this point in the history
  • Loading branch information
dima767 committed Jul 19, 2018
2 parents 005f2f7 + 7945464 commit 27790e3
Show file tree
Hide file tree
Showing 42 changed files with 1,440 additions and 140 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { MetadataProvider } from '../metadata-provider';

export interface BaseMetadataProvider extends MetadataProvider {
metadataFilters: any[];
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { MetadataProvider } from '../metadata-provider';
import { BaseMetadataProvider } from './base-metadata-provider';

export interface FileBackedHttpMetadataProvider extends MetadataProvider {
metadataFilters: any[];
export interface FileBackedHttpMetadataProvider extends BaseMetadataProvider {
id: string;
metadataURL: string;
reloadableMetadataResolverAttributes: any;
}
3 changes: 2 additions & 1 deletion ui/src/app/metadata/domain/model/providers/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './file-backed-http-metadata-provider';
export * from './file-backed-http-metadata-provider';
export * from './base-metadata-provider';
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
</div>
</div>
<div class="p-3">
<code><pre>{{ providers$ | async | json }}</pre></code>
<a *ngFor="let provider of providers$ | async"
[routerLink]="['/', 'metadata', 'provider', provider.resourceId, 'edit']">
{{ provider.name }}
</a>
</div>
</div>
</section>
Expand Down
31 changes: 28 additions & 3 deletions ui/src/app/metadata/provider/action/collection.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ export enum ProviderCollectionActionTypes {
UPDATE_PROVIDER_SUCCESS = '[Metadata Provider] Update Success',
UPDATE_PROVIDER_FAIL = '[Metadata Provider] Update Fail',

LOAD_PROVIDER_REQUEST = '[Metadata Provider Collection] Provider REQUEST',
LOAD_PROVIDER_SUCCESS = '[Metadata Provider Collection] Provider SUCCESS',
LOAD_PROVIDER_ERROR = '[Metadata Provider Collection] Provider ERROR',
LOAD_PROVIDER_REQUEST = '[Metadata Provider Collection] Provider Load REQUEST',
LOAD_PROVIDER_SUCCESS = '[Metadata Provider Collection] Provider Load SUCCESS',
LOAD_PROVIDER_ERROR = '[Metadata Provider Collection] Provider Load ERROR',

SELECT_PROVIDER_REQUEST = '[Metadata Provider Collection] Provider SELECT REQUEST',
SELECT_PROVIDER_SUCCESS = '[Metadata Provider Collection] Provider SELECT SUCCESS',
SELECT_PROVIDER_ERROR = '[Metadata Provider Collection] Provider SELECT ERROR',

ADD_PROVIDER_REQUEST = '[Metadata Provider Collection] Add Provider',
ADD_PROVIDER_SUCCESS = '[Metadata Provider Collection] Add Provider Success',
Expand Down Expand Up @@ -38,6 +42,24 @@ export class LoadProviderError implements Action {
constructor(public payload: any) { }
}

export class SelectProviderRequest implements Action {
readonly type = ProviderCollectionActionTypes.SELECT_PROVIDER_REQUEST;

constructor(public payload: any) { }
}

export class SelectProviderSuccess implements Action {
readonly type = ProviderCollectionActionTypes.SELECT_PROVIDER_SUCCESS;

constructor(public payload: Update<MetadataProvider>) { }
}

export class SelectProviderError implements Action {
readonly type = ProviderCollectionActionTypes.SELECT_PROVIDER_ERROR;

constructor(public payload: any) { }
}

export class UpdateProviderRequest implements Action {
readonly type = ProviderCollectionActionTypes.UPDATE_PROVIDER_REQUEST;

Expand Down Expand Up @@ -96,6 +118,9 @@ export type ProviderCollectionActionsUnion =
| LoadProviderRequest
| LoadProviderSuccess
| LoadProviderError
| SelectProviderRequest
| SelectProviderSuccess
| SelectProviderError
| AddProviderRequest
| AddProviderSuccess
| AddProviderFail
Expand Down
8 changes: 0 additions & 8 deletions ui/src/app/metadata/provider/action/entity.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,11 @@ import { Action } from '@ngrx/store';
import { MetadataProvider } from '../../domain/model';

export enum EntityActionTypes {
SELECT_PROVIDER = '[Provider Entity] Select Provider',
UPDATE_PROVIDER = '[Provider Entity] Update Provider',
CLEAR_PROVIDER = '[Provider Entity] Clear',
RESET_CHANGES = '[Provider Entity] Reset Changes'
}

export class SelectProvider implements Action {
readonly type = EntityActionTypes.SELECT_PROVIDER;

constructor(public payload: MetadataProvider) { }
}

export class UpdateProvider implements Action {
readonly type = EntityActionTypes.UPDATE_PROVIDER;

Expand All @@ -29,7 +22,6 @@ export class ResetChanges implements Action {
}

export type EntityActionUnion =
| SelectProvider
| UpdateProvider
| ClearProvider
| ResetChanges;
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { StoreModule, Store, combineReducers } from '@ngrx/store';

import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';

import { ProviderWizardSummaryComponent } from './provider-wizard-summary.component';
import { ProviderWizardSummaryComponent, getStepProperties } from './provider-wizard-summary.component';
import * as fromRoot from '../reducer';
import { SchemaFormModule, WidgetRegistry, DefaultWidgetRegistry } from 'ngx-schema-form';
import * as fromWizard from '../../../wizard/reducer';
Expand Down Expand Up @@ -76,6 +76,31 @@ describe('Provider Wizard Summary Component', () => {
expect(app).toBeTruthy();
}));

describe('getStepProperties function', () => {
it('should return an empty array of schema or schema.properties is not defined', () => {
expect(getStepProperties(null, {})).toEqual([]);
expect(getStepProperties({}, {})).toEqual([]);
});

it('should return a formatted list of properties', () => {
expect(getStepProperties(SCHEMA, {}).length).toBe(2);
});
});

describe('gotoPage function', () => {
it('should emit an empty string if page is null', () => {
spyOn(app.onPageSelect, 'emit');
app.gotoPage();
expect(app.onPageSelect.emit).toHaveBeenCalledWith('');
});

it('should emit the provided page', () => {
spyOn(app.onPageSelect, 'emit');
app.gotoPage('foo');
expect(app.onPageSelect.emit).toHaveBeenCalledWith('foo');
});
});

describe('ngOnChanges', () => {
it('should set columns and sections if summary is provided', () => {
instance.summary = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ interface Section {
properties: Property[];
}

function getStepProperties(schema: any, model: any): Property[] {
export function getStepProperties(schema: any, model: any): Property[] {
if (!schema || !schema.properties) { return []; }
return Object.keys(schema.properties).map(property => ({
name: schema.properties[property].title,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<ng-container *ngIf="definition$ | async">
<sf-form
[schema]="schema$ | async"
[model]="model$ | async"
[validators]="validators$ | async"
(onChange)="valueChangeSubject.next($event)"
(onErrorChange)="statusChangeSubject.next($event)"></sf-form>
</ng-container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { Component, ViewChild } from '@angular/core';
import { TestBed, async, ComponentFixture, fakeAsync, tick } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { StoreModule, Store, combineReducers } from '@ngrx/store';
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
import { ProviderEditStepComponent } from './provider-edit-step.component';
import * as fromRoot from '../reducer';
import * as fromWizard from '../../../wizard/reducer';
import { SchemaFormModule, WidgetRegistry, DefaultWidgetRegistry } from 'ngx-schema-form';
import { SharedModule } from '../../../shared/shared.module';
import { SetDefinition } from '../../../wizard/action/wizard.action';
import { FileBackedHttpMetadataProviderEditor } from '../model';

@Component({
template: `
<provider-edit-step></provider-edit-step>
`
})
class TestHostComponent {
@ViewChild(ProviderEditStepComponent)
public componentUnderTest: ProviderEditStepComponent;
}

describe('Provider Edit Step Component', () => {

let fixture: ComponentFixture<TestHostComponent>;
let instance: TestHostComponent;
let app: ProviderEditStepComponent;
let store: Store<fromRoot.State>;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
NgbDropdownModule.forRoot(),
RouterTestingModule,
SchemaFormModule.forRoot(),
SharedModule,
StoreModule.forRoot({
provider: combineReducers(fromRoot.reducers),
wizard: combineReducers(fromWizard.reducers, {
wizard: {
index: 'common',
disabled: false,
definition: FileBackedHttpMetadataProviderEditor,
schemaCollection: []
}
})
})
],
declarations: [
ProviderEditStepComponent,
TestHostComponent
],
providers: [
{ provide: WidgetRegistry, useClass: DefaultWidgetRegistry }
]
}).compileComponents();

store = TestBed.get(Store);
spyOn(store, 'dispatch');

fixture = TestBed.createComponent(TestHostComponent);
instance = fixture.componentInstance;
app = instance.componentUnderTest;
fixture.detectChanges();
}));

it('should instantiate the component', async(() => {
expect(app).toBeTruthy();
}));

describe('updateStatus method', () => {
it('should update the status with provided errors', () => {
app.currentPage = 'common';
app.updateStatus({value: 'common'});
app.updateStatus({value: 'foo'});
expect(store.dispatch).toHaveBeenCalledTimes(2);
});
});

describe('valueChangeEmitted$ subject', () => {
it('should update the provider', fakeAsync(() => {
app.valueChangeSubject.next({value: { name: 'foo' } });
fixture.detectChanges();
tick();
fixture.detectChanges();
expect(store.dispatch).toHaveBeenCalled();
}));
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { Component, OnDestroy } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { Store } from '@ngrx/store';

import * as fromProvider from '../reducer';
import { UpdateStatus } from '../action/editor.action';
import { Wizard } from '../../../wizard/model';
import { MetadataProvider } from '../../domain/model';

import * as fromWizard from '../../../wizard/reducer';
import { withLatestFrom, map, skipWhile, distinctUntilChanged } from 'rxjs/operators';
import { UpdateProvider } from '../action/entity.action';

@Component({
selector: 'provider-edit-step',
templateUrl: './provider-edit-step.component.html',
styleUrls: []
})

export class ProviderEditStepComponent implements OnDestroy {
valueChangeSubject = new Subject<Partial<any>>();
private valueChangeEmitted$ = this.valueChangeSubject.asObservable();

statusChangeSubject = new Subject<Partial<any>>();
private statusChangeEmitted$ = this.statusChangeSubject.asObservable();

currentPage: string;

namesList: string[] = [];

schema$: Observable<any>;
provider$: Observable<MetadataProvider>;
model$: Observable<any>;
definition$: Observable<Wizard<MetadataProvider>>;
changes$: Observable<MetadataProvider>;

validators$: Observable<{ [key: string]: any }>;

constructor(
private store: Store<fromProvider.ProviderState>
) {
this.schema$ = this.store.select(fromProvider.getSchema);
this.definition$ = this.store.select(fromWizard.getWizardDefinition);
this.changes$ = this.store.select(fromProvider.getEntityChanges);
this.provider$ = this.store.select(fromProvider.getSelectedProvider);

this.validators$ = this.store.select(fromProvider.getProviderNames).pipe(
withLatestFrom(this.definition$, this.provider$),
map(([names, def, provider]) => def.getValidators(names.filter(n => n !== provider.name)))
);

this.model$ = this.schema$.pipe(
withLatestFrom(
this.store.select(fromProvider.getSelectedProvider),
this.store.select(fromWizard.getModel),
this.changes$,
this.definition$
),
map(([schema, provider, model, changes, definition]) => ({
model: {
...model,
...provider,
...changes
},
definition
})),
skipWhile(({ model, definition }) => !definition || !model),
map(({ model, definition }) => definition.translate.formatter(model))
);

this.valueChangeEmitted$.pipe(
map(changes => changes.value),
withLatestFrom(this.definition$),
skipWhile(([ changes, definition ]) => !definition || !changes),
map(([ changes, definition ]) => definition.translate.parser(changes))
)
.subscribe(changes => this.store.dispatch(new UpdateProvider(changes)));

this.statusChangeEmitted$.pipe(distinctUntilChanged()).subscribe(errors => this.updateStatus(errors));

this.store.select(fromWizard.getWizardIndex).subscribe(i => this.currentPage = i);
}

updateStatus(errors: any): void {
const status = { [this.currentPage]: !(errors.value) ? 'VALID' : 'INVALID' };
this.store.dispatch(new UpdateStatus(status));
}

ngOnDestroy() {
this.valueChangeSubject.complete();
}
}

Loading

0 comments on commit 27790e3

Please sign in to comment.