diff --git a/ui/src/app/app.component.ts b/ui/src/app/app.component.ts index 50a5533c6..4554efce8 100644 --- a/ui/src/app/app.component.ts +++ b/ui/src/app/app.component.ts @@ -51,17 +51,5 @@ export class AppComponent implements OnInit { 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)); - */ } } diff --git a/ui/src/app/metadata/resolver/container/blank-resolver.component.html b/ui/src/app/metadata/resolver/container/blank-resolver.component.html deleted file mode 100644 index 70ee5fa19..000000000 --- a/ui/src/app/metadata/resolver/container/blank-resolver.component.html +++ /dev/null @@ -1,59 +0,0 @@ -
-
-
- -
-
- - - - - Service Resolver Name is required - - -
-
- - - - - Entity ID is required - - - - Entity ID must be unique - -
- -
-
-
-
diff --git a/ui/src/app/metadata/resolver/container/blank-resolver.component.spec.ts b/ui/src/app/metadata/resolver/container/blank-resolver.component.spec.ts deleted file mode 100644 index 7d0e07d45..000000000 --- a/ui/src/app/metadata/resolver/container/blank-resolver.component.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { TestBed, ComponentFixture } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { StoreModule, Store, combineReducers } from '@ngrx/store'; -import * as fromResolver from '../reducer'; -import { BlankResolverComponent } from './blank-resolver.component'; -import { MockI18nModule } from '../../../../testing/i18n.stub'; - -describe('Blank Resolver Page', () => { - let fixture: ComponentFixture; - let store: Store; - let instance: BlankResolverComponent; - - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [ - NoopAnimationsModule, - StoreModule.forRoot({ - resolver: combineReducers(fromResolver.reducers), - }), - ReactiveFormsModule, - MockI18nModule - ], - declarations: [ - BlankResolverComponent - ], - }); - - fixture = TestBed.createComponent(BlankResolverComponent); - instance = fixture.componentInstance; - store = TestBed.get(Store); - - spyOn(store, 'dispatch').and.callThrough(); - }); - - it('should compile', () => { - fixture.detectChanges(); - - expect(fixture).toBeDefined(); - }); -}); diff --git a/ui/src/app/metadata/resolver/container/blank-resolver.component.ts b/ui/src/app/metadata/resolver/container/blank-resolver.component.ts deleted file mode 100644 index b82c8c6fa..000000000 --- a/ui/src/app/metadata/resolver/container/blank-resolver.component.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { - Component, - OnInit, - Output, - EventEmitter -} from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Observable } from 'rxjs'; -import { Store } from '@ngrx/store'; - -import { AddDraftRequest } from '../action/draft.action'; -import * as fromResolver from '../reducer'; -import { EntityValidators } from '../../domain/service/entity-validators.service'; -import { FileBackedHttpMetadataResolver } from '../../domain/entity/resolver/file-backed-http-metadata-resolver'; - -@Component({ - selector: 'blank-resolver-form', - templateUrl: './blank-resolver.component.html' -}) -export class BlankResolverComponent implements OnInit { - @Output() save: EventEmitter = new EventEmitter(); - - providerForm: FormGroup; - ids$: Observable; - - constructor( - private store: Store, - private fb: FormBuilder - ) { - this.ids$ = this.store.select(fromResolver.getAllEntityIds); - } - - ngOnInit(): void { - this.providerForm = this.fb.group({ - serviceProviderName: ['', Validators.required], - entityId: ['', Validators.required, EntityValidators.createUniqueIdValidator(this.ids$)] - }); - } - - next(): void { - const val = new FileBackedHttpMetadataResolver({ - entityId: this.providerForm.get('entityId').value, - serviceProviderName: this.providerForm.get('serviceProviderName').value - }); - this.store.dispatch(new AddDraftRequest(val)); - } -} diff --git a/ui/src/app/metadata/resolver/container/new-resolver.component.spec.ts b/ui/src/app/metadata/resolver/container/new-resolver.component.spec.ts index ca735a319..fa76b3d45 100644 --- a/ui/src/app/metadata/resolver/container/new-resolver.component.spec.ts +++ b/ui/src/app/metadata/resolver/container/new-resolver.component.spec.ts @@ -7,7 +7,6 @@ import { APP_BASE_HREF } from '@angular/common'; import { StoreModule, Store } from '@ngrx/store'; import { NewResolverComponent } from './new-resolver.component'; -import { BlankResolverComponent } from './blank-resolver.component'; import { UploadResolverComponent } from './upload-resolver.component'; import { CopyResolverComponent } from './copy-resolver.component'; import { SharedModule } from '../../../shared/shared.module'; @@ -37,7 +36,6 @@ describe('New Resolver Page', () => { ], declarations: [ NewResolverComponent, - BlankResolverComponent, UploadResolverComponent, CopyResolverComponent ], diff --git a/ui/src/app/metadata/resolver/container/resolver-wizard-step.component.ts b/ui/src/app/metadata/resolver/container/resolver-wizard-step.component.ts index bd5dfced5..399e75602 100644 --- a/ui/src/app/metadata/resolver/container/resolver-wizard-step.component.ts +++ b/ui/src/app/metadata/resolver/container/resolver-wizard-step.component.ts @@ -1,5 +1,5 @@ import { Component, OnDestroy } from '@angular/core'; -import { Observable, Subject } from 'rxjs'; +import { Observable, Subject, combineLatest } from 'rxjs'; import { withLatestFrom, map, distinctUntilChanged, skipWhile, filter } from 'rxjs/operators'; import { Store } from '@ngrx/store'; @@ -64,14 +64,17 @@ export class ResolverWizardStepComponent implements OnDestroy { map(({ model, definition }) => definition.formatter(model)) ); - this.validators$ = this.definition$.pipe( - withLatestFrom( - this.store.select(fromResolver.getAllEntityIds), - this.model$ - ), - map(([def, ids, resolver]) => def.getValidators( - ids.filter(id => id !== resolver.entityId) - )) + this.validators$ = combineLatest( + this.definition$, + this.store.select(fromResolver.getValidEntityIds), + this.model$ + ).pipe( + map(([def, ids, resolver]) => { + console.log(resolver); + return def.getValidators( + ids + ); + }) ); this.valueChangeEmitted$.pipe( diff --git a/ui/src/app/metadata/resolver/reducer/collection.reducer.spec.ts b/ui/src/app/metadata/resolver/reducer/collection.reducer.spec.ts index 43b1ebfe3..80de420e4 100644 --- a/ui/src/app/metadata/resolver/reducer/collection.reducer.spec.ts +++ b/ui/src/app/metadata/resolver/reducer/collection.reducer.spec.ts @@ -13,7 +13,8 @@ snapshot: fromCollection.CollectionState = { [resolvers[0].id]: resolvers[0], [resolvers[1].id]: resolvers[1] }, - selectedResolverId: null + selectedResolverId: null, + loading: false }; describe('Resolver Reducer', () => { @@ -21,6 +22,7 @@ describe('Resolver Reducer', () => { ids: [], entities: {}, selectedResolverId: null, + loading: false }; describe('undefined action', () => { diff --git a/ui/src/app/metadata/resolver/reducer/collection.reducer.ts b/ui/src/app/metadata/resolver/reducer/collection.reducer.ts index 425e2dee6..37fd58bb9 100644 --- a/ui/src/app/metadata/resolver/reducer/collection.reducer.ts +++ b/ui/src/app/metadata/resolver/reducer/collection.reducer.ts @@ -4,6 +4,7 @@ import { ResolverCollectionActionsUnion, ResolverCollectionActionTypes } from '. export interface CollectionState extends EntityState { selectedResolverId: string | null; + loading: boolean; } export function sortByDate(a: MetadataResolver, b: MetadataResolver): number { @@ -16,14 +17,22 @@ export const adapter: EntityAdapter = createEntityAdapter state.loading; diff --git a/ui/src/app/metadata/resolver/reducer/index.spec.ts b/ui/src/app/metadata/resolver/reducer/index.spec.ts new file mode 100644 index 000000000..5a7cc66ee --- /dev/null +++ b/ui/src/app/metadata/resolver/reducer/index.spec.ts @@ -0,0 +1,40 @@ +import { + getResolverEntityIdCollectionFn, + getAllOtherIdsFn, + getResolverUniqueValidEntityIdsFn +} from './index'; + +describe('Resolver Reducer selectors', () => { + describe(`getResolverEntityIdCollectionFn function`, () => { + it('should return a list of entity ids', () => { + + const resolvers = [ + { + entityId: 'foo' + }, + { + entityId: 'bar' + }, + { + entityId: 'baz' + } + ]; + + expect(getResolverEntityIdCollectionFn(resolvers)).toEqual(['foo', 'bar', 'baz']); + }); + }); + + describe('getResolverUniqueValidEntityIdsFn function', () => { + it('should return a unique and valid list of ids from the provided list', () => { + const ids = ['foo', undefined, undefined, 'foo', 'bar']; + expect(getResolverUniqueValidEntityIdsFn(ids)).toEqual(['foo', 'bar']); + }); + }); + + describe('getAllOtherIdsFn function', () => { + it('should return a list of ids without the selected', () => { + const ids = ['foo', 'bar', 'baz']; + expect(getAllOtherIdsFn(ids, 'foo')).toEqual(['bar', 'baz']); + }); + }); +}); diff --git a/ui/src/app/metadata/resolver/reducer/index.ts b/ui/src/app/metadata/resolver/reducer/index.ts index a22693e4d..d7ae921b2 100644 --- a/ui/src/app/metadata/resolver/reducer/index.ts +++ b/ui/src/app/metadata/resolver/reducer/index.ts @@ -81,7 +81,10 @@ export const getSelectedResolverId = createSelector(getCollectionState, fromColl export const getResolverIds = createSelector(getCollectionState, fromCollection.selectResolverIds); export const getResolverCollection = createSelector(getCollectionState, getResolverIds, fromCollection.selectAllResolvers); +export const getResolverEntityIdCollectionFn = (resolvers) => resolvers.map(r => r.entityId); +export const getResolverEntityIdCollection = createSelector(getResolverCollection, getResolverEntityIdCollectionFn); export const getSelectedResolver = createSelector(getResolverEntities, getSelectedResolverId, getInCollectionFn); +export const getResolversLoading = createSelector(getCollectionState, fromCollection.getResolversLoading); /* @@ -105,11 +108,15 @@ export const getAllResolvers = createSelector(getDraftCollection, getResolverCol export const getAllResolverIds = createSelector(getDraftIds, getResolverIds, combineAllFn); export const getAllEntityIds = createSelector(getAllResolvers, getEntityIdsFn); +export const getResolverUniqueValidEntityIdsFn = (ids) => [...new Set(ids.filter(id => !!id))]; +export const getValidEntityIds = createSelector(getResolverEntityIdCollection, getResolverUniqueValidEntityIdsFn); + +export const getAllOtherIdsFn = (ids, selected) => ids.filter(id => id !== selected); export const getAllOtherIds = createSelector( getAllResolvers, getSelectedResolverId, - (ids, selected) => ids.filter(id => id !== selected) + getAllOtherIdsFn ); export const getDraftModelWithChanges = createSelector( diff --git a/ui/src/app/metadata/resolver/resolver.component.ts b/ui/src/app/metadata/resolver/resolver.component.ts index d488a26d8..dee3e3f75 100644 --- a/ui/src/app/metadata/resolver/resolver.component.ts +++ b/ui/src/app/metadata/resolver/resolver.component.ts @@ -1,22 +1,25 @@ import { Component, ChangeDetectionStrategy } from '@angular/core'; import { Store } from '@ngrx/store'; - +import { Observable } from 'rxjs'; import { LoadResolverRequest } from './action/collection.action'; -import { LoadDraftRequest } from './action/draft.action'; import * as fromRoot from '../../app.reducer'; +import * as fromResolver from './reducer'; @Component({ selector: 'metadata-resolver-page', changeDetection: ChangeDetectionStrategy.OnPush, - template: '', + template: ` + + `, styleUrls: [] }) export class MetadataResolverPageComponent { + loading$: Observable = this.store.select(fromResolver.getResolversLoading); + constructor( private store: Store ) { - // this.store.dispatch(new LoadResolverRequest()); - // this.store.dispatch(new LoadDraftRequest()); + this.store.dispatch(new LoadResolverRequest()); } } diff --git a/ui/src/app/metadata/resolver/resolver.module.ts b/ui/src/app/metadata/resolver/resolver.module.ts index e303181fc..ce5a6ec21 100644 --- a/ui/src/app/metadata/resolver/resolver.module.ts +++ b/ui/src/app/metadata/resolver/resolver.module.ts @@ -9,7 +9,6 @@ import { NgbDropdownModule, NgbPopoverModule, NgbModalModule } from '@ng-bootstr import { NewResolverComponent } from './container/new-resolver.component'; import { UploadResolverComponent } from './container/upload-resolver.component'; -import { BlankResolverComponent } from './container/blank-resolver.component'; import { CopyResolverComponent } from './container/copy-resolver.component'; import { SharedModule } from '../../shared/shared.module'; import { SearchIdEffects } from './effect/search.effect'; @@ -42,7 +41,6 @@ import { MetadataConfigurationModule } from '../configuration/configuration.modu declarations: [ NewResolverComponent, UploadResolverComponent, - BlankResolverComponent, CopyResolverComponent, ConfirmCopyComponent, ResolverEditComponent,