diff --git a/ui/src/app/metadata/configuration/component/configuration-property.component.spec.ts b/ui/src/app/metadata/configuration/component/configuration-property.component.spec.ts index 5ef0452e0..aa7fd9478 100644 --- a/ui/src/app/metadata/configuration/component/configuration-property.component.spec.ts +++ b/ui/src/app/metadata/configuration/component/configuration-property.component.spec.ts @@ -62,7 +62,8 @@ describe('Configuration Property Component', () => { describe('getItemType method', () => { it('should return the item`s type', () => { - expect(app.getItemType({ widget: { id: 'string' } } as Property)).toBe('string'); + expect(app.getItemType({items: { widget: { id: 'string' } } } as Property)).toBe('string'); + expect(app.getItemType({items: {}} as Property)).toBe('default'); expect(app.getItemType({} as Property)).toBe('default'); }); }); diff --git a/ui/src/app/metadata/configuration/component/configuration-property.component.ts b/ui/src/app/metadata/configuration/component/configuration-property.component.ts index 04d58ca41..5418bde30 100644 --- a/ui/src/app/metadata/configuration/component/configuration-property.component.ts +++ b/ui/src/app/metadata/configuration/component/configuration-property.component.ts @@ -18,7 +18,8 @@ export class ConfigurationPropertyComponent { getItemType(property: Property): string { const items = property.items; - return items.widget ? items.widget.id : 'default'; + const def = 'default'; + return items ? items.widget ? items.widget.id : def : def; } get width(): string { diff --git a/ui/src/app/metadata/configuration/component/filter-configuration-list.component.ts b/ui/src/app/metadata/configuration/component/filter-configuration-list.component.ts index b155926d6..5208a7f4c 100644 --- a/ui/src/app/metadata/configuration/component/filter-configuration-list.component.ts +++ b/ui/src/app/metadata/configuration/component/filter-configuration-list.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import { FilterListComponent } from '../../filter/container/filter-list.component'; +import { FilterListComponent } from '../../filter/component/filter-list.component'; @Component({ selector: 'filter-configuration-list', diff --git a/ui/src/app/metadata/configuration/component/metadata-configuration.component.html b/ui/src/app/metadata/configuration/component/metadata-configuration.component.html index 6f4628c75..d26fb0dd1 100644 --- a/ui/src/app/metadata/configuration/component/metadata-configuration.component.html +++ b/ui/src/app/metadata/configuration/component/metadata-configuration.component.html @@ -31,7 +31,7 @@

*ngIf="section" [property]="section" [columns]="configuration.dates.length" - (preview)="onPreview($event)"> + (preview)="preview.emit($event)"> diff --git a/ui/src/app/metadata/configuration/component/metadata-configuration.component.ts b/ui/src/app/metadata/configuration/component/metadata-configuration.component.ts index 7a389d925..10ec0eed8 100644 --- a/ui/src/app/metadata/configuration/component/metadata-configuration.component.ts +++ b/ui/src/app/metadata/configuration/component/metadata-configuration.component.ts @@ -1,4 +1,4 @@ -import { Component, ChangeDetectionStrategy, Input } from '@angular/core'; +import { Component, ChangeDetectionStrategy, Input, Output, EventEmitter } from '@angular/core'; import { Router, ActivatedRoute } from '@angular/router'; import { MetadataConfiguration } from '../model/metadata-configuration'; import { Property } from '../../domain/model/property'; @@ -21,23 +21,17 @@ export class MetadataConfigurationComponent { @Input() numbered = true; @Input() editable = true; + @Output() preview: EventEmitter = new EventEmitter(); + constructor( private router: Router, - private activatedRoute: ActivatedRoute, - private store: Store + private activatedRoute: ActivatedRoute ) {} edit(id: string): void { this.router.navigate(['../', 'edit', id], { relativeTo: this.activatedRoute.parent }); } - onPreview($event): void { - this.store.dispatch(new PreviewEntity({ - id: $event.data, - entity: this.definition.getEntity(this.entity) - })); - } - get width(): string { const columns = this.configuration.dates.length; return `${Math.floor(100 / (columns + 1)) }%`; diff --git a/ui/src/app/metadata/configuration/component/object-property.component.spec.ts b/ui/src/app/metadata/configuration/component/object-property.component.spec.ts index 6299b20d5..7ccb135fe 100644 --- a/ui/src/app/metadata/configuration/component/object-property.component.spec.ts +++ b/ui/src/app/metadata/configuration/component/object-property.component.spec.ts @@ -10,6 +10,7 @@ import { SCHEMA } from '../../../../testing/form-schema.stub'; import { getStepProperties, getStepProperty } from '../../domain/utility/configuration'; import { PrimitivePropertyComponent } from './primitive-property.component'; import { ArrayPropertyComponent } from './array-property.component'; +import { FilterTargetPropertyComponent } from './filter-target-property.component'; @Component({ template: ` @@ -44,6 +45,7 @@ describe('Object Property Component', () => { ObjectPropertyComponent, PrimitivePropertyComponent, ArrayPropertyComponent, + FilterTargetPropertyComponent, TestHostComponent ] }).compileComponents(); diff --git a/ui/src/app/metadata/configuration/container/metadata-options.component.html b/ui/src/app/metadata/configuration/container/metadata-options.component.html index 972e0e4da..f10147755 100644 --- a/ui/src/app/metadata/configuration/container/metadata-options.component.html +++ b/ui/src/app/metadata/configuration/container/metadata-options.component.html @@ -29,6 +29,7 @@
diff --git a/ui/src/app/metadata/configuration/container/metadata-options.component.spec.ts b/ui/src/app/metadata/configuration/container/metadata-options.component.spec.ts index a012fcd70..8f12d9828 100644 --- a/ui/src/app/metadata/configuration/container/metadata-options.component.spec.ts +++ b/ui/src/app/metadata/configuration/container/metadata-options.component.spec.ts @@ -6,30 +6,20 @@ import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; import { MetadataConfiguration } from '../model/metadata-configuration'; import * as fromConfiguration from '../reducer'; +import * as fromFilters from '../../filter/reducer'; +import * as fromProviders from '../../provider/reducer'; +import * as fromResolvers from '../../resolver/reducer'; import { MockI18nModule } from '../../../../testing/i18n.stub'; import { MetadataOptionsComponent } from './metadata-options.component'; -import { Metadata } from '../../domain/domain.type'; -import { MetadataVersion } from '../model/version'; import { CommonModule } from '@angular/common'; -@Component({ - selector: 'metadata-configuration', - template: `` -}) -class MetadataConfigurationComponent { - @Input() configuration: MetadataConfiguration; -} - -@Component({ - selector: 'metadata-header', - template: `` -}) -class MetadataHeaderComponent { - @Input() isEnabled: boolean; - @Input() version: MetadataVersion; - @Input() versionNumber: number; - @Input() isCurrent: boolean; -} +import { + MetadataConfigurationComponentStub, + MetadataHeaderComponentStub +} from '../../../../testing/metadata-configuration.stub'; +import { + FilterConfigurationListComponentStub +} from '../../../../testing/filter-list.stub'; @Component({ template: ` @@ -59,6 +49,9 @@ describe('Metadata Options Page Component', () => { NgbDropdownModule, StoreModule.forRoot({ 'metadata-configuration': combineReducers(fromConfiguration.reducers), + 'filters': combineReducers(fromFilters.reducers), + 'provider': combineReducers(fromProviders.reducers), + 'resolver': combineReducers(fromResolvers.reducers) }), MockI18nModule, RouterTestingModule, @@ -66,9 +59,10 @@ describe('Metadata Options Page Component', () => { ], declarations: [ MetadataOptionsComponent, - MetadataConfigurationComponent, - MetadataHeaderComponent, - TestHostComponent + MetadataConfigurationComponentStub, + MetadataHeaderComponentStub, + TestHostComponent, + FilterConfigurationListComponentStub ], }).compileComponents(); diff --git a/ui/src/app/metadata/configuration/container/metadata-options.component.ts b/ui/src/app/metadata/configuration/container/metadata-options.component.ts index 19051596b..337ad4fc3 100644 --- a/ui/src/app/metadata/configuration/container/metadata-options.component.ts +++ b/ui/src/app/metadata/configuration/container/metadata-options.component.ts @@ -1,6 +1,10 @@ import { Store } from '@ngrx/store'; -import { Component, ChangeDetectionStrategy, OnDestroy, HostListener, ElementRef } from '@angular/core'; +import { Component, ChangeDetectionStrategy, OnDestroy } from '@angular/core'; import { Observable, Subject } from 'rxjs'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { Router, Event, Scroll } from '@angular/router'; +import { ViewportScroller } from '@angular/common'; +import { takeUntil, filter, delay } from 'rxjs/operators'; import { ConfigurationState, @@ -11,7 +15,7 @@ import { getConfigurationModelEnabled, getConfigurationHasXml, getConfigurationModel, - getConfigurationModelKind + getConfigurationDefinition } from '../reducer'; import { MetadataConfiguration } from '../model/metadata-configuration'; import { MetadataVersion } from '../model/version'; @@ -24,13 +28,11 @@ import { ChangeFilterOrderUp, RemoveFilterRequest } from '../../filter/action/collection.action'; -import { takeUntil, map, filter, delay } from 'rxjs/operators'; + import { Metadata } from '../../domain/domain.type'; import { DeleteFilterComponent } from '../../provider/component/delete-filter.component'; -import { ModalService } from '../../../core/service/modal.service'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { Router, Event, Scroll } from '@angular/router'; -import { ViewportScroller } from '@angular/common'; +import { Wizard } from '../../../wizard/model'; +import { PreviewEntity } from '../../domain/action/entity.action'; @Component({ selector: 'metadata-options-page', @@ -50,6 +52,7 @@ export class MetadataOptionsComponent implements OnDestroy { hasXml$: Observable; filters$: Observable; model$: Observable; + definition: Wizard; id: string; kind: string; @@ -73,10 +76,11 @@ export class MetadataOptionsComponent implements OnDestroy { this.model$ .pipe( - takeUntil(this.ngUnsubscribe) + takeUntil(this.ngUnsubscribe), + filter(model => !!model) ) .subscribe(p => { - this.id = p.resourceId; + this.id = 'resourceId' in p ? p.resourceId : p.id; this.kind = '@type' in p ? 'provider' : 'resolver'; if (this.kind === 'provider') { this.store.dispatch(new LoadFilterRequest(this.id)); @@ -90,6 +94,12 @@ export class MetadataOptionsComponent implements OnDestroy { ).subscribe(e => { scroller.scrollToAnchor(e.anchor); }); + + this.store.select(getConfigurationDefinition) + .pipe( + takeUntil(this.ngUnsubscribe) + ) + .subscribe(d => this.definition = d); } onScrollTo(element): void { @@ -105,7 +115,6 @@ export class MetadataOptionsComponent implements OnDestroy { } removeFilter(id: string): void { - console.log(id); this.modalService .open(DeleteFilterComponent) .result @@ -119,6 +128,13 @@ export class MetadataOptionsComponent implements OnDestroy { ); } + onPreview($event: { data: any, parent: Metadata }): void { + this.store.dispatch(new PreviewEntity({ + id: $event.data, + entity: this.definition.getEntity($event.parent) + })); + } + ngOnDestroy(): void { this.ngUnsubscribe.next(); this.ngUnsubscribe.complete(); diff --git a/ui/src/app/metadata/configuration/service/configuration.service.spec.ts b/ui/src/app/metadata/configuration/service/configuration.service.spec.ts index 49e9014ab..40bfb39ac 100644 --- a/ui/src/app/metadata/configuration/service/configuration.service.spec.ts +++ b/ui/src/app/metadata/configuration/service/configuration.service.spec.ts @@ -6,11 +6,16 @@ import { FileBackedHttpMetadataProviderEditor } from '../../provider/model'; import { MetadataSourceEditor } from '../../domain/model/wizards/metadata-source-editor'; import { ResolverService } from '../../domain/service/resolver.service'; import { of } from 'rxjs'; +import { MetadataProviderService } from '../../domain/service/provider.service'; describe(`Configuration Service`, () => { let resolverService: any; + let mockService = { + find: () => of([]) + }; + beforeEach(() => { TestBed.configureTestingModule({ imports: [ @@ -20,9 +25,12 @@ describe(`Configuration Service`, () => { providers: [ MetadataConfigurationService, { - provide: ResolverService, useValue: { - find: () => of([]) - } + provide: ResolverService, + useValue: mockService + }, + { + provide: MetadataProviderService, + useValue: mockService } ] }); diff --git a/ui/src/app/metadata/filter/container/filter-list.component.html b/ui/src/app/metadata/filter/component/filter-list.component.html similarity index 100% rename from ui/src/app/metadata/filter/container/filter-list.component.html rename to ui/src/app/metadata/filter/component/filter-list.component.html diff --git a/ui/src/app/metadata/filter/container/filter-list.component.scss b/ui/src/app/metadata/filter/component/filter-list.component.scss similarity index 100% rename from ui/src/app/metadata/filter/container/filter-list.component.scss rename to ui/src/app/metadata/filter/component/filter-list.component.scss diff --git a/ui/src/app/metadata/filter/component/filter-list.component.spec.ts b/ui/src/app/metadata/filter/component/filter-list.component.spec.ts new file mode 100644 index 000000000..44cc812cb --- /dev/null +++ b/ui/src/app/metadata/filter/component/filter-list.component.spec.ts @@ -0,0 +1,30 @@ +import { TestBed, ComponentFixture } from '@angular/core/testing'; +import { FilterListComponent } from './filter-list.component'; +import { RouterModule } from '@angular/router'; + +describe('Filter List Component', () => { + let fixture: ComponentFixture; + let instance: FilterListComponent; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [], + imports: [ + RouterModule + ], + declarations: [ + FilterListComponent + ], + }); + + fixture = TestBed.createComponent(FilterListComponent); + instance = fixture.componentInstance; + }); + + it('should compile', () => { + fixture.detectChanges(); + + expect(fixture).toBeDefined(); + expect(instance).toBeDefined(); + }); +}); diff --git a/ui/src/app/metadata/filter/container/filter-list.component.ts b/ui/src/app/metadata/filter/component/filter-list.component.ts similarity index 100% rename from ui/src/app/metadata/filter/container/filter-list.component.ts rename to ui/src/app/metadata/filter/component/filter-list.component.ts diff --git a/ui/src/app/metadata/filter/container/filter-list.component.spec.ts b/ui/src/app/metadata/filter/container/filter-list.component.spec.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/ui/src/app/metadata/filter/filter.module.ts b/ui/src/app/metadata/filter/filter.module.ts index 68fdf8b96..f30d517df 100644 --- a/ui/src/app/metadata/filter/filter.module.ts +++ b/ui/src/app/metadata/filter/filter.module.ts @@ -22,7 +22,7 @@ import { FilterCollectionEffects } from './effect/collection.effect'; import { FormModule } from '../../schema-form/schema-form.module'; import { I18nModule } from '../../i18n/i18n.module'; import { FilterComponent } from './container/filter.component'; -import { FilterListComponent } from './container/filter-list.component'; +import { FilterListComponent } from './component/filter-list.component'; @NgModule({ declarations: [ diff --git a/ui/src/app/metadata/filter/model/entity-attributes-configuration.filter.ts b/ui/src/app/metadata/filter/model/entity-attributes-configuration.filter.ts index 60d09539f..5333e08f1 100644 --- a/ui/src/app/metadata/filter/model/entity-attributes-configuration.filter.ts +++ b/ui/src/app/metadata/filter/model/entity-attributes-configuration.filter.ts @@ -1,51 +1,10 @@ import { Wizard } from '../../../wizard/model'; import { MetadataFilter } from '../../domain/model'; import { removeNulls } from '../../../shared/util'; -import { EntityAttributesFilterEntity } from '../../domain/entity'; +import { EntityAttributesFilter } from './entity-attributes.filter'; export const EntityAttributesFilterConfiguration: Wizard = { - label: 'EntityAttributes', - type: 'EntityAttributes', - schema: '/api/ui/EntityAttributesFilters', - getEntity(filter: MetadataFilter): EntityAttributesFilterEntity { - return new EntityAttributesFilterEntity(filter); - }, - getValidators(namesList: string[] = []): any { - const validators = { - '/': (value, property, form_current) => { - let errors; - // iterate all customer - Object.keys(value).forEach((key) => { - const item = value[key]; - const validatorKey = `/${key}`; - const validator = validators.hasOwnProperty(validatorKey) ? validators[validatorKey] : null; - const error = validator ? validator(item, { path: `/${key}` }, form_current) : null; - if (error) { - errors = errors || []; - errors.push(error); - } - }); - return errors; - }, - '/name': (value, property, form) => { - const err = namesList.indexOf(value) > -1 ? { - code: 'INVALID_NAME', - path: `#${property.path}`, - message: 'message.name-must-be-unique', - params: [value] - } : null; - return err; - } - }; - return validators; - }, - parser: (changes: any): MetadataFilter => { - return { - ...changes, - relyingPartyOverrides: removeNulls(new EntityAttributesFilterEntity(changes).relyingPartyOverrides) - }; - }, - formatter: (changes: MetadataFilter): any => changes, + ...EntityAttributesFilter, steps: [ { id: 'target', diff --git a/ui/src/app/metadata/filter/model/nameid-configuration.filter.ts b/ui/src/app/metadata/filter/model/nameid-configuration.filter.ts index 0452c683f..9c82117ae 100644 --- a/ui/src/app/metadata/filter/model/nameid-configuration.filter.ts +++ b/ui/src/app/metadata/filter/model/nameid-configuration.filter.ts @@ -1,45 +1,9 @@ import { Wizard } from '../../../wizard/model'; import { MetadataFilter } from '../../domain/model'; -import { NameIDFormatFilterEntity } from '../../domain/entity/filter/nameid-format-filter'; +import { NameIDFilter } from './nameid.filter'; export const NameIDFilterConfiguration: Wizard = { - label: 'NameIDFormat', - type: 'NameIDFormat', - schema: '/api/ui/NameIdFormatFilter', - getEntity(filter: MetadataFilter): NameIDFormatFilterEntity { - return new NameIDFormatFilterEntity(filter); - }, - getValidators(namesList: string[] = []): any { - const validators = { - '/': (value, property, form_current) => { - let errors; - // iterate all customer - Object.keys(value).forEach((key) => { - const item = value[key]; - const validatorKey = `/${key}`; - const validator = validators.hasOwnProperty(validatorKey) ? validators[validatorKey] : null; - const error = validator ? validator(item, { path: `/${key}` }, form_current) : null; - if (error) { - errors = errors || []; - errors.push(error); - } - }); - return errors; - }, - '/name': (value, property, form) => { - const err = namesList.indexOf(value) > -1 ? { - code: 'INVALID_NAME', - path: `#${property.path}`, - message: 'message.name-must-be-unique', - params: [value] - } : null; - return err; - } - }; - return validators; - }, - parser: (changes: any): MetadataFilter => changes, - formatter: (changes: MetadataFilter): any => changes, + ...NameIDFilter, steps: [ { id: 'target', diff --git a/ui/src/app/metadata/provider/container/provider-filter-list.component.spec.ts b/ui/src/app/metadata/provider/container/provider-filter-list.component.spec.ts index 67e526f5d..bc1d737c0 100644 --- a/ui/src/app/metadata/provider/container/provider-filter-list.component.spec.ts +++ b/ui/src/app/metadata/provider/container/provider-filter-list.component.spec.ts @@ -1,16 +1,17 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, Input, Output, EventEmitter } from '@angular/core'; import { TestBed, async, ComponentFixture } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { StoreModule, Store, combineReducers } from '@ngrx/store'; -import { NgbDropdownModule, NgbModalModule, NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { NgbDropdownModule, NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ProviderFilterListComponent } from './provider-filter-list.component'; import * as fromRoot from '../reducer'; import * as fromWizard from '../../../wizard/reducer'; -import { EditorNavComponent } from '../../domain/component/editor-nav.component'; +import { EditorNavComponent, NAV_FORMATS } from '../../domain/component/editor-nav.component'; import { ValidFormIconComponent } from '../../../shared/component/valid-form-icon.component'; import { DeleteFilterComponent } from '../component/delete-filter.component'; import { NgbModalStub } from '../../../../testing/modal.stub'; import { MockI18nModule } from '../../../../testing/i18n.stub'; +import { FilterListComponentStub } from '../../../../testing/filter-list.stub'; @Component({ template: ` @@ -45,7 +46,8 @@ describe('Provider Filter List Component', () => { EditorNavComponent, ValidFormIconComponent, DeleteFilterComponent, - TestHostComponent + TestHostComponent, + FilterListComponentStub ], providers: [ { provide: NgbModal, useClass: NgbModalStub } diff --git a/ui/src/app/wizard/model/form-definition.ts b/ui/src/app/wizard/model/form-definition.ts index 997937961..3f03957c0 100644 --- a/ui/src/app/wizard/model/form-definition.ts +++ b/ui/src/app/wizard/model/form-definition.ts @@ -1,7 +1,7 @@ export interface FormDefinition { label: string; type: string; - schema?: string; + schema: string; bindings?: any; getEntity?(entity: any): any; parser(changes: Partial, schema?: any); diff --git a/ui/src/app/wizard/model/wizard.ts b/ui/src/app/wizard/model/wizard.ts index 870c1bc93..5729c4f24 100644 --- a/ui/src/app/wizard/model/wizard.ts +++ b/ui/src/app/wizard/model/wizard.ts @@ -1,7 +1,7 @@ import { FormDefinition } from './form-definition'; export interface Wizard extends FormDefinition { - steps?: WizardStep[]; + steps: WizardStep[]; schema: string; } diff --git a/ui/src/testing/filter-list.stub.ts b/ui/src/testing/filter-list.stub.ts new file mode 100644 index 000000000..37944825b --- /dev/null +++ b/ui/src/testing/filter-list.stub.ts @@ -0,0 +1,27 @@ +import { Component, Input, Output, EventEmitter } from '@angular/core'; +import { MetadataFilter } from '../app/metadata/domain/model'; +import { NAV_FORMATS } from '../app/metadata/domain/component/editor-nav.component'; + +/* tslint:disable */ +@Component({ + selector: 'filter-list', + template: `
` +}) +export class FilterListComponentStub { + @Input() filters: MetadataFilter[]; + @Input() disabled: boolean; + + @Output() onUpdateOrderUp: EventEmitter = new EventEmitter(); + @Output() onUpdateOrderDown: EventEmitter = new EventEmitter(); + @Output() onRemove: EventEmitter = new EventEmitter(); + @Output() onToggleEnabled: EventEmitter = new EventEmitter(); + + formats = NAV_FORMATS; +} + +/* tslint:disable */ +@Component({ + selector: 'filter-configuration-list', + template: `
` +}) +export class FilterConfigurationListComponentStub extends FilterListComponentStub {} diff --git a/ui/src/testing/metadata-configuration.stub.ts b/ui/src/testing/metadata-configuration.stub.ts new file mode 100644 index 000000000..c29e29d1b --- /dev/null +++ b/ui/src/testing/metadata-configuration.stub.ts @@ -0,0 +1,23 @@ +import { Component, Input } from '@angular/core'; +import { MetadataConfiguration } from '../app/metadata/configuration/model/metadata-configuration'; +import { MetadataVersion } from '../app/metadata/configuration/model/version'; + +/* tslint:disable */ +@Component({ + selector: 'metadata-configuration', + template: `` +}) +export class MetadataConfigurationComponentStub { + @Input() configuration: MetadataConfiguration; +} + +@Component({ + selector: 'metadata-header', + template: `` +}) +export class MetadataHeaderComponentStub { + @Input() isEnabled: boolean; + @Input() version: MetadataVersion; + @Input() versionNumber: number; + @Input() isCurrent: boolean; +}