From 59d818e5a4983caf3d05da436aa045206d27ad23 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 11 Jul 2019 07:28:45 -0700 Subject: [PATCH 01/14] SHIBUI-1270 Initial commit for comparison --- .../configuration/action/compare.action.ts | 47 +++++++++++++++++++ .../configuration/configuration.module.ts | 15 ++++-- .../configuration/configuration.routing.ts | 5 ++ .../metadata-comparison.component.html | 0 .../metadata-comparison.component.spec.ts | 0 .../metadata-comparison.component.ts | 24 ++++++++++ .../container/metadata-history.component.html | 4 +- .../container/metadata-history.component.ts | 5 ++ .../container/metadata-options.component.html | 4 +- .../configuration/effect/compare.effect.ts | 28 +++++++++++ .../configuration/reducer/compare.reducer.ts | 30 ++++++++++++ .../metadata/configuration/reducer/index.ts | 10 +++- .../configuration/service/history.service.ts | 9 ++++ .../widget/array/array.component.html | 2 +- .../widget/array/array.component.ts | 19 ++++---- .../array/inline-obj-list.component.html | 2 +- 16 files changed, 182 insertions(+), 22 deletions(-) create mode 100644 ui/src/app/metadata/configuration/action/compare.action.ts create mode 100644 ui/src/app/metadata/configuration/container/metadata-comparison.component.html create mode 100644 ui/src/app/metadata/configuration/container/metadata-comparison.component.spec.ts create mode 100644 ui/src/app/metadata/configuration/container/metadata-comparison.component.ts create mode 100644 ui/src/app/metadata/configuration/effect/compare.effect.ts create mode 100644 ui/src/app/metadata/configuration/reducer/compare.reducer.ts diff --git a/ui/src/app/metadata/configuration/action/compare.action.ts b/ui/src/app/metadata/configuration/action/compare.action.ts new file mode 100644 index 000000000..5bb5e2699 --- /dev/null +++ b/ui/src/app/metadata/configuration/action/compare.action.ts @@ -0,0 +1,47 @@ +import { Action } from '@ngrx/store'; +import { MetadataHistory } from '../model/history'; +import { MetadataVersion } from '../model/version'; +import { Metadata } from '../../domain/domain.type'; + +export enum CompareActionTypes { + COMPARE_METADATA_REQUEST = '[Compare Version] Compare Version Request', + COMPARE_METADATA_SUCCESS = '[Compare Version] Compare Version Success', + COMPARE_METADATA_ERROR = '[Compare Version] Compare Version Error', + SET_VERSIONS = '[Compare Version] Set Versions', + CLEAR_VERSIONS = '[Compare Version] Clear Versions' +} + +export class CompareVersionRequest implements Action { + readonly type = CompareActionTypes.COMPARE_METADATA_REQUEST; + + constructor(public payload: MetadataVersion[]) { } +} + +export class CompareVersionSuccess implements Action { + readonly type = CompareActionTypes.COMPARE_METADATA_SUCCESS; + + constructor(public payload: MetadataHistory) { } +} + +export class CompareVersionError implements Action { + readonly type = CompareActionTypes.COMPARE_METADATA_ERROR; + + constructor(public payload: any) { } +} + +export class SetMetadataVersions implements Action { + readonly type = CompareActionTypes.SET_VERSIONS; + + constructor(public payload: Metadata[]) { } +} + +export class ClearVersions implements Action { + readonly type = CompareActionTypes.CLEAR_VERSIONS; +} + +export type CompareActionsUnion = + | CompareVersionRequest + | CompareVersionSuccess + | CompareVersionError + | SetMetadataVersions + | ClearVersions; diff --git a/ui/src/app/metadata/configuration/configuration.module.ts b/ui/src/app/metadata/configuration/configuration.module.ts index dc291952c..05fa99298 100644 --- a/ui/src/app/metadata/configuration/configuration.module.ts +++ b/ui/src/app/metadata/configuration/configuration.module.ts @@ -2,7 +2,7 @@ import { NgModule, ModuleWithProviders } from '@angular/core'; import { CommonModule } from '@angular/common'; import { StoreModule } from '@ngrx/store'; import { EffectsModule } from '@ngrx/effects'; - +import { RouterModule } from '@angular/router'; import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; import { I18nModule } from '../../i18n/i18n.module'; @@ -15,7 +15,6 @@ import { ConfigurationPropertyComponent } from './component/configuration-proper import { PrimitivePropertyComponent } from './component/primitive-property.component'; import { ObjectPropertyComponent } from './component/object-property.component'; import { ArrayPropertyComponent } from './component/array-property.component'; -import { RouterModule } from '@angular/router'; import { MetadataOptionsComponent } from './container/metadata-options.component'; import { MetadataXmlComponent } from './container/metadata-xml.component'; import { MetadataHeaderComponent } from './component/metadata-header.component'; @@ -24,6 +23,8 @@ import { MetadataHistoryService } from './service/history.service'; import { MetadataHistoryComponent } from './container/metadata-history.component'; import { HistoryListComponent } from './component/history-list.component'; import { DomainModule } from '../domain/domain.module'; +import { MetadataComparisonComponent } from './container/metadata-comparison.component'; +import { CompareVersionEffects } from './effect/compare.effect'; @NgModule({ declarations: [ @@ -37,7 +38,8 @@ import { DomainModule } from '../domain/domain.module'; ConfigurationComponent, MetadataHeaderComponent, MetadataHistoryComponent, - HistoryListComponent + HistoryListComponent, + MetadataComparisonComponent ], entryComponents: [], imports: [ @@ -66,7 +68,12 @@ export class MetadataConfigurationModule { imports: [ MetadataConfigurationModule, StoreModule.forFeature('metadata-configuration', fromConfig.reducers), - EffectsModule.forFeature([MetadataConfigurationEffects, MetadataHistoryEffects]) + EffectsModule.forFeature( + [ + MetadataConfigurationEffects, + MetadataHistoryEffects, + CompareVersionEffects + ]) ], providers: [] }) diff --git a/ui/src/app/metadata/configuration/configuration.routing.ts b/ui/src/app/metadata/configuration/configuration.routing.ts index d27b29872..0a77b0c2b 100644 --- a/ui/src/app/metadata/configuration/configuration.routing.ts +++ b/ui/src/app/metadata/configuration/configuration.routing.ts @@ -3,6 +3,7 @@ import { ConfigurationComponent } from './container/configuration.component'; import { MetadataOptionsComponent } from './container/metadata-options.component'; import { MetadataXmlComponent } from './container/metadata-xml.component'; import { MetadataHistoryComponent } from './container/metadata-history.component'; +import { MetadataComparisonComponent } from './container/metadata-comparison.component'; export const ConfigurationRoutes: Routes = [ { @@ -24,6 +25,10 @@ export const ConfigurationRoutes: Routes = [ { path: 'history', component: MetadataHistoryComponent + }, + { + path: 'compare', + component: MetadataComparisonComponent } ] } diff --git a/ui/src/app/metadata/configuration/container/metadata-comparison.component.html b/ui/src/app/metadata/configuration/container/metadata-comparison.component.html new file mode 100644 index 000000000..e69de29bb diff --git a/ui/src/app/metadata/configuration/container/metadata-comparison.component.spec.ts b/ui/src/app/metadata/configuration/container/metadata-comparison.component.spec.ts new file mode 100644 index 000000000..e69de29bb diff --git a/ui/src/app/metadata/configuration/container/metadata-comparison.component.ts b/ui/src/app/metadata/configuration/container/metadata-comparison.component.ts new file mode 100644 index 000000000..ee2c64e0e --- /dev/null +++ b/ui/src/app/metadata/configuration/container/metadata-comparison.component.ts @@ -0,0 +1,24 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { Observable } from 'rxjs'; +import { Store } from '@ngrx/store'; +import { ConfigurationState, getVersionCollection } from '../reducer'; +import { Metadata } from '../../domain/domain.type'; +import { ActivatedRoute } from '@angular/router'; + +@Component({ + selector: 'metadata-comparison', + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './metadata-comparison.component.html', + styleUrls: [] +}) +export class MetadataComparisonComponent { + + versions$: Observable; + + constructor( + private store: Store, + private activatedRoute: ActivatedRoute + ) { + this.activatedRoute.queryParams.subscribe(versions => console.log(versions)); + } +} diff --git a/ui/src/app/metadata/configuration/container/metadata-history.component.html b/ui/src/app/metadata/configuration/container/metadata-history.component.html index 225912756..2bcc27fe5 100644 --- a/ui/src/app/metadata/configuration/container/metadata-history.component.html +++ b/ui/src/app/metadata/configuration/container/metadata-history.component.html @@ -1,3 +1,5 @@
- +
diff --git a/ui/src/app/metadata/configuration/container/metadata-history.component.ts b/ui/src/app/metadata/configuration/container/metadata-history.component.ts index 6fb60bdb9..636385077 100644 --- a/ui/src/app/metadata/configuration/container/metadata-history.component.ts +++ b/ui/src/app/metadata/configuration/container/metadata-history.component.ts @@ -3,6 +3,7 @@ import { Observable } from 'rxjs'; import { Store } from '@ngrx/store'; import { ConfigurationState, getVersionCollection } from '../reducer'; import { MetadataVersion } from '../model/version'; +import { CompareVersionRequest } from '../action/compare.action'; @Component({ selector: 'metadata-history', @@ -19,4 +20,8 @@ export class MetadataHistoryComponent { ) { this.history$ = this.store.select(getVersionCollection); } + + compareVersions(versions: MetadataVersion[]): void { + this.store.dispatch(new CompareVersionRequest(versions)); + } } 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 0825b10d4..9c4dbb489 100644 --- a/ui/src/app/metadata/configuration/container/metadata-options.component.html +++ b/ui/src/app/metadata/configuration/container/metadata-options.component.html @@ -4,13 +4,11 @@ [version]="version$ | async" [versionNumber]="versionNumber$ | async" [isCurrent]="isCurrent$ | async"> -
-
Options XML diff --git a/ui/src/app/metadata/configuration/effect/compare.effect.ts b/ui/src/app/metadata/configuration/effect/compare.effect.ts new file mode 100644 index 000000000..4b8b08a59 --- /dev/null +++ b/ui/src/app/metadata/configuration/effect/compare.effect.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@angular/core'; +import { Effect, Actions, ofType } from '@ngrx/effects'; +import { switchMap, catchError, tap, withLatestFrom } from 'rxjs/operators'; +import { of } from 'rxjs'; +import { MetadataHistoryService } from '../service/history.service'; +import { CompareVersionRequest, CompareActionTypes } from '../action/compare.action'; +import { Store } from '@ngrx/store'; +import { State, getConfigurationModel } from '../reducer'; +import { ActivatedRoute, RouterState, RouterStateSnapshot } from '@angular/router'; + +@Injectable() +export class CompareVersionEffects { + + @Effect({dispatch: false}) + compareVersionRequest$ = this.actions$.pipe( + ofType(CompareActionTypes.COMPARE_METADATA_REQUEST), + withLatestFrom( + this.store.select(getConfigurationModel) + ), + tap((data) => console.log(data, '@type' in data[1])) + ); + + constructor( + private historyService: MetadataHistoryService, + private store: Store, + private actions$: Actions + ) { } +} diff --git a/ui/src/app/metadata/configuration/reducer/compare.reducer.ts b/ui/src/app/metadata/configuration/reducer/compare.reducer.ts new file mode 100644 index 000000000..a703875af --- /dev/null +++ b/ui/src/app/metadata/configuration/reducer/compare.reducer.ts @@ -0,0 +1,30 @@ +import { CompareActionTypes, CompareActionsUnion } from '../action/compare.action'; +import { Metadata } from '../../domain/domain.type'; + +export interface State { + models: Metadata[]; + loaded: Boolean; +} + +export const initialState: State = { + models: [], + loaded: false +}; + +export function reducer(state = initialState, action: CompareActionsUnion): State { + switch (action.type) { + case CompareActionTypes.SET_VERSIONS: + return { + ...state, + models: action.payload, + loaded: true + }; + case CompareActionTypes.CLEAR_VERSIONS: + return { + ...initialState + }; + default: { + return state; + } + } +} diff --git a/ui/src/app/metadata/configuration/reducer/index.ts b/ui/src/app/metadata/configuration/reducer/index.ts index 702e731f4..470442b76 100644 --- a/ui/src/app/metadata/configuration/reducer/index.ts +++ b/ui/src/app/metadata/configuration/reducer/index.ts @@ -3,6 +3,7 @@ import { createSelector, createFeatureSelector } from '@ngrx/store'; import * as fromRoot from '../../../app.reducer'; import * as fromConfiguration from './configuration.reducer'; import * as fromHistory from './history.reducer'; +import * as fromCompare from './compare.reducer'; import { WizardStep } from '../../../wizard/model'; import * as utils from '../../domain/utility/configuration'; @@ -12,11 +13,13 @@ import { getInCollectionFn } from '../../domain/domain.util'; export interface ConfigurationState { configuration: fromConfiguration.State; history: fromHistory.HistoryState; + compare: fromCompare.State; } export const reducers = { configuration: fromConfiguration.reducer, - history: fromHistory.reducer + history: fromHistory.reducer, + compare: fromCompare.reducer }; export interface State extends fromRoot.State { @@ -27,6 +30,7 @@ export const getState = createFeatureSelector('metadata-conf export const getConfigurationStateFn = (state: ConfigurationState) => state.configuration; export const getHistoryStateFn = (state: ConfigurationState) => state.history; +export const getCompareStateFn = (state: ConfigurationState) => state.compare; export const getConfigurationState = createSelector(getState, getConfigurationStateFn); export const getConfigurationModel = createSelector(getConfigurationState, fromConfiguration.getModel); @@ -83,3 +87,7 @@ export const getSelectedIsCurrent = createSelector( return selected ? collection[0].id === selected.id : null; } ); + +// Version Comparison + +export const getCompareState = createSelector(getState, getCompareStateFn); diff --git a/ui/src/app/metadata/configuration/service/history.service.ts b/ui/src/app/metadata/configuration/service/history.service.ts index 3125c2091..2e55db65b 100644 --- a/ui/src/app/metadata/configuration/service/history.service.ts +++ b/ui/src/app/metadata/configuration/service/history.service.ts @@ -6,6 +6,7 @@ import { MetadataHistory } from '../model/history'; import { PATHS } from '../../configuration/configuration.values'; import { MetadataVersion } from '../model/version'; import { map } from 'rxjs/operators'; +import { Metadata } from '../../domain/domain.type'; @Injectable() export class MetadataHistoryService { @@ -24,4 +25,12 @@ export class MetadataHistoryService { })) ); } + + find(resourceId: string, versions: MetadataVersion, type: string): Observable { + return of([]); + } + + getVersion(resourceId: string, type: string): Observable { + return of(); + } } diff --git a/ui/src/app/schema-form/widget/array/array.component.html b/ui/src/app/schema-form/widget/array/array.component.html index 253fa2af4..620efd944 100644 --- a/ui/src/app/schema-form/widget/array/array.component.html +++ b/ui/src/app/schema-form/widget/array/array.component.html @@ -12,7 +12,7 @@ - + , {{ error.message }} diff --git a/ui/src/app/schema-form/widget/array/array.component.ts b/ui/src/app/schema-form/widget/array/array.component.ts index 698500fca..44f5a90a8 100644 --- a/ui/src/app/schema-form/widget/array/array.component.ts +++ b/ui/src/app/schema-form/widget/array/array.component.ts @@ -18,9 +18,9 @@ export interface FormError { selector: 'array-component', templateUrl: `./array.component.html` }) -export class CustomArrayComponent extends ArrayWidget implements AfterViewInit, OnDestroy { +export class CustomArrayComponent extends ArrayWidget implements AfterViewInit { errors$: Observable; - hasErrors: boolean; + hasErrors$: Observable; hasErrorSub: Subscription; messages = { @@ -29,18 +29,15 @@ export class CustomArrayComponent extends ArrayWidget implements AfterViewInit, ngAfterViewInit(): void { this.errors$ = this.formProperty.errorsChanges.pipe( - map(errors => errors ? errors.filter(err => err.code !== 'UNRESOLVABLE_REFERENCE').reduce((coll, err) => { - coll[err.code] = err; - return coll; - }, {}) : {}), + map(errors => errors ? + errors.filter(err => err.code !== 'UNRESOLVABLE_REFERENCE').reduce((coll, err) => { + coll[err.code] = err; + return coll; + }, {}) : {}), map(collection => Object.values(collection)) ); - this.hasErrorSub = this.errors$.subscribe(e => this.hasErrors = !!e.length); - } - - ngOnDestroy(): void { - this.hasErrorSub.unsubscribe(); + this.hasErrors$ = this.errors$.pipe(map(errors => !!errors.length)); } removeItem(index: number, item: FormProperty = null): void { diff --git a/ui/src/app/schema-form/widget/array/inline-obj-list.component.html b/ui/src/app/schema-form/widget/array/inline-obj-list.component.html index 876ea01f7..59149b0c1 100644 --- a/ui/src/app/schema-form/widget/array/inline-obj-list.component.html +++ b/ui/src/app/schema-form/widget/array/inline-obj-list.component.html @@ -12,7 +12,7 @@ - + , {{ error.message }} From 1fc94d13c1b9a1768532cbfe5e9d20ffde21e768 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 12 Jul 2019 15:16:11 -0700 Subject: [PATCH 02/14] SHIBUI-1270 Implemented metadata comparison component --- .../configuration/action/compare.action.ts | 4 +- .../component/array-property.component.html | 37 +++++---- .../configuration-property.component.ts | 8 +- .../metadata-configuration.component.html | 22 +++-- .../metadata-configuration.component.ts | 26 ++++++ .../component/object-property.component.html | 6 +- .../primitive-property.component.html | 11 ++- .../container/configuration.component.html | 4 +- .../metadata-comparison.component.html | 15 ++++ .../metadata-comparison.component.ts | 16 +++- .../container/metadata-history.component.ts | 13 ++- .../container/metadata-options.component.ts | 2 +- .../configuration/effect/compare.effect.ts | 32 +++++-- .../model/metadata-configuration.ts | 3 +- .../metadata/configuration/model/section.ts | 14 +++- .../compare.reducer.spec.ts} | 0 .../configuration/reducer/compare.reducer.ts | 3 + .../metadata/configuration/reducer/index.ts | 83 ++++++++++++++----- .../configuration/service/history.service.ts | 12 +-- ui/src/app/metadata/domain/model/property.ts | 2 +- .../metadata/domain/utility/configuration.ts | 13 +-- .../resolver/effect/collection.effects.ts | 1 - .../resolver/reducer/collection.reducer.ts | 8 +- 23 files changed, 250 insertions(+), 85 deletions(-) rename ui/src/app/metadata/configuration/{component/configuration-property.component.html => reducer/compare.reducer.spec.ts} (100%) diff --git a/ui/src/app/metadata/configuration/action/compare.action.ts b/ui/src/app/metadata/configuration/action/compare.action.ts index 5bb5e2699..410a8dcab 100644 --- a/ui/src/app/metadata/configuration/action/compare.action.ts +++ b/ui/src/app/metadata/configuration/action/compare.action.ts @@ -14,13 +14,13 @@ export enum CompareActionTypes { export class CompareVersionRequest implements Action { readonly type = CompareActionTypes.COMPARE_METADATA_REQUEST; - constructor(public payload: MetadataVersion[]) { } + constructor(public payload: string[]) { } } export class CompareVersionSuccess implements Action { readonly type = CompareActionTypes.COMPARE_METADATA_SUCCESS; - constructor(public payload: MetadataHistory) { } + constructor(public payload: Metadata[]) { } } export class CompareVersionError implements Action { diff --git a/ui/src/app/metadata/configuration/component/array-property.component.html b/ui/src/app/metadata/configuration/component/array-property.component.html index ee177445e..4dccb304d 100644 --- a/ui/src/app/metadata/configuration/component/array-property.component.html +++ b/ui/src/app/metadata/configuration/component/array-property.component.html @@ -5,12 +5,17 @@
-
+
{{ i + 1 }}.  {{ property.items.properties[prop].title }}
-
- {{ value[prop] }} +
+ {{ v[prop] }}
@@ -25,12 +30,14 @@
- {{ attr.label }} -
- + {{ attr.label }} +
+ true - + false
@@ -40,12 +47,14 @@
- {{ property.name }} -

-
    -
  • - {{ item }} -
  • -
+ {{ property.name }} + +

+
    +
  • + {{ item }} +
  • +
+
\ No newline at end of file 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 bcdd45711..001a8235b 100644 --- a/ui/src/app/metadata/configuration/component/configuration-property.component.ts +++ b/ui/src/app/metadata/configuration/component/configuration-property.component.ts @@ -3,12 +3,12 @@ import { Property } from '../../domain/model/property'; @Component({ selector: 'configuration-property', - template: `{{ property | json }}`, - styleUrls: [] + template: `{{ property | json }}` }) export class ConfigurationPropertyComponent { @Input() property: Property; + @Input() columns = 1; constructor() { } @@ -19,5 +19,9 @@ export class ConfigurationPropertyComponent { getItemType(items: Property): string { return items.widget ? items.widget.id : 'default'; } + + get width(): string { + return `${ Math.floor(100 / (this.columns + 1)) }%`; + } } 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 4f58d07f1..73979ce40 100644 --- a/ui/src/app/metadata/configuration/component/metadata-configuration.component.html +++ b/ui/src/app/metadata/configuration/component/metadata-configuration.component.html @@ -3,10 +3,12 @@

- 0{{ i + 1 }} + + 0{{ i + 1 }} + {{ section.label | translate }}

-
+
- Option - Value + Option + + Value + {{ date | date:'medium' }} +
- + +
-
+
\ No newline at end of file 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 9e94bcdbd..ed568ff32 100644 --- a/ui/src/app/metadata/configuration/component/metadata-configuration.component.ts +++ b/ui/src/app/metadata/configuration/component/metadata-configuration.component.ts @@ -1,6 +1,8 @@ import { Component, ChangeDetectionStrategy, Input } from '@angular/core'; import { Router, ActivatedRoute } from '@angular/router'; import { MetadataConfiguration } from '../model/metadata-configuration'; +import { Property } from '../../domain/model/property'; +import { Observable, of } from 'rxjs'; @Component({ selector: 'metadata-configuration', @@ -19,4 +21,28 @@ export class MetadataConfigurationComponent { edit(id: string): void { this.router.navigate(['../', 'edit', id], { relativeTo: this.activatedRoute.parent }); } + + getItemType(items: Property): string { + return items.widget ? items.widget.id : 'default'; + } + + getKeys(schema): string[] { + return Object.keys(schema.properties); + } + + get attributeList$(): Observable<{ key: string, label: string }[]> { + /* + if (this.property.widget && this.property.widget.hasOwnProperty('data')) { + return of(this.property.widget.data); + } + if (this.property.widget && this.property.widget.hasOwnProperty('dataUrl')) { + return this.attrService.query(this.property.widget.dataUrl); + } + */ + return of([]); + } + + get width(): string { + return `${ Math.floor(100 / this.configuration.dates.length) }%`; + } } diff --git a/ui/src/app/metadata/configuration/component/object-property.component.html b/ui/src/app/metadata/configuration/component/object-property.component.html index b0aa7b967..0c19ac9d0 100644 --- a/ui/src/app/metadata/configuration/component/object-property.component.html +++ b/ui/src/app/metadata/configuration/component/object-property.component.html @@ -1,7 +1,7 @@ - - - + + + diff --git a/ui/src/app/metadata/configuration/component/primitive-property.component.html b/ui/src/app/metadata/configuration/component/primitive-property.component.html index 9eef2181f..608f4acdd 100644 --- a/ui/src/app/metadata/configuration/component/primitive-property.component.html +++ b/ui/src/app/metadata/configuration/component/primitive-property.component.html @@ -1,5 +1,10 @@
- {{ property.name }} - {{ property.value || property.value === false ? property.value : '-' }} + {{ property.name }} + {{ v ? v : (v === false) ? v : '-' }}
\ No newline at end of file diff --git a/ui/src/app/metadata/configuration/container/configuration.component.html b/ui/src/app/metadata/configuration/container/configuration.component.html index e4709611b..b0d813546 100644 --- a/ui/src/app/metadata/configuration/container/configuration.component.html +++ b/ui/src/app/metadata/configuration/container/configuration.component.html @@ -14,7 +14,9 @@

Source Configuration

- + + +
\ No newline at end of file diff --git a/ui/src/app/metadata/configuration/container/metadata-comparison.component.html b/ui/src/app/metadata/configuration/container/metadata-comparison.component.html index e69de29bb..fabdb5338 100644 --- a/ui/src/app/metadata/configuration/container/metadata-comparison.component.html +++ b/ui/src/app/metadata/configuration/container/metadata-comparison.component.html @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/ui/src/app/metadata/configuration/container/metadata-comparison.component.ts b/ui/src/app/metadata/configuration/container/metadata-comparison.component.ts index ee2c64e0e..701c99d2a 100644 --- a/ui/src/app/metadata/configuration/container/metadata-comparison.component.ts +++ b/ui/src/app/metadata/configuration/container/metadata-comparison.component.ts @@ -1,9 +1,12 @@ import { Component, ChangeDetectionStrategy } from '@angular/core'; import { Observable } from 'rxjs'; import { Store } from '@ngrx/store'; -import { ConfigurationState, getVersionCollection } from '../reducer'; -import { Metadata } from '../../domain/domain.type'; import { ActivatedRoute } from '@angular/router'; +import { map } from 'rxjs/operators'; +import { ConfigurationState, getVersionConfigurations } from '../reducer'; +import { Metadata } from '../../domain/domain.type'; +import { CompareVersionRequest } from '../action/compare.action'; +import { MetadataConfiguration } from '../model/metadata-configuration'; @Component({ selector: 'metadata-comparison', @@ -13,12 +16,17 @@ import { ActivatedRoute } from '@angular/router'; }) export class MetadataComparisonComponent { - versions$: Observable; + versions$: Observable; constructor( private store: Store, private activatedRoute: ActivatedRoute ) { - this.activatedRoute.queryParams.subscribe(versions => console.log(versions)); + this.activatedRoute.queryParams.pipe( + map(params => params.versions), + map(versions => new CompareVersionRequest(versions)) + ).subscribe(this.store); + + this.versions$ = this.store.select(getVersionConfigurations); } } diff --git a/ui/src/app/metadata/configuration/container/metadata-history.component.ts b/ui/src/app/metadata/configuration/container/metadata-history.component.ts index 636385077..56669e1bb 100644 --- a/ui/src/app/metadata/configuration/container/metadata-history.component.ts +++ b/ui/src/app/metadata/configuration/container/metadata-history.component.ts @@ -4,6 +4,7 @@ import { Store } from '@ngrx/store'; import { ConfigurationState, getVersionCollection } from '../reducer'; import { MetadataVersion } from '../model/version'; import { CompareVersionRequest } from '../action/compare.action'; +import { Router, ActivatedRoute } from '@angular/router'; @Component({ selector: 'metadata-history', @@ -16,12 +17,20 @@ export class MetadataHistoryComponent { history$: Observable; constructor( - private store: Store + private store: Store, + private router: Router, + private route: ActivatedRoute ) { this.history$ = this.store.select(getVersionCollection); } compareVersions(versions: MetadataVersion[]): void { - this.store.dispatch(new CompareVersionRequest(versions)); + this.router.navigate( + ['../', 'compare'], + { + queryParams: { versions: versions.map(v => v.id) }, + relativeTo: this.route + } + ); } } 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 461252f1d..09cc5b199 100644 --- a/ui/src/app/metadata/configuration/container/metadata-options.component.ts +++ b/ui/src/app/metadata/configuration/container/metadata-options.component.ts @@ -31,7 +31,7 @@ export class MetadataOptionsComponent { constructor( private store: Store ) { - this.configuration$ = this.store.select(getConfigurationSections); + this.configuration$ = this.store.select(getConfigurationSections).pipe(map(config => config)); this.isEnabled$ = this.store.select(getConfigurationModel).pipe( map(config => config ? ('serviceEnabled' in config) ? config.serviceEnabled : config.enabled : false) ); diff --git a/ui/src/app/metadata/configuration/effect/compare.effect.ts b/ui/src/app/metadata/configuration/effect/compare.effect.ts index 4b8b08a59..1b3b4d633 100644 --- a/ui/src/app/metadata/configuration/effect/compare.effect.ts +++ b/ui/src/app/metadata/configuration/effect/compare.effect.ts @@ -1,23 +1,43 @@ import { Injectable } from '@angular/core'; import { Effect, Actions, ofType } from '@ngrx/effects'; -import { switchMap, catchError, tap, withLatestFrom } from 'rxjs/operators'; +import { catchError, withLatestFrom, map, filter, combineLatest, switchMap } from 'rxjs/operators'; import { of } from 'rxjs'; import { MetadataHistoryService } from '../service/history.service'; -import { CompareVersionRequest, CompareActionTypes } from '../action/compare.action'; +import { + CompareVersionRequest, + CompareActionTypes, + CompareVersionSuccess, + CompareVersionError, + SetMetadataVersions +} from '../action/compare.action'; import { Store } from '@ngrx/store'; import { State, getConfigurationModel } from '../reducer'; -import { ActivatedRoute, RouterState, RouterStateSnapshot } from '@angular/router'; @Injectable() export class CompareVersionEffects { - @Effect({dispatch: false}) + @Effect() compareVersionRequest$ = this.actions$.pipe( ofType(CompareActionTypes.COMPARE_METADATA_REQUEST), - withLatestFrom( + map(action => action.payload), + combineLatest( this.store.select(getConfigurationModel) ), - tap((data) => console.log(data, '@type' in data[1])) + switchMap(([versions, model]) => { + const type = '@type' in model ? 'provider' : 'resolver'; + const id = '@type' in model ? model.resourceId : model.id; + return this.historyService.getVersions(id, versions, type).pipe( + map(v => new CompareVersionSuccess(v)), + catchError(err => of(new CompareVersionError(err))) + ); + }) + ); + + @Effect() + setVersionsOnSuccess$ = this.actions$.pipe( + ofType(CompareActionTypes.COMPARE_METADATA_SUCCESS), + map(action => action.payload), + map(versions => new SetMetadataVersions(versions)) ); constructor( diff --git a/ui/src/app/metadata/configuration/model/metadata-configuration.ts b/ui/src/app/metadata/configuration/model/metadata-configuration.ts index b8a37b85e..a06dda3f5 100644 --- a/ui/src/app/metadata/configuration/model/metadata-configuration.ts +++ b/ui/src/app/metadata/configuration/model/metadata-configuration.ts @@ -1,5 +1,6 @@ -import Section from './section'; +import { Section } from './section'; export interface MetadataConfiguration { sections: Section[]; + dates: String[]; } diff --git a/ui/src/app/metadata/configuration/model/section.ts b/ui/src/app/metadata/configuration/model/section.ts index 089a1953a..fd7f9b00f 100644 --- a/ui/src/app/metadata/configuration/model/section.ts +++ b/ui/src/app/metadata/configuration/model/section.ts @@ -1,11 +1,17 @@ -import { Property } from '../../domain/model/property'; - export interface Section { id: string; index: number; label: string; pageNumber: number; - properties: Property[]; + properties: SectionProperty[]; } -export default Section; +export interface SectionProperty { + label: string; + type: string; + value: any[]; + widget?: { + id: string; + [propertyName: string]: any; + }; +} diff --git a/ui/src/app/metadata/configuration/component/configuration-property.component.html b/ui/src/app/metadata/configuration/reducer/compare.reducer.spec.ts similarity index 100% rename from ui/src/app/metadata/configuration/component/configuration-property.component.html rename to ui/src/app/metadata/configuration/reducer/compare.reducer.spec.ts diff --git a/ui/src/app/metadata/configuration/reducer/compare.reducer.ts b/ui/src/app/metadata/configuration/reducer/compare.reducer.ts index a703875af..ea674238f 100644 --- a/ui/src/app/metadata/configuration/reducer/compare.reducer.ts +++ b/ui/src/app/metadata/configuration/reducer/compare.reducer.ts @@ -28,3 +28,6 @@ export function reducer(state = initialState, action: CompareActionsUnion): Stat } } } + +export const getVersionModels = (state: State) => state.models; +export const getVersionModelsLoaded = (state: State) => state.loaded; diff --git a/ui/src/app/metadata/configuration/reducer/index.ts b/ui/src/app/metadata/configuration/reducer/index.ts index 470442b76..a92497ddf 100644 --- a/ui/src/app/metadata/configuration/reducer/index.ts +++ b/ui/src/app/metadata/configuration/reducer/index.ts @@ -9,6 +9,8 @@ import { WizardStep } from '../../../wizard/model'; import * as utils from '../../domain/utility/configuration'; import { getSplitSchema } from '../../../wizard/reducer'; import { getInCollectionFn } from '../../domain/domain.util'; +import { MetadataConfiguration } from '../model/metadata-configuration'; +import { Property } from '../../domain/model/property'; export interface ConfigurationState { configuration: fromConfiguration.State; @@ -34,32 +36,63 @@ export const getCompareStateFn = (state: ConfigurationState) => state.compare; export const getConfigurationState = createSelector(getState, getConfigurationStateFn); export const getConfigurationModel = createSelector(getConfigurationState, fromConfiguration.getModel); +export const getConfigurationModelList = createSelector(getConfigurationModel, (model) => [model]); export const getConfigurationDefinition = createSelector(getConfigurationState, fromConfiguration.getDefinition); export const getConfigurationSchema = createSelector(getConfigurationState, fromConfiguration.getSchema); export const getConfigurationXml = createSelector(getConfigurationState, fromConfiguration.getXml); -export const getConfigurationSectionsFn = (model, definition, schema) => !definition || !schema ? null : - ({ - sections: definition.steps - .filter(step => step.id !== 'summary') - .map( - (step: WizardStep, num: number) => { - return ({ - id: step.id, - pageNumber: num + 1, - index: step.index, - label: step.label, - properties: utils.getStepProperties( - getSplitSchema(schema, step), - definition.formatter(model), - schema.definitions || {} - ) - }); - } - ) +export const assignValueToProperties = (models, properties): any[] => { + return properties.map(prop => { + switch (prop.type) { + case 'object': + return { + ...prop, + properties: assignValueToProperties(models.map(model => model[prop.id] || {}), prop.properties) + }; + default: + return { + ...prop, + value: models.map(model => { + return model[prop.id]; + }) + }; + } }); +}; + +export const getConfigurationSectionsFn = (models, definition, schema): MetadataConfiguration => { + console.log(models); + return !definition || !schema ? null : + ({ + dates: models.map(m => m.updatedDate), + sections: definition.steps + .filter(step => step.id !== 'summary') + .map( + (step: WizardStep, num: number) => { + return ({ + id: step.id, + pageNumber: num + 1, + index: step.index, + label: step.label, + properties: utils.getStepProperties( + getSplitSchema(schema, step), + definition.formatter({}), + schema.definitions || {} + ) + }); + } + ) + .map((section: any) => { + return { + ...section, + properties: assignValueToProperties(models, section.properties) + }; + }) + }); + }; + export const getConfigurationSections = createSelector( - getConfigurationModel, + getConfigurationModelList, getConfigurationDefinition, getConfigurationSchema, getConfigurationSectionsFn @@ -91,3 +124,13 @@ export const getSelectedIsCurrent = createSelector( // Version Comparison export const getCompareState = createSelector(getState, getCompareStateFn); +export const getVersionModels = createSelector(getCompareState, fromCompare.getVersionModels); +export const getVersionModelsLoaded = createSelector(getCompareState, fromCompare.getVersionModelsLoaded); +export const getVersionConfigurations = createSelector( + getVersionModels, + getConfigurationDefinition, + getConfigurationSchema, + getConfigurationSectionsFn +); + + diff --git a/ui/src/app/metadata/configuration/service/history.service.ts b/ui/src/app/metadata/configuration/service/history.service.ts index 2e55db65b..8dbcf9029 100644 --- a/ui/src/app/metadata/configuration/service/history.service.ts +++ b/ui/src/app/metadata/configuration/service/history.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { Observable, of } from 'rxjs'; +import { Observable, of, forkJoin } from 'rxjs'; import { MetadataHistory } from '../model/history'; import { PATHS } from '../../configuration/configuration.values'; @@ -26,11 +26,13 @@ export class MetadataHistoryService { ); } - find(resourceId: string, versions: MetadataVersion, type: string): Observable { - return of([]); + getVersions(resourceId: string, versions: string[], type: string): Observable { + return forkJoin(versions.map( + v => this.getVersion(resourceId, type, v) + )); } - getVersion(resourceId: string, type: string): Observable { - return of(); + getVersion(resourceId: string, type: string, versionId: string): Observable { + return this.http.get(`/${this.base}/${PATHS[type]}/${resourceId}/${this.path}/${versionId}`); } } diff --git a/ui/src/app/metadata/domain/model/property.ts b/ui/src/app/metadata/domain/model/property.ts index a792514d8..dcd5e9f1b 100644 --- a/ui/src/app/metadata/domain/model/property.ts +++ b/ui/src/app/metadata/domain/model/property.ts @@ -2,7 +2,7 @@ export interface Property { title?: string; type: string; name: string; - value: string[]; + value: any[]; items: Property; properties: Property[]; widget?: { diff --git a/ui/src/app/metadata/domain/utility/configuration.ts b/ui/src/app/metadata/domain/utility/configuration.ts index dc641c4dd..2d5572cb4 100644 --- a/ui/src/app/metadata/domain/utility/configuration.ts +++ b/ui/src/app/metadata/domain/utility/configuration.ts @@ -33,10 +33,13 @@ export function getStepProperties(schema: any, model: any, definitions: any = {} return Object .keys(schema.properties) .map(property => { - return getStepProperty( - schema.properties[property], - model && model.hasOwnProperty(property) ? model[property] : null, - definitions - ); + return { + ...getStepProperty( + schema.properties[property], + model && model.hasOwnProperty(property) ? model[property] : null, + definitions + ), + id: property + }; }); } diff --git a/ui/src/app/metadata/resolver/effect/collection.effects.ts b/ui/src/app/metadata/resolver/effect/collection.effects.ts index e5f1edd94..ff5c5ea9c 100644 --- a/ui/src/app/metadata/resolver/effect/collection.effects.ts +++ b/ui/src/app/metadata/resolver/effect/collection.effects.ts @@ -10,7 +10,6 @@ import { LoadResolverRequest, LoadResolverSuccess, LoadResolverError, - LoadAdminResolverRequest, AddResolverRequest, AddResolverSuccess, AddResolverFail, diff --git a/ui/src/app/metadata/resolver/reducer/collection.reducer.ts b/ui/src/app/metadata/resolver/reducer/collection.reducer.ts index 9ce28324b..925255d96 100644 --- a/ui/src/app/metadata/resolver/reducer/collection.reducer.ts +++ b/ui/src/app/metadata/resolver/reducer/collection.reducer.ts @@ -32,11 +32,11 @@ export function reducer(state = initialState, action: ResolverCollectionActionsU return adapter.updateOne(action.payload, state); } - case ResolverCollectionActionTypes.SELECT: { - return { + case ResolverCollectionActionTypes.SELECT_SUCCESS: { + return adapter.addOne(action.payload, { ...state, - selectedResolverId: action.payload, - }; + selectedResolverId: action.payload.id, + }); } case ResolverCollectionActionTypes.LOAD_RESOLVER_ERROR: { From db62acbd2619722981e46d3a6dcc4c1f5594a298 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 15 Jul 2019 13:37:41 -0700 Subject: [PATCH 03/14] SHIBUI-1270 Fixed issue with array layouts --- .../component/array-property.component.html | 25 ++++++++++--------- .../component/array-property.component.ts | 11 ++++++-- .../metadata-configuration.component.html | 2 +- .../container/metadata-history.component.ts | 6 ++++- .../metadata/configuration/reducer/index.ts | 1 - ui/tsconfig.json | 1 + 6 files changed, 29 insertions(+), 17 deletions(-) diff --git a/ui/src/app/metadata/configuration/component/array-property.component.html b/ui/src/app/metadata/configuration/component/array-property.component.html index 4dccb304d..969bd175e 100644 --- a/ui/src/app/metadata/configuration/component/array-property.component.html +++ b/ui/src/app/metadata/configuration/component/array-property.component.html @@ -1,23 +1,24 @@
{{ property.name }}
-
-
-
-
- {{ i + 1 }}.  - {{ property.items.properties[prop].title }} -
-
+
+
+ {{ property.items.properties[prop].title }} +
+ +
- {{ v[prop] }} + {{ version[i][prop] }}
-
+
+ — +
+
diff --git a/ui/src/app/metadata/configuration/component/array-property.component.ts b/ui/src/app/metadata/configuration/component/array-property.component.ts index ff9cd0ac4..35d50dedd 100644 --- a/ui/src/app/metadata/configuration/component/array-property.component.ts +++ b/ui/src/app/metadata/configuration/component/array-property.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, OnChanges } from '@angular/core'; import { Property } from '../../domain/model/property'; import { Observable, of } from 'rxjs'; import { AttributesService } from '../../domain/service/attributes.service'; @@ -10,15 +10,22 @@ import { ConfigurationPropertyComponent } from './configuration-property.compone styleUrls: [] }) -export class ArrayPropertyComponent extends ConfigurationPropertyComponent { +export class ArrayPropertyComponent extends ConfigurationPropertyComponent implements OnChanges { @Input() property: Property; + range = []; + constructor( private attrService: AttributesService ) { super(); } + ngOnChanges(): void { + const keys = this.property.value.reduce((val, version) => version ? version.length > val ? version.length : val : val, 0); + this.range = [...Array(keys).keys()]; + } + get attributeList$(): Observable<{ key: string, label: string }[]> { if (this.property.widget && this.property.widget.hasOwnProperty('data')) { return of(this.property.widget.data); 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 73979ce40..82034cca4 100644 --- a/ui/src/app/metadata/configuration/component/metadata-configuration.component.html +++ b/ui/src/app/metadata/configuration/component/metadata-configuration.component.html @@ -1,5 +1,5 @@
-
+

diff --git a/ui/src/app/metadata/configuration/container/metadata-history.component.ts b/ui/src/app/metadata/configuration/container/metadata-history.component.ts index 56669e1bb..f7caf2219 100644 --- a/ui/src/app/metadata/configuration/container/metadata-history.component.ts +++ b/ui/src/app/metadata/configuration/container/metadata-history.component.ts @@ -28,7 +28,11 @@ export class MetadataHistoryComponent { this.router.navigate( ['../', 'compare'], { - queryParams: { versions: versions.map(v => v.id) }, + queryParams: { versions: versions.sort((a, b) => { + const aDate = new Date(a.date).getTime(); + const bDate = new Date(b.date).getTime(); + return aDate === bDate ? 0 : aDate < bDate ? -1 : 1; + }).map(v => v.id) }, relativeTo: this.route } ); diff --git a/ui/src/app/metadata/configuration/reducer/index.ts b/ui/src/app/metadata/configuration/reducer/index.ts index a92497ddf..82beef304 100644 --- a/ui/src/app/metadata/configuration/reducer/index.ts +++ b/ui/src/app/metadata/configuration/reducer/index.ts @@ -61,7 +61,6 @@ export const assignValueToProperties = (models, properties): any[] => { }; export const getConfigurationSectionsFn = (models, definition, schema): MetadataConfiguration => { - console.log(models); return !definition || !schema ? null : ({ dates: models.map(m => m.updatedDate), diff --git a/ui/tsconfig.json b/ui/tsconfig.json index ff13e7e77..8fd46afd8 100644 --- a/ui/tsconfig.json +++ b/ui/tsconfig.json @@ -8,6 +8,7 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "allowSyntheticDefaultImports": true, + "downlevelIteration": true, "target": "es5", "typeRoots": [ "node_modules/@types" From 226e37770a739fedad09156293140e3c742c46ae Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 16 Jul 2019 08:19:14 -0700 Subject: [PATCH 04/14] SHIBUI-1270 Fixed existing tests --- .../component/array-property.component.spec.ts | 4 ++-- .../component/metadata-configuration.component.spec.ts | 6 +++++- .../container/configuration.component.spec.ts | 5 ++++- .../container/metadata-history.component.spec.ts | 9 +++++++++ .../container/metadata-options.component.spec.ts | 5 ++++- .../container/metadata-xml.component.spec.ts | 2 -- ui/src/app/metadata/configuration/reducer/index.spec.ts | 2 +- ui/src/app/metadata/configuration/reducer/index.ts | 2 +- .../metadata/resolver/reducer/collection.reducer.spec.ts | 8 ++++---- 9 files changed, 30 insertions(+), 13 deletions(-) diff --git a/ui/src/app/metadata/configuration/component/array-property.component.spec.ts b/ui/src/app/metadata/configuration/component/array-property.component.spec.ts index 453d9d484..614738b06 100644 --- a/ui/src/app/metadata/configuration/component/array-property.component.spec.ts +++ b/ui/src/app/metadata/configuration/component/array-property.component.spec.ts @@ -21,12 +21,12 @@ class TestHostComponent { @ViewChild(ArrayPropertyComponent) public componentUnderTest: ArrayPropertyComponent; - property: Property = getStepProperty(SCHEMA.properties.list, { + property: Property = getStepProperty(SCHEMA.properties.list, [{ name: 'foo', type: 'baz', description: 'foo bar baz', list: [] - }, SCHEMA.definitions); + }], SCHEMA.definitions); setProperty(property: Property): void { this.property = property; diff --git a/ui/src/app/metadata/configuration/component/metadata-configuration.component.spec.ts b/ui/src/app/metadata/configuration/component/metadata-configuration.component.spec.ts index f26c8d65c..1d72b1b7e 100644 --- a/ui/src/app/metadata/configuration/component/metadata-configuration.component.spec.ts +++ b/ui/src/app/metadata/configuration/component/metadata-configuration.component.spec.ts @@ -14,6 +14,7 @@ import { MockI18nModule } from '../../../../testing/i18n.stub'; }) class ObjectPropertyComponent { @Input() property: Property; + @Input() columns = 1; } @Component({ @@ -25,7 +26,10 @@ class TestHostComponent { @ViewChild(MetadataConfigurationComponent) public componentUnderTest: MetadataConfigurationComponent; - configuration: MetadataConfiguration = {sections: []}; + configuration: MetadataConfiguration = { + dates: [], + sections: [] + }; } describe('Metadata Configuration Component', () => { diff --git a/ui/src/app/metadata/configuration/container/configuration.component.spec.ts b/ui/src/app/metadata/configuration/container/configuration.component.spec.ts index c399fbacf..bc82b8a14 100644 --- a/ui/src/app/metadata/configuration/container/configuration.component.spec.ts +++ b/ui/src/app/metadata/configuration/container/configuration.component.spec.ts @@ -18,7 +18,10 @@ class TestHostComponent { @ViewChild(ConfigurationComponent) public componentUnderTest: ConfigurationComponent; - configuration: MetadataConfiguration = { sections: [] }; + configuration: MetadataConfiguration = { + dates: [], + sections: [] + }; } describe('Metadata Configuration Page Component', () => { diff --git a/ui/src/app/metadata/configuration/container/metadata-history.component.spec.ts b/ui/src/app/metadata/configuration/container/metadata-history.component.spec.ts index 084d79ef0..cab2e2da1 100644 --- a/ui/src/app/metadata/configuration/container/metadata-history.component.spec.ts +++ b/ui/src/app/metadata/configuration/container/metadata-history.component.spec.ts @@ -8,6 +8,9 @@ import { MetadataHistoryService } from '../service/history.service'; import { of } from 'rxjs'; import { StoreModule, combineReducers } from '@ngrx/store'; import * as fromConfiguration from '../reducer'; +import { Router, ActivatedRoute } from '@angular/router'; +import { RouterStub } from '../../../../testing/router.stub'; +import { ActivatedRouteStub } from '../../../../testing/activated-route.stub'; export const TestData = { versions: [ @@ -43,6 +46,12 @@ describe('Metadata Version History Component', () => { providers: [ { provide: MetadataHistoryService, useValue: MockHistoryService + }, + { + provide: Router, useClass: RouterStub + }, + { + provide: ActivatedRoute, useClass: ActivatedRouteStub } ], imports: [ 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 0cb1bd5b0..a012fcd70 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 @@ -40,7 +40,10 @@ class TestHostComponent { @ViewChild(MetadataOptionsComponent) public componentUnderTest: MetadataOptionsComponent; - configuration: MetadataConfiguration = { sections: [] }; + configuration: MetadataConfiguration = { + dates: [], + sections: [] + }; } describe('Metadata Options Page Component', () => { diff --git a/ui/src/app/metadata/configuration/container/metadata-xml.component.spec.ts b/ui/src/app/metadata/configuration/container/metadata-xml.component.spec.ts index 81fbd836f..6f7e052e3 100644 --- a/ui/src/app/metadata/configuration/container/metadata-xml.component.spec.ts +++ b/ui/src/app/metadata/configuration/container/metadata-xml.component.spec.ts @@ -17,8 +17,6 @@ import { MetadataXmlComponent } from './metadata-xml.component'; class TestHostComponent { @ViewChild(MetadataXmlComponent) public componentUnderTest: MetadataXmlComponent; - - configuration: MetadataConfiguration = { sections: [] }; } describe('Metadata Xml Page Component', () => { diff --git a/ui/src/app/metadata/configuration/reducer/index.spec.ts b/ui/src/app/metadata/configuration/reducer/index.spec.ts index 5a675621c..cb470cba7 100644 --- a/ui/src/app/metadata/configuration/reducer/index.spec.ts +++ b/ui/src/app/metadata/configuration/reducer/index.spec.ts @@ -12,7 +12,7 @@ describe('Configuration Reducer', () => { describe('getConfigurationSectionsFn', () => { it('should parse the schema, definition, and model into a MetadataConfiguration', () => { - const config = getConfigurationSectionsFn(model, definition, schema); + const config = getConfigurationSectionsFn([model], definition, schema); expect(config.sections).toBeDefined(); }); }); diff --git a/ui/src/app/metadata/configuration/reducer/index.ts b/ui/src/app/metadata/configuration/reducer/index.ts index 82beef304..3b86ae925 100644 --- a/ui/src/app/metadata/configuration/reducer/index.ts +++ b/ui/src/app/metadata/configuration/reducer/index.ts @@ -63,7 +63,7 @@ export const assignValueToProperties = (models, properties): any[] => { export const getConfigurationSectionsFn = (models, definition, schema): MetadataConfiguration => { return !definition || !schema ? null : ({ - dates: models.map(m => m.updatedDate), + dates: models.map(m => m.modifiedDate), sections: definition.steps .filter(step => step.id !== 'summary') .map( 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 26e8dc34d..43b1ebfe3 100644 --- a/ui/src/app/metadata/resolver/reducer/collection.reducer.spec.ts +++ b/ui/src/app/metadata/resolver/reducer/collection.reducer.spec.ts @@ -73,13 +73,13 @@ describe('Resolver Reducer', () => { describe('Select Resolver', () => { it('should update the selected draft id', () => { let id = 'foo', + createdDate = new Date().toDateString(), expected = { ...snapshot, selectedResolverId: id }; - const action = new resolverActions.SelectResolver(id); + const action = new resolverActions.SelectResolverSuccess({ id, createdDate } as MetadataResolver); const result = reducer({ ...snapshot }, action); - expect(result).toEqual( - Object.assign({}, initialState, expected) - ); + expect(result.selectedResolverId).toEqual(id); + expect(result.ids.length).toBe(3); }); }); }); From dd0ad8626fe9269eca998b44a0780c67723c6c03 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 16 Jul 2019 09:54:00 -0700 Subject: [PATCH 05/14] SHIBUI-1270 Implemented new unit tests --- .../component/history-list.component.spec.ts | 10 ++++ .../metadata-configuration.component.spec.ts | 28 +++++++++ .../metadata-configuration.component.ts | 23 +------- .../container/configuration.component.ts | 7 +-- .../metadata-history.component.spec.ts | 57 +++++++++++++++++-- .../container/metadata-history.component.ts | 15 +++-- .../container/metadata-options.component.ts | 10 ++-- .../reducer/compare.reducer.spec.ts | 53 +++++++++++++++++ .../configuration/reducer/index.spec.ts | 23 +++++++- .../metadata/configuration/reducer/index.ts | 10 ++++ .../container/new-resolver.component.ts | 4 +- 11 files changed, 195 insertions(+), 45 deletions(-) diff --git a/ui/src/app/metadata/configuration/component/history-list.component.spec.ts b/ui/src/app/metadata/configuration/component/history-list.component.spec.ts index 43d49a29f..3c191c300 100644 --- a/ui/src/app/metadata/configuration/component/history-list.component.spec.ts +++ b/ui/src/app/metadata/configuration/component/history-list.component.spec.ts @@ -79,4 +79,14 @@ describe('Metadata History List Component', () => { expect(instance.restore).toHaveBeenCalledWith(selected); }); }); + + describe('toggleVersionSelected method', () => { + it('should add or remove the selected version', () => { + list.toggleVersionSelected(TestData.versions[0]); + fixture.detectChanges(); + list.toggleVersionSelected(TestData.versions[0]); + fixture.detectChanges(); + expect(list.selected.length).toBe(0); + }); + }); }); diff --git a/ui/src/app/metadata/configuration/component/metadata-configuration.component.spec.ts b/ui/src/app/metadata/configuration/component/metadata-configuration.component.spec.ts index 1d72b1b7e..c17a469af 100644 --- a/ui/src/app/metadata/configuration/component/metadata-configuration.component.spec.ts +++ b/ui/src/app/metadata/configuration/component/metadata-configuration.component.spec.ts @@ -7,6 +7,7 @@ import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; import { MetadataConfiguration } from '../model/metadata-configuration'; import { Property } from '../../domain/model/property'; import { MockI18nModule } from '../../../../testing/i18n.stub'; +import { Router } from '@angular/router'; @Component({ selector: 'object-property', @@ -37,6 +38,7 @@ describe('Metadata Configuration Component', () => { let fixture: ComponentFixture; let instance: TestHostComponent; let app: MetadataConfigurationComponent; + let router: Router; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -55,10 +57,36 @@ describe('Metadata Configuration Component', () => { fixture = TestBed.createComponent(TestHostComponent); instance = fixture.componentInstance; app = instance.componentUnderTest; + router = TestBed.get(Router); fixture.detectChanges(); })); it('should accept a configuration input', async(() => { expect(app).toBeTruthy(); })); + + describe('edit method', () => { + it('should call router.navigate', () => { + spyOn(router, 'navigate'); + app.edit('foo'); + expect(router.navigate).toHaveBeenCalled(); + }); + }); + + describe('width getter', () => { + it('should default to 100%', () => { + expect(app.width).toBe('100%'); + }); + it('should calculate the width based on dates', () => { + instance.configuration = { + ...instance.configuration, + dates: [ + new Date().toISOString(), + new Date().toISOString() + ] + }; + fixture.detectChanges(); + expect(app.width).toBe('33%'); + }); + }); }); 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 ed568ff32..fd90fb58b 100644 --- a/ui/src/app/metadata/configuration/component/metadata-configuration.component.ts +++ b/ui/src/app/metadata/configuration/component/metadata-configuration.component.ts @@ -22,27 +22,8 @@ export class MetadataConfigurationComponent { this.router.navigate(['../', 'edit', id], { relativeTo: this.activatedRoute.parent }); } - getItemType(items: Property): string { - return items.widget ? items.widget.id : 'default'; - } - - getKeys(schema): string[] { - return Object.keys(schema.properties); - } - - get attributeList$(): Observable<{ key: string, label: string }[]> { - /* - if (this.property.widget && this.property.widget.hasOwnProperty('data')) { - return of(this.property.widget.data); - } - if (this.property.widget && this.property.widget.hasOwnProperty('dataUrl')) { - return this.attrService.query(this.property.widget.dataUrl); - } - */ - return of([]); - } - get width(): string { - return `${ Math.floor(100 / this.configuration.dates.length) }%`; + const columns = this.configuration.dates.length; + return `${Math.floor(100 / (columns + 1)) }%`; } } diff --git a/ui/src/app/metadata/configuration/container/configuration.component.ts b/ui/src/app/metadata/configuration/container/configuration.component.ts index 357d745fd..17ce4b99c 100644 --- a/ui/src/app/metadata/configuration/container/configuration.component.ts +++ b/ui/src/app/metadata/configuration/container/configuration.component.ts @@ -52,12 +52,7 @@ export class ConfigurationComponent implements OnDestroy { } }); - this.name$ = this.store - .select(fromReducer.getConfigurationModel) - .pipe( - filter(model => !!model), - map(model => model ? ('serviceProviderName' in model) ? model.serviceProviderName : model.name : false) - ); + this.name$ = this.store.select(fromReducer.getConfigurationModelName); } ngOnDestroy() { diff --git a/ui/src/app/metadata/configuration/container/metadata-history.component.spec.ts b/ui/src/app/metadata/configuration/container/metadata-history.component.spec.ts index cab2e2da1..43d8cc11b 100644 --- a/ui/src/app/metadata/configuration/container/metadata-history.component.spec.ts +++ b/ui/src/app/metadata/configuration/container/metadata-history.component.spec.ts @@ -15,10 +15,9 @@ import { ActivatedRouteStub } from '../../../../testing/activated-route.stub'; export const TestData = { versions: [ { - versionNumber: 1, - saveDate: new Date(), - changedBy: 'admin', - actions: [] + id: '1', + date: new Date().toDateString(), + creator: 'admin' } ] }; @@ -40,6 +39,7 @@ const MockHistoryService = { describe('Metadata Version History Component', () => { let fixture: ComponentFixture; let instance: MetadataHistoryComponent; + let router: Router; beforeEach(() => { TestBed.configureTestingModule({ @@ -68,10 +68,59 @@ describe('Metadata Version History Component', () => { fixture = TestBed.createComponent(MetadataHistoryComponent); instance = fixture.componentInstance; + router = TestBed.get(Router); + spyOn(router, 'navigate'); fixture.detectChanges(); }); it('should compile', () => { expect(instance).toBeDefined(); }); + + describe('compare versions method', () => { + it('should call the router.navigate method', () => { + instance.compareVersions(TestData.versions); + expect(router.navigate).toHaveBeenCalled(); + }); + }); + + describe('sortVersionsByDate method', () => { + it('should sort the versions by their date', () => { + const nowTime = new Date().getTime(); + const futureTime = nowTime + 10000; + const beforeTime = nowTime - 10000; + const nowDate = new Date(nowTime); + const futureDate = new Date(futureTime); + const beforeDate = new Date(beforeTime); + + const versions = [ + { + id: 'foo', + creator: 'bar', + date: nowDate.toISOString() + }, + { + id: 'bar', + creator: 'baz', + date: beforeDate.toISOString() + }, + { + id: 'baz', + creator: 'foo', + date: beforeDate.toISOString() + }, + { + id: 'baz2', + creator: 'foo', + date: futureDate.toISOString() + } + ]; + + const sorted = instance.sortVersionsByDate(versions); + expect(sorted[0].id).toEqual('bar'); + expect(sorted[1].id).toEqual('baz'); + expect(sorted[2].id).toEqual('foo'); + expect(sorted[3].id).toEqual('baz2'); + }); + }); }); diff --git a/ui/src/app/metadata/configuration/container/metadata-history.component.ts b/ui/src/app/metadata/configuration/container/metadata-history.component.ts index f7caf2219..6d62e6ed7 100644 --- a/ui/src/app/metadata/configuration/container/metadata-history.component.ts +++ b/ui/src/app/metadata/configuration/container/metadata-history.component.ts @@ -24,15 +24,20 @@ export class MetadataHistoryComponent { this.history$ = this.store.select(getVersionCollection); } + sortVersionsByDate(versions: MetadataVersion[]): MetadataVersion[] { + return versions.sort((a, b) => { + const aDate = new Date(a.date).getTime(); + const bDate = new Date(b.date).getTime(); + return aDate === bDate ? 0 : aDate < bDate ? -1 : 1; + }); + } + compareVersions(versions: MetadataVersion[]): void { + const sorted = this.sortVersionsByDate(versions); this.router.navigate( ['../', 'compare'], { - queryParams: { versions: versions.sort((a, b) => { - const aDate = new Date(a.date).getTime(); - const bDate = new Date(b.date).getTime(); - return aDate === bDate ? 0 : aDate < bDate ? -1 : 1; - }).map(v => v.id) }, + queryParams: { versions: sorted.map(v => v.id) }, relativeTo: this.route } ); 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 09cc5b199..556aa8805 100644 --- a/ui/src/app/metadata/configuration/container/metadata-options.component.ts +++ b/ui/src/app/metadata/configuration/container/metadata-options.component.ts @@ -8,11 +8,13 @@ import { getConfigurationModel, getSelectedVersion, getSelectedVersionNumber, - getSelectedIsCurrent + getSelectedIsCurrent, + getConfigurationModelEnabled } from '../reducer'; import { MetadataConfiguration } from '../model/metadata-configuration'; import { MetadataVersion } from '../model/version'; import { map } from 'rxjs/operators'; +import { Metadata } from '../../domain/domain.type'; @Component({ selector: 'metadata-options-page', @@ -31,10 +33,8 @@ export class MetadataOptionsComponent { constructor( private store: Store ) { - this.configuration$ = this.store.select(getConfigurationSections).pipe(map(config => config)); - this.isEnabled$ = this.store.select(getConfigurationModel).pipe( - map(config => config ? ('serviceEnabled' in config) ? config.serviceEnabled : config.enabled : false) - ); + this.configuration$ = this.store.select(getConfigurationSections); + this.isEnabled$ = this.store.select(getConfigurationModelEnabled); this.version$ = this.store.select(getSelectedVersion); this.versionNumber$ = this.store.select(getSelectedVersionNumber); this.isCurrent$ = this.store.select(getSelectedIsCurrent); diff --git a/ui/src/app/metadata/configuration/reducer/compare.reducer.spec.ts b/ui/src/app/metadata/configuration/reducer/compare.reducer.spec.ts index e69de29bb..4423c6be9 100644 --- a/ui/src/app/metadata/configuration/reducer/compare.reducer.spec.ts +++ b/ui/src/app/metadata/configuration/reducer/compare.reducer.spec.ts @@ -0,0 +1,53 @@ +import { reducer } from './compare.reducer'; +import * as fromCompare from './compare.reducer'; +import { MetadataResolver } from '../../domain/model'; +import { SetMetadataVersions, ClearVersions } from '../action/compare.action'; + +describe('Comparison Reducer', () => { + const initialState: fromCompare.State = { ...fromCompare.initialState }; + const models: MetadataResolver[] = [{ + id: 'foo', + serviceProviderName: 'foo', + '@type': 'MetadataResolver', + createdBy: 'admin' + }]; + + describe('undefined action', () => { + it('should return the default state', () => { + const result = reducer(undefined, {} as any); + + expect(result).toEqual(initialState); + }); + }); + + describe('set versions action', () => { + it('should add the models to the state', () => { + const action = new SetMetadataVersions(models); + const result = reducer(initialState, action); + expect(result.models).toEqual(models); + expect(result.loaded).toBe(true); + }); + }); + + describe('clear versions action', () => { + it('should remove the models from the state', () => { + const action = new ClearVersions(); + const result = reducer(initialState, action); + expect(result.models).toEqual([]); + expect(result.loaded).toBe(false); + }); + }); + + describe('selector functions', () => { + describe('getModel', () => { + it('should retrieve the model from state', () => { + expect(fromCompare.getVersionModels({ ...initialState, models })).toBe(models); + }); + }); + describe('getVersionModelsLoaded', () => { + it('should retrieve the loaded state', () => { + expect(fromCompare.getVersionModelsLoaded({ ...initialState, loaded: true })).toBe(true); + }); + }); + }); +}); diff --git a/ui/src/app/metadata/configuration/reducer/index.spec.ts b/ui/src/app/metadata/configuration/reducer/index.spec.ts index cb470cba7..eba8409be 100644 --- a/ui/src/app/metadata/configuration/reducer/index.spec.ts +++ b/ui/src/app/metadata/configuration/reducer/index.spec.ts @@ -1,6 +1,11 @@ -import { getConfigurationSectionsFn } from './index'; +import { + getConfigurationSectionsFn, + getConfigurationModelNameFn, + getConfigurationModelEnabledFn +} from './index'; import { SCHEMA as schema } from '../../../../testing/form-schema.stub'; import { MetadataSourceEditor } from '../../domain/model/wizards/metadata-source-editor'; +import { Metadata } from '../../domain/domain.type'; describe('Configuration Reducer', () => { const model = { @@ -16,4 +21,20 @@ describe('Configuration Reducer', () => { expect(config.sections).toBeDefined(); }); }); + + describe('getConfigurationModelNameFn function', () => { + it('should return the name attribute', () => { + expect(getConfigurationModelNameFn({ serviceProviderName: 'foo' } as Metadata)).toBe('foo'); + expect(getConfigurationModelNameFn({ name: 'bar' } as Metadata)).toBe('bar'); + expect(getConfigurationModelNameFn(null)).toBe(false); + }); + }); + + describe('getConfigurationModelEnabledFn function', () => { + it('should return the name attribute', () => { + expect(getConfigurationModelEnabledFn({ serviceEnabled: true } as Metadata)).toBe(true); + expect(getConfigurationModelEnabledFn({ enabled: true } as Metadata)).toBe(true); + expect(getConfigurationModelEnabledFn(null)).toBe(false); + }); + }); }); diff --git a/ui/src/app/metadata/configuration/reducer/index.ts b/ui/src/app/metadata/configuration/reducer/index.ts index 3b86ae925..baf934164 100644 --- a/ui/src/app/metadata/configuration/reducer/index.ts +++ b/ui/src/app/metadata/configuration/reducer/index.ts @@ -11,6 +11,7 @@ import { getSplitSchema } from '../../../wizard/reducer'; import { getInCollectionFn } from '../../domain/domain.util'; import { MetadataConfiguration } from '../model/metadata-configuration'; import { Property } from '../../domain/model/property'; +import { Metadata } from '../../domain/domain.type'; export interface ConfigurationState { configuration: fromConfiguration.State; @@ -97,6 +98,15 @@ export const getConfigurationSections = createSelector( getConfigurationSectionsFn ); +export const getConfigurationModelEnabledFn = + (config: Metadata) => config ? ('serviceEnabled' in config) ? config.serviceEnabled : config.enabled : false; + +export const getConfigurationModelNameFn = + (config: Metadata) => config ? ('serviceProviderName' in config) ? config.serviceProviderName : config.name : false; + +export const getConfigurationModelEnabled = createSelector(getConfigurationModel, getConfigurationModelEnabledFn); +export const getConfigurationModelName = createSelector(getConfigurationModel, getConfigurationModelNameFn); + // Version History export const getHistoryState = createSelector(getState, getHistoryStateFn); diff --git a/ui/src/app/metadata/resolver/container/new-resolver.component.ts b/ui/src/app/metadata/resolver/container/new-resolver.component.ts index 09efb0f1f..f58392e21 100644 --- a/ui/src/app/metadata/resolver/container/new-resolver.component.ts +++ b/ui/src/app/metadata/resolver/container/new-resolver.component.ts @@ -36,9 +36,7 @@ export class NewResolverComponent implements OnDestroy { this.actionsSubscription = this.route.queryParams.pipe( takeUntil(this.ngUnsubscribe), distinctUntilChanged(), - map(data => { - return new SelectDraftRequest(data.id); - }) + map(data => new SelectDraftRequest(data.id)) ).subscribe(this.store); } ngOnDestroy(): void { From 757d2b8d2c8d8d5309af0d8b1c89a7d900ee5cbd Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 16 Jul 2019 10:08:57 -0700 Subject: [PATCH 06/14] SHIBUI-1270 Fixed a11y issue --- .../configuration/effect/compare.effect.ts | 2 +- ui/src/theme/breadcrumb.scss | 15 ++------------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/ui/src/app/metadata/configuration/effect/compare.effect.ts b/ui/src/app/metadata/configuration/effect/compare.effect.ts index 1b3b4d633..bb6e077d2 100644 --- a/ui/src/app/metadata/configuration/effect/compare.effect.ts +++ b/ui/src/app/metadata/configuration/effect/compare.effect.ts @@ -20,7 +20,7 @@ export class CompareVersionEffects { compareVersionRequest$ = this.actions$.pipe( ofType(CompareActionTypes.COMPARE_METADATA_REQUEST), map(action => action.payload), - combineLatest( + withLatestFrom( this.store.select(getConfigurationModel) ), switchMap(([versions, model]) => { diff --git a/ui/src/theme/breadcrumb.scss b/ui/src/theme/breadcrumb.scss index f1e5a6c93..9482c7233 100644 --- a/ui/src/theme/breadcrumb.scss +++ b/ui/src/theme/breadcrumb.scss @@ -1,5 +1,5 @@ .breadcrumb-bar { - $default-color: $gray-400; + $default-color: $gray-700; padding: 0; margin: 1rem 0; @@ -7,18 +7,7 @@ border-radius: 0; padding: 0.375rem 0; border-bottom: 1px solid $gray-600; - /* - &, & > .breadcrumb-item.active { + & > .breadcrumb-item.active { color: $default-color; } - > .breadcrumb-item > a { - color: $white; - } - - & > .breadcrumb-item + .breadcrumb-item { - &::before { - color: $default-color; - } - } - */ } \ No newline at end of file From 1afd84774db5e1a8ed9b45756cdbbe29e60c3eaf Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 19 Jul 2019 15:25:19 -0700 Subject: [PATCH 07/14] SHIBUI-1332 converted filter list to re-usable component --- .../configuration/configuration.module.ts | 4 +- .../container/configuration.component.html | 6 +- .../container/configuration.component.ts | 2 + .../container/metadata-options.component.html | 17 +++-- .../container/metadata-options.component.ts | 39 +++++++++-- .../effect/configuration.effect.ts | 23 ++----- .../metadata/configuration/reducer/index.ts | 6 ++ .../service/configuration.service.ts | 4 ++ .../domain/service/entity-id.service.ts | 2 - .../container/filter-list.component.html | 62 +++++++++++++++++ .../container/filter-list.component.scss | 17 +++++ .../container/filter-list.component.spec.ts | 0 .../filter/container/filter-list.component.ts | 25 +++++++ ui/src/app/metadata/filter/filter.module.ts | 7 +- .../component/provider-search.component.html | 3 +- .../dashboard-providers-list.component.html | 5 +- .../provider-filter-list.component.html | 66 +++---------------- .../app/metadata/provider/provider.module.ts | 4 +- 18 files changed, 198 insertions(+), 94 deletions(-) create mode 100644 ui/src/app/metadata/filter/container/filter-list.component.html create mode 100644 ui/src/app/metadata/filter/container/filter-list.component.scss create mode 100644 ui/src/app/metadata/filter/container/filter-list.component.spec.ts create mode 100644 ui/src/app/metadata/filter/container/filter-list.component.ts diff --git a/ui/src/app/metadata/configuration/configuration.module.ts b/ui/src/app/metadata/configuration/configuration.module.ts index 05fa99298..35fc8ed6b 100644 --- a/ui/src/app/metadata/configuration/configuration.module.ts +++ b/ui/src/app/metadata/configuration/configuration.module.ts @@ -25,6 +25,7 @@ import { HistoryListComponent } from './component/history-list.component'; import { DomainModule } from '../domain/domain.module'; import { MetadataComparisonComponent } from './container/metadata-comparison.component'; import { CompareVersionEffects } from './effect/compare.effect'; +import { FilterModule } from '../filter/filter.module'; @NgModule({ declarations: [ @@ -47,7 +48,8 @@ import { CompareVersionEffects } from './effect/compare.effect'; I18nModule, NgbPopoverModule, RouterModule, - DomainModule + DomainModule, + FilterModule ], exports: [], providers: [] diff --git a/ui/src/app/metadata/configuration/container/configuration.component.html b/ui/src/app/metadata/configuration/container/configuration.component.html index b0d813546..53f8fa697 100644 --- a/ui/src/app/metadata/configuration/container/configuration.component.html +++ b/ui/src/app/metadata/configuration/container/configuration.component.html @@ -13,7 +13,11 @@ -

Source Configuration

+

+ Source + Provider + Configuration +

diff --git a/ui/src/app/metadata/configuration/container/configuration.component.ts b/ui/src/app/metadata/configuration/container/configuration.component.ts index 17ce4b99c..9fb1cc8cd 100644 --- a/ui/src/app/metadata/configuration/container/configuration.component.ts +++ b/ui/src/app/metadata/configuration/container/configuration.component.ts @@ -20,6 +20,7 @@ export class ConfigurationComponent implements OnDestroy { private ngUnsubscribe: Subject = new Subject(); name$: Observable; + type$: Observable constructor( private store: Store, @@ -53,6 +54,7 @@ export class ConfigurationComponent implements OnDestroy { }); this.name$ = this.store.select(fromReducer.getConfigurationModelName); + this.type$ = this.store.select(fromReducer.getConfigurationModelType); } ngOnDestroy() { 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 9c4dbb489..19681afcd 100644 --- a/ui/src/app/metadata/configuration/container/metadata-options.component.html +++ b/ui/src/app/metadata/configuration/container/metadata-options.component.html @@ -9,10 +9,19 @@   Version History -
- Options - XML +
+ Options + XML
- + + +

\ No newline at end of file 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 556aa8805..55abe4634 100644 --- a/ui/src/app/metadata/configuration/container/metadata-options.component.ts +++ b/ui/src/app/metadata/configuration/container/metadata-options.component.ts @@ -1,19 +1,23 @@ import { Store } from '@ngrx/store'; -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { Observable } from 'rxjs'; +import { Component, ChangeDetectionStrategy, OnDestroy } from '@angular/core'; +import { Observable, Subject } from 'rxjs'; import { ConfigurationState, getConfigurationSections, - getConfigurationModel, getSelectedVersion, getSelectedVersionNumber, getSelectedIsCurrent, - getConfigurationModelEnabled + getConfigurationModelEnabled, + getConfigurationHasXml, + getConfigurationModel } from '../reducer'; import { MetadataConfiguration } from '../model/metadata-configuration'; import { MetadataVersion } from '../model/version'; -import { map } from 'rxjs/operators'; +import { MetadataFilter } from '../../domain/model'; +import { getAdditionalFilters } from '../../filter/reducer'; +import { ClearFilters, LoadFilterRequest } from '../../filter/action/collection.action'; +import { takeUntil, map } from 'rxjs/operators'; import { Metadata } from '../../domain/domain.type'; @Component({ @@ -22,21 +26,44 @@ import { Metadata } from '../../domain/domain.type'; templateUrl: './metadata-options.component.html', styleUrls: [] }) -export class MetadataOptionsComponent { +export class MetadataOptionsComponent implements OnDestroy { + + private ngUnsubscribe: Subject = new Subject(); configuration$: Observable; isEnabled$: Observable; version$: Observable; versionNumber$: Observable; isCurrent$: Observable; + hasXml$: Observable; + filters$: Observable; + model$: Observable; constructor( private store: Store ) { this.configuration$ = this.store.select(getConfigurationSections); + this.model$ = this.store.select(getConfigurationModel); this.isEnabled$ = this.store.select(getConfigurationModelEnabled); this.version$ = this.store.select(getSelectedVersion); this.versionNumber$ = this.store.select(getSelectedVersionNumber); this.isCurrent$ = this.store.select(getSelectedIsCurrent); + this.hasXml$ = this.store.select(getConfigurationHasXml); + this.filters$ = this.store.select(getAdditionalFilters); + + this.model$ + .pipe( + takeUntil(this.ngUnsubscribe) + ) + .subscribe(p => { + this.store.dispatch(new LoadFilterRequest(p.resourceId)); + }); + } + + ngOnDestroy(): void { + this.ngUnsubscribe.next(); + this.ngUnsubscribe.complete(); + + this.store.dispatch(new ClearFilters()); } } diff --git a/ui/src/app/metadata/configuration/effect/configuration.effect.ts b/ui/src/app/metadata/configuration/effect/configuration.effect.ts index b9a9c7181..e63b873e7 100644 --- a/ui/src/app/metadata/configuration/effect/configuration.effect.ts +++ b/ui/src/app/metadata/configuration/effect/configuration.effect.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { Effect, Actions, ofType } from '@ngrx/effects'; -import { switchMap, catchError, map, tap, withLatestFrom } from 'rxjs/operators'; +import { switchMap, catchError, map, tap, withLatestFrom, filter } from 'rxjs/operators'; import { of, Observable } from 'rxjs'; import * as FileSaver from 'file-saver'; import { Store } from '@ngrx/store'; @@ -53,22 +53,11 @@ export class MetadataConfigurationEffects { @Effect() loadMetadataXml$ = this.actions$.pipe( ofType(ConfigurationActionTypes.LOAD_METADATA_REQUEST), - switchMap(action => { - let loader: Observable; - switch (action.payload.type) { - case 'filter': - loader = this.entityService.preview(action.payload.id); - break; - default: - loader = this.providerService.preview(action.payload.id); - break; - } - - return loader.pipe( - map(xml => new LoadXmlSuccess(xml)), - catchError(error => of(new LoadXmlError(error))) - ); - }) + filter(action => action.payload.type === 'resolver'), + switchMap(action => this.providerService.preview(action.payload.id).pipe( + map(xml => new LoadXmlSuccess(xml)), + catchError(error => of(new LoadXmlError(error))) + )) ); @Effect() diff --git a/ui/src/app/metadata/configuration/reducer/index.ts b/ui/src/app/metadata/configuration/reducer/index.ts index baf934164..d37312323 100644 --- a/ui/src/app/metadata/configuration/reducer/index.ts +++ b/ui/src/app/metadata/configuration/reducer/index.ts @@ -104,9 +104,15 @@ export const getConfigurationModelEnabledFn = export const getConfigurationModelNameFn = (config: Metadata) => config ? ('serviceProviderName' in config) ? config.serviceProviderName : config.name : false; +export const getConfigurationModelTypeFn = + (config: Metadata) => config ? ('@type' in config) ? config['@type'] : 'resolver' : null; + export const getConfigurationModelEnabled = createSelector(getConfigurationModel, getConfigurationModelEnabledFn); export const getConfigurationModelName = createSelector(getConfigurationModel, getConfigurationModelNameFn); +export const getConfigurationModelType = createSelector(getConfigurationModel, getConfigurationModelTypeFn); +export const getConfigurationHasXml = createSelector(getConfigurationXml, xml => !!xml); +export const getConfigurationFilters = createSelector(getConfigurationModel, model => model.metadataFilters); // Version History export const getHistoryState = createSelector(getState, getHistoryStateFn); diff --git a/ui/src/app/metadata/configuration/service/configuration.service.ts b/ui/src/app/metadata/configuration/service/configuration.service.ts index c361037e0..1ee9507d6 100644 --- a/ui/src/app/metadata/configuration/service/configuration.service.ts +++ b/ui/src/app/metadata/configuration/service/configuration.service.ts @@ -8,12 +8,14 @@ import { MetadataProviderEditorTypes } from '../../provider/model'; import { Schema } from '../model/schema'; import { TYPES } from '../configuration.values'; import { ResolverService } from '../../domain/service/resolver.service'; +import { MetadataProviderService } from '../../domain/service/provider.service'; @Injectable() export class MetadataConfigurationService { constructor( private resolverService: ResolverService, + private providerService: MetadataProviderService, private http: HttpClient ) {} @@ -21,6 +23,8 @@ export class MetadataConfigurationService { switch (type) { case TYPES.resolver: return this.resolverService.find(id); + case TYPES.provider: + return this.providerService.find(id); default: return throwError(new Error('Type not supported')); } diff --git a/ui/src/app/metadata/domain/service/entity-id.service.ts b/ui/src/app/metadata/domain/service/entity-id.service.ts index 8daec78df..07009e3d1 100644 --- a/ui/src/app/metadata/domain/service/entity-id.service.ts +++ b/ui/src/app/metadata/domain/service/entity-id.service.ts @@ -14,8 +14,6 @@ export class EntityIdService { readonly entitiesEndpoint = '/entities'; readonly base = '/api'; - private subj: Subject = new Subject(); - constructor( private http: HttpClient ) { } diff --git a/ui/src/app/metadata/filter/container/filter-list.component.html b/ui/src/app/metadata/filter/container/filter-list.component.html new file mode 100644 index 000000000..6eee1d9d9 --- /dev/null +++ b/ui/src/app/metadata/filter/container/filter-list.component.html @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + +
Filter NameFilter TypeEnabled?EditDelete
+
+ + +
+
{{ i + 1 }}{{ filter.name }}{{ filter['@type'] }} +
+
+ + +
+ +
+
+ + + Edit + + + +
\ No newline at end of file diff --git a/ui/src/app/metadata/filter/container/filter-list.component.scss b/ui/src/app/metadata/filter/container/filter-list.component.scss new file mode 100644 index 000000000..e1a2e17b9 --- /dev/null +++ b/ui/src/app/metadata/filter/container/filter-list.component.scss @@ -0,0 +1,17 @@ +:host { + .table { + .td-sm { + max-width: 100px; + } + .td-xs { + max-width: 20px; + } + .td-lg { + width: 30%; + } + + td { + vertical-align: middle; + } + } +} \ No newline at end of file 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 new file mode 100644 index 000000000..e69de29bb diff --git a/ui/src/app/metadata/filter/container/filter-list.component.ts b/ui/src/app/metadata/filter/container/filter-list.component.ts new file mode 100644 index 000000000..08491102b --- /dev/null +++ b/ui/src/app/metadata/filter/container/filter-list.component.ts @@ -0,0 +1,25 @@ +import { Component, Input, Output, EventEmitter } from '@angular/core'; +import { MetadataFilter } from '../../domain/model'; + +import {} from '../../filter/action/collection.action'; +import { NAV_FORMATS } from '../../domain/component/editor-nav.component'; + +@Component({ + selector: 'filter-list', + templateUrl: './filter-list.component.html', + styleUrls: ['./filter-list.component.scss'] +}) +export class FilterListComponent { + + @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; + + constructor() {} +} diff --git a/ui/src/app/metadata/filter/filter.module.ts b/ui/src/app/metadata/filter/filter.module.ts index e090745f2..68fdf8b96 100644 --- a/ui/src/app/metadata/filter/filter.module.ts +++ b/ui/src/app/metadata/filter/filter.module.ts @@ -22,6 +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'; @NgModule({ declarations: [ @@ -29,7 +30,8 @@ import { FilterComponent } from './container/filter.component'; EditFilterComponent, SelectFilterComponent, SearchDialogComponent, - FilterComponent + FilterComponent, + FilterListComponent ], entryComponents: [ SearchDialogComponent @@ -45,6 +47,9 @@ import { FilterComponent } from './container/filter.component'; RouterModule, FormModule, I18nModule + ], + exports: [ + FilterListComponent ] }) export class FilterModule { diff --git a/ui/src/app/metadata/manager/component/provider-search.component.html b/ui/src/app/metadata/manager/component/provider-search.component.html index 381aa8568..d534cea51 100644 --- a/ui/src/app/metadata/manager/component/provider-search.component.html +++ b/ui/src/app/metadata/manager/component/provider-search.component.html @@ -10,7 +10,8 @@ aria-label="To search for a source, enter name then press enter" formControlName="search" role="textbox" - (keyup)="search.emit($event.target.value)"> + (keyup)="search.emit($event.target.value)" + disableValidation="true">
-
- - - - - - - - - - - - - - - - - - - - - - - -
Filter NameFilter TypeEnabled?EditDelete
- - - {{ i + 1 }}{{ filter.name }}{{ filter['@type'] }} - - - - - - Edit - - - -
+
+ +
diff --git a/ui/src/app/metadata/provider/provider.module.ts b/ui/src/app/metadata/provider/provider.module.ts index 38bfecdf1..99e033e74 100644 --- a/ui/src/app/metadata/provider/provider.module.ts +++ b/ui/src/app/metadata/provider/provider.module.ts @@ -26,6 +26,7 @@ import { DeleteFilterComponent } from './component/delete-filter.component'; import { I18nModule } from '../../i18n/i18n.module'; import { DomainModule } from '../domain/domain.module'; import { MetadataProviderPageComponent } from './provider.component'; +import { FilterModule } from '../filter/filter.module'; @NgModule({ declarations: [ @@ -53,7 +54,8 @@ import { MetadataProviderPageComponent } from './provider.component'; NgbDropdownModule, NgbModalModule, I18nModule, - DomainModule + DomainModule, + FilterModule ], exports: [] }) From 03fc51c9209f1bdbe0979bd2130fa6eb7f0853a8 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 23 Jul 2019 15:23:52 -0700 Subject: [PATCH 08/14] SHIBUI-1332 Implemented filter component --- .../main/resources/i18n/messages.properties | 7 ++ ui/src/app/app.routing.ts | 3 +- .../action/configuration.action.ts | 27 +------ ...ter-configuration-list-item.component.html | 48 ++++++++++++ ...ilter-configuration-list-item.component.ts | 40 ++++++++++ .../filter-configuration-list.component.html | 13 ++++ .../filter-configuration-list.component.ts | 8 ++ .../metadata-configuration.component.html | 11 ++- .../metadata-configuration.component.ts | 2 + .../configuration/configuration.module.ts | 6 +- .../container/configuration.component.html | 2 +- .../container/configuration.component.ts | 6 +- .../container/metadata-options.component.html | 40 ++++++++-- .../container/metadata-options.component.ts | 48 +++++++++++- .../effect/configuration.effect.ts | 50 ++++++------- .../reducer/configuration.reducer.ts | 12 ++- .../metadata/configuration/reducer/index.ts | 16 +++- .../service/configuration.service.ts | 10 ++- .../filter/container/filter-list.component.ts | 2 +- .../filter/effect/collection.effect.ts | 6 ++ .../entity-attributes-configuration.filter.ts | 74 +++++++++++++++++++ ui/src/app/metadata/filter/model/index.ts | 7 ++ .../model/nameid-configuration.filter.ts | 61 +++++++++++++++ .../filter-target.component.html | 2 +- ui/src/app/wizard/model/wizard.ts | 2 +- 25 files changed, 421 insertions(+), 82 deletions(-) create mode 100644 ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html create mode 100644 ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.ts create mode 100644 ui/src/app/metadata/configuration/component/filter-configuration-list.component.html create mode 100644 ui/src/app/metadata/configuration/component/filter-configuration-list.component.ts create mode 100644 ui/src/app/metadata/filter/model/entity-attributes-configuration.filter.ts create mode 100644 ui/src/app/metadata/filter/model/nameid-configuration.filter.ts diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index f3054d636..5bf9688c9 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -41,6 +41,7 @@ action.copy=Copy action.choose-file=Choose File action.search-by=Search By action.preview=Preview +action.preview-xml=Preview XML action.select-metadata-filter-type=Select a metadata filter type action.add-authentication-method=Add Authentication Method action.move-up=Move Up @@ -51,6 +52,9 @@ action.manage-filters=Manage Filters action.version-history=Version History action.options=Options action.xml=XML +action.manage=Manage +action.close=Close +action.back-to-top=Back to Top value.enabled=Enabled value.disabled=Disabled @@ -240,6 +244,7 @@ label.filter-enabled=Filter Enabled label.filter-target=FilterTarget label.filter-type=Filter Type label.option=Option +label.options=Options label.value=Value label.binding-type=Binding Type label.sign-assertion=Sign Assertions @@ -261,6 +266,8 @@ label.make-default=Make Default label.metadata-provider-name-dashboard-display-only=Metadata Provider Name (Dashboard Display Only) label.default-authentication-methods=Default Authentication Method(s) label.new-of-type=New { type } +label.filters=Filters +label.attributes=Attributes label.metadata-filter-name=Metadata Filter Name (Dashboard Display Only) label.filter-enable=Enable this Filter? diff --git a/ui/src/app/app.routing.ts b/ui/src/app/app.routing.ts index 99b8d88de..751b0a36c 100644 --- a/ui/src/app/app.routing.ts +++ b/ui/src/app/app.routing.ts @@ -15,7 +15,8 @@ const routes: Routes = [ @NgModule({ imports: [RouterModule.forRoot(routes, { - preloadingStrategy: PreloadAllModules + preloadingStrategy: PreloadAllModules, + anchorScrolling: 'enabled' })], exports: [RouterModule] }) diff --git a/ui/src/app/metadata/configuration/action/configuration.action.ts b/ui/src/app/metadata/configuration/action/configuration.action.ts index b5b86ade1..78e834eea 100644 --- a/ui/src/app/metadata/configuration/action/configuration.action.ts +++ b/ui/src/app/metadata/configuration/action/configuration.action.ts @@ -4,10 +4,6 @@ import { Schema } from '../model/schema'; import { Wizard } from '../../../wizard/model'; export enum ConfigurationActionTypes { - LOAD_METADATA_REQUEST = '[Metadata Configuration] Load Metadata Request', - LOAD_METADATA_SUCCESS = '[Metadata Configuration] Load Metadata Success', - LOAD_METADATA_ERROR = '[Metadata Configuration] Load Metadata Error', - LOAD_SCHEMA_REQUEST = '[Metadata Configuration] Load Schema Request', LOAD_SCHEMA_SUCCESS = '[Metadata Configuration] Load Schema Success', LOAD_SCHEMA_ERROR = '[Metadata Configuration] Load Schema Error', @@ -26,24 +22,6 @@ export enum ConfigurationActionTypes { CLEAR = '[Metadata Configuration] Clear' } -export class LoadMetadataRequest implements Action { - readonly type = ConfigurationActionTypes.LOAD_METADATA_REQUEST; - - constructor(public payload: { id: string, type: string }) { } -} - -export class LoadMetadataSuccess implements Action { - readonly type = ConfigurationActionTypes.LOAD_METADATA_SUCCESS; - - constructor(public payload: Metadata) { } -} - -export class LoadMetadataError implements Action { - readonly type = ConfigurationActionTypes.LOAD_METADATA_ERROR; - - constructor(public payload: any) { } -} - export class LoadSchemaRequest implements Action { readonly type = ConfigurationActionTypes.LOAD_SCHEMA_REQUEST; @@ -83,7 +61,7 @@ export class LoadXmlError implements Action { export class SetMetadata implements Action { readonly type = ConfigurationActionTypes.SET_METADATA; - constructor(public payload: Metadata) { } + constructor(public payload: { id: string, type: string }) { } } export class SetDefinition implements Action { @@ -113,9 +91,6 @@ export class ClearConfiguration implements Action { } export type ConfigurationActionsUnion = - | LoadMetadataRequest - | LoadMetadataSuccess - | LoadMetadataError | LoadSchemaRequest | LoadSchemaSuccess | LoadSchemaError diff --git a/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html b/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html new file mode 100644 index 000000000..b35efc1a9 --- /dev/null +++ b/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html @@ -0,0 +1,48 @@ +
+ {{ index + 1 }} +
+ + +
+ + {{ filter['@type'] }} + + Enabled + Disabled + +
+
+
+
+ +   + Preview XML + +
+ +   + Edit + + +
+
+ + +
\ No newline at end of file diff --git a/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.ts b/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.ts new file mode 100644 index 000000000..76ff0eefe --- /dev/null +++ b/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.ts @@ -0,0 +1,40 @@ +import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges } from '@angular/core'; +import { MetadataFilter } from '../../domain/model'; +import { MetadataConfigurationService } from '../service/configuration.service'; +import { Wizard } from '../../../wizard/model'; +import { MetadataConfiguration } from '../model/metadata-configuration'; + +@Component({ + selector: 'filter-configuration-list-item', + templateUrl: './filter-configuration-list-item.component.html' +}) +export class FilterConfigurationListItemComponent implements OnChanges { + @Input() filter: MetadataFilter; + @Input() index: number; + @Input() isFirst: boolean; + @Input() isLast: boolean; + + @Output() onUpdateOrderUp: EventEmitter = new EventEmitter(); + @Output() onUpdateOrderDown: EventEmitter = new EventEmitter(); + @Output() onRemove: EventEmitter = new EventEmitter(); + + open = false; + configuration: MetadataConfiguration; + + constructor( + private configService: MetadataConfigurationService + ) {} + + ngOnChanges(changes: SimpleChanges): void { + if (changes.filter) { + const definition = this.configService.getDefinition(this.filter['@type']); + this.configService.loadSchema(definition.schema).subscribe(schema => { + this.configuration = this.configService.getMetadataConfiguration( + this.filter, + definition, + schema + ); + }); + } + } +} diff --git a/ui/src/app/metadata/configuration/component/filter-configuration-list.component.html b/ui/src/app/metadata/configuration/component/filter-configuration-list.component.html new file mode 100644 index 000000000..af8dd280d --- /dev/null +++ b/ui/src/app/metadata/configuration/component/filter-configuration-list.component.html @@ -0,0 +1,13 @@ +
    +
  • + +
  • +
\ No newline at end of file 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 new file mode 100644 index 000000000..b155926d6 --- /dev/null +++ b/ui/src/app/metadata/configuration/component/filter-configuration-list.component.ts @@ -0,0 +1,8 @@ +import { Component } from '@angular/core'; +import { FilterListComponent } from '../../filter/container/filter-list.component'; + +@Component({ + selector: 'filter-configuration-list', + templateUrl: './filter-configuration-list.component.html' +}) +export class FilterConfigurationListComponent extends FilterListComponent { } 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 82034cca4..965b5382d 100644 --- a/ui/src/app/metadata/configuration/component/metadata-configuration.component.html +++ b/ui/src/app/metadata/configuration/component/metadata-configuration.component.html @@ -1,14 +1,17 @@
-
+

- + 0{{ i + 1 }} - {{ section.label | translate }} + {{ section.label | translate }}

-
+
  + {{ item }} + +
    +
  • + {{ item }} +
  • +
+
\ No newline at end of file diff --git a/ui/src/app/metadata/configuration/component/array-property.component.scss b/ui/src/app/metadata/configuration/component/array-property.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/ui/src/app/metadata/configuration/component/array-property.component.ts b/ui/src/app/metadata/configuration/component/array-property.component.ts index 35d50dedd..a17ad01da 100644 --- a/ui/src/app/metadata/configuration/component/array-property.component.ts +++ b/ui/src/app/metadata/configuration/component/array-property.component.ts @@ -1,18 +1,21 @@ -import { Component, Input, OnChanges } from '@angular/core'; +import { Component, Input, OnChanges, Output, EventEmitter } from '@angular/core'; import { Property } from '../../domain/model/property'; import { Observable, of } from 'rxjs'; import { AttributesService } from '../../domain/service/attributes.service'; import { ConfigurationPropertyComponent } from './configuration-property.component'; +import UriValidator from '../../../shared/validation/uri.validator'; @Component({ selector: 'array-property', templateUrl: './array-property.component.html', - styleUrls: [] + styleUrls: ['./array-property.component.scss'] }) export class ArrayPropertyComponent extends ConfigurationPropertyComponent implements OnChanges { @Input() property: Property; + @Output() preview: EventEmitter = new EventEmitter(); + range = []; constructor( @@ -26,6 +29,10 @@ export class ArrayPropertyComponent extends ConfigurationPropertyComponent imple this.range = [...Array(keys).keys()]; } + isUrl(str: string): boolean { + return UriValidator.isUri(str); + } + get attributeList$(): Observable<{ key: string, label: string }[]> { if (this.property.widget && this.property.widget.hasOwnProperty('data')) { return of(this.property.widget.data); 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 001a8235b..04d58ca41 100644 --- a/ui/src/app/metadata/configuration/component/configuration-property.component.ts +++ b/ui/src/app/metadata/configuration/component/configuration-property.component.ts @@ -16,7 +16,8 @@ export class ConfigurationPropertyComponent { return Object.keys(schema.properties); } - getItemType(items: Property): string { + getItemType(property: Property): string { + const items = property.items; return items.widget ? items.widget.id : 'default'; } diff --git a/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html b/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html index b35efc1a9..bb04284ac 100644 --- a/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html +++ b/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html @@ -20,10 +20,6 @@

- -   - Preview XML -
@@ -40,7 +36,9 @@ + [configuration]="configuration" + [entity]="filter" + [definition]="definition">
+ [configuration]="configuration$ | async" + id="configuration"> \ No newline at end of file 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 e962fd310..19051596b 100644 --- a/ui/src/app/metadata/configuration/container/metadata-options.component.ts +++ b/ui/src/app/metadata/configuration/container/metadata-options.component.ts @@ -1,5 +1,5 @@ import { Store } from '@ngrx/store'; -import { Component, ChangeDetectionStrategy, OnDestroy } from '@angular/core'; +import { Component, ChangeDetectionStrategy, OnDestroy, HostListener, ElementRef } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { @@ -24,11 +24,13 @@ import { ChangeFilterOrderUp, RemoveFilterRequest } from '../../filter/action/collection.action'; -import { takeUntil, map } from 'rxjs/operators'; +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'; @Component({ selector: 'metadata-options-page', @@ -51,9 +53,14 @@ export class MetadataOptionsComponent implements OnDestroy { id: string; kind: string; + htmlTags = ['DIV', 'A', 'METADATA-CONFIGURATION', 'METADATA-HEADER']; + currentSection: string; + constructor( private store: Store, - private modalService: NgbModal + private modalService: NgbModal, + private router: Router, + private scroller: ViewportScroller ) { this.configuration$ = this.store.select(getConfigurationSections); this.model$ = this.store.select(getConfigurationModel); @@ -75,6 +82,18 @@ export class MetadataOptionsComponent implements OnDestroy { this.store.dispatch(new LoadFilterRequest(this.id)); } }); + + this.router.events.pipe( + takeUntil(this.ngUnsubscribe), + filter((e: Event): e is Scroll => e instanceof Scroll), + delay(1000) + ).subscribe(e => { + scroller.scrollToAnchor(e.anchor); + }); + } + + onScrollTo(element): void { + this.scroller.scrollToAnchor(element); } updateOrderUp(filter: MetadataFilter): void { diff --git a/ui/src/app/metadata/configuration/model/metadata-configuration.ts b/ui/src/app/metadata/configuration/model/metadata-configuration.ts index a06dda3f5..13886d1a3 100644 --- a/ui/src/app/metadata/configuration/model/metadata-configuration.ts +++ b/ui/src/app/metadata/configuration/model/metadata-configuration.ts @@ -1,4 +1,5 @@ import { Section } from './section'; +import { Metadata } from '../../domain/domain.type'; export interface MetadataConfiguration { sections: Section[]; diff --git a/ui/src/app/metadata/domain/model/property.ts b/ui/src/app/metadata/domain/model/property.ts index dcd5e9f1b..4768de9e4 100644 --- a/ui/src/app/metadata/domain/model/property.ts +++ b/ui/src/app/metadata/domain/model/property.ts @@ -7,6 +7,8 @@ export interface Property { properties: Property[]; widget?: { id: string; + data?: {key: string, label: string}[]; + dataUrl?: string; [propertyName: string]: any; }; } 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 944fff229..60d09539f 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 @@ -47,17 +47,24 @@ export const EntityAttributesFilterConfiguration: Wizard = { }, formatter: (changes: MetadataFilter): any => changes, steps: [ + { + id: 'target', + label: 'label.target', + index: 1, + fields: [ + 'entityAttributesFilterTarget' + ] + }, { id: 'options', label: 'label.options', - index: 1, + index: 2, initialValues: [], fields: [ 'name', '@type', 'resourceId', 'version', - 'entityAttributesFilterTarget', 'filterEnabled', 'relyingPartyOverrides' ] @@ -65,7 +72,7 @@ export const EntityAttributesFilterConfiguration: Wizard = { { id: 'attributes', label: 'label.attributes', - index: 2, + index: 3, fields: [ 'attributeRelease' ] 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 1047bf38e..0452c683f 100644 --- a/ui/src/app/metadata/filter/model/nameid-configuration.filter.ts +++ b/ui/src/app/metadata/filter/model/nameid-configuration.filter.ts @@ -41,6 +41,14 @@ export const NameIDFilterConfiguration: Wizard = { parser: (changes: any): MetadataFilter => changes, formatter: (changes: MetadataFilter): any => changes, steps: [ + { + id: 'target', + label: 'label.target', + index: 1, + fields: [ + 'nameIdFormatFilterTarget' + ] + }, { id: 'options', label: 'label.options', @@ -48,7 +56,6 @@ export const NameIDFilterConfiguration: Wizard = { initialValues: [], fields: [ 'name', - 'nameIdFormatFilterTarget', 'filterEnabled', '@type', 'resourceId', diff --git a/ui/src/theme/modal.scss b/ui/src/theme/modal.scss index d2158f5f1..065d41840 100644 --- a/ui/src/theme/modal.scss +++ b/ui/src/theme/modal.scss @@ -26,3 +26,8 @@ delete-dialog { font-weight: 700; } } + +.popover.popover-lg { + width: auto; + max-width: none; +} \ No newline at end of file From 9393832a66f4925d02bf38c6b3cf88909235aba4 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 25 Jul 2019 09:00:11 -0700 Subject: [PATCH 10/14] SHIBUI-1332 Fixed layout --- .../component/array-property.component.html | 30 +++++++++---------- ...ter-configuration-list-item.component.html | 2 +- .../metadata-configuration.component.html | 28 +++++++++-------- .../primitive-property.component.html | 2 +- .../container/configuration.component.spec.ts | 4 +++ .../metadata-comparison.component.html | 11 +++---- .../metadata-comparison.component.ts | 4 ++- .../container/metadata-options.component.html | 6 ++-- .../reducer/configuration.reducer.spec.ts | 9 +++--- .../metadata/configuration/reducer/index.ts | 2 +- ui/src/theme/modal.scss | 1 + 11 files changed, 53 insertions(+), 46 deletions(-) diff --git a/ui/src/app/metadata/configuration/component/array-property.component.html b/ui/src/app/metadata/configuration/component/array-property.component.html index 692cb3a5f..c2f976657 100644 --- a/ui/src/app/metadata/configuration/component/array-property.component.html +++ b/ui/src/app/metadata/configuration/component/array-property.component.html @@ -1,7 +1,7 @@
-
{{ property.name }}
-
+
{{ property.name }}
+
{{ property.items.properties[prop].title }} @@ -11,12 +11,13 @@ [ngbPopover]="version[i][prop]" triggers="mouseenter:mouseleave" container="body" - placement="left" - [ngStyle]="{'width': width}"> + [ngStyle]="{'width': width}" + class="text-truncate" + popoverClass="popover-lg"> {{ version[i][prop] }}
- — + -
@@ -34,9 +35,9 @@
-
- {{ attr.label }} -
+
+ {{ attr.label }} +
true @@ -51,17 +52,16 @@
- {{ property.name }} + {{ property.name }} -

- {{ v }} +

-

    -
  • + popoverClass="popover-lg" + *ngIf="v && v.length > 0"> +
\ No newline at end of file diff --git a/ui/src/app/metadata/configuration/component/primitive-property.component.html b/ui/src/app/metadata/configuration/component/primitive-property.component.html index 608f4acdd..4d93c07cc 100644 --- a/ui/src/app/metadata/configuration/component/primitive-property.component.html +++ b/ui/src/app/metadata/configuration/component/primitive-property.component.html @@ -1,4 +1,4 @@ -
+
{ NgbDropdownModule, StoreModule.forRoot({ 'metadata-configuration': combineReducers(fromConfiguration.reducers), + 'provider': combineReducers(fromProviders.reducers), + 'resolver': combineReducers(fromResolvers.reducers) }), MockI18nModule, RouterTestingModule diff --git a/ui/src/app/metadata/configuration/container/metadata-comparison.component.html b/ui/src/app/metadata/configuration/container/metadata-comparison.component.html index fabdb5338..d5b533716 100644 --- a/ui/src/app/metadata/configuration/container/metadata-comparison.component.html +++ b/ui/src/app/metadata/configuration/container/metadata-comparison.component.html @@ -1,10 +1,7 @@ -
- +
  diff --git a/ui/src/app/metadata/configuration/container/metadata-comparison.component.ts b/ui/src/app/metadata/configuration/container/metadata-comparison.component.ts index 701c99d2a..92019297d 100644 --- a/ui/src/app/metadata/configuration/container/metadata-comparison.component.ts +++ b/ui/src/app/metadata/configuration/container/metadata-comparison.component.ts @@ -3,7 +3,7 @@ import { Observable } from 'rxjs'; import { Store } from '@ngrx/store'; import { ActivatedRoute } from '@angular/router'; import { map } from 'rxjs/operators'; -import { ConfigurationState, getVersionConfigurations } from '../reducer'; +import { ConfigurationState, getVersionConfigurations, getVersionConfigurationCount } from '../reducer'; import { Metadata } from '../../domain/domain.type'; import { CompareVersionRequest } from '../action/compare.action'; import { MetadataConfiguration } from '../model/metadata-configuration'; @@ -17,6 +17,7 @@ import { MetadataConfiguration } from '../model/metadata-configuration'; export class MetadataComparisonComponent { versions$: Observable; + numVersions$: Observable; constructor( private store: Store, @@ -28,5 +29,6 @@ export class MetadataComparisonComponent { ).subscribe(this.store); this.versions$ = this.store.select(getVersionConfigurations); + this.numVersions$ = this.store.select(getVersionConfigurationCount); } } 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 77e63d79d..972e0e4da 100644 --- a/ui/src/app/metadata/configuration/container/metadata-options.component.html +++ b/ui/src/app/metadata/configuration/container/metadata-options.component.html @@ -7,11 +7,11 @@ > 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; +} From 61ca58fae2d9e87b738ddd9052d5f236a1c521fb Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 25 Jul 2019 14:17:29 -0700 Subject: [PATCH 12/14] SHIBUI-1332 Implemented unit tests --- .../reducer/configuration.reducer.spec.ts | 35 +++++++++ ui/src/app/core/reducer/index.spec.ts | 18 ++++- ui/src/app/core/reducer/index.ts | 2 +- .../component/array-property.component.html | 4 +- ...ter-configuration-list-item.component.html | 3 +- ...ilter-configuration-list-item.component.ts | 15 +++- .../filter-target-property.component.spec.ts | 66 ++++++++++++++++ .../component/history-list.component.html | 6 +- .../metadata-configuration.component.html | 2 +- .../metadata-configuration.component.ts | 9 +-- .../object-property.component.spec.ts | 6 +- .../component/primitive-property.component.ts | 1 - .../metadata-history.component.spec.ts | 8 +- .../container/metadata-history.component.ts | 6 +- .../container/metadata-options.component.html | 2 +- .../metadata-options.component.spec.ts | 76 ++++++++++++++++++- .../container/metadata-options.component.ts | 31 +++----- .../domain/utility/configuration.spec.ts | 2 +- ui/src/testing/form-schema.stub.ts | 48 ++++++++++++ ui/src/testing/property-component.stub.ts | 57 ++++++++++++++ ui/src/theme/modal.scss | 8 ++ 21 files changed, 351 insertions(+), 54 deletions(-) create mode 100644 ui/src/app/core/reducer/configuration.reducer.spec.ts create mode 100644 ui/src/testing/property-component.stub.ts diff --git a/ui/src/app/core/reducer/configuration.reducer.spec.ts b/ui/src/app/core/reducer/configuration.reducer.spec.ts new file mode 100644 index 000000000..e8e8a802e --- /dev/null +++ b/ui/src/app/core/reducer/configuration.reducer.spec.ts @@ -0,0 +1,35 @@ +import { reducer } from './configuration.reducer'; +import * as fromConfiguration from './configuration.reducer'; +import * as actions from '../action/configuration.action'; + +describe('Configuration Reducer', () => { + const initialState: fromConfiguration.ConfigState = { + roles: [] + }; + + describe('undefined action', () => { + it('should return the default state', () => { + const result = reducer(undefined, {} as any); + expect(result).toEqual(initialState); + }); + }); + + describe('Role Load Request', () => { + it('should set fetching to true', () => { + const action = new actions.LoadRoleSuccess(['ADMIN']); + const result = reducer(initialState, action); + expect(result).toEqual( + { + ...initialState, + roles: ['ADMIN'] + } + ); + }); + }); + + describe('selector functions', () => { + it('should return the roles from state', () => { + expect(fromConfiguration.getRoles(initialState)).toEqual([]); + }); + }); +}); diff --git a/ui/src/app/core/reducer/index.spec.ts b/ui/src/app/core/reducer/index.spec.ts index f14a08006..5a1fbef3e 100644 --- a/ui/src/app/core/reducer/index.spec.ts +++ b/ui/src/app/core/reducer/index.spec.ts @@ -10,7 +10,6 @@ describe('Core index reducers', () => { version: fromVersion.initialState as fromVersion.VersionState, config: fromConfig.initialState as fromConfig.ConfigState }; - describe('getUserStateFn function', () => { it('should return the user state', () => { expect(fromIndex.getUserStateFn(state)).toEqual(state.user); @@ -21,4 +20,21 @@ describe('Core index reducers', () => { expect(fromIndex.getVersionStateFn(state)).toEqual(state.version); }); }); + describe('getConfigStateFn function', () => { + it('should return the config state', () => { + expect(fromIndex.getConfigStateFn(state)).toEqual(state.config); + }); + }); + describe('filterRolesFn', () => { + it('should return the roles that are not `non roles`', () => { + expect(fromIndex.filterRolesFn(['ROLE_ADMIN', 'ROLE_NONE'])).toEqual(['ROLE_ADMIN']); + }); + }); + describe('isUserAdminFn', () => { + it('should check if the provided user has the ROLE_ADMIN role', () => { + expect(fromIndex.isUserAdminFn({role: 'ROLE_ADMIN'})).toBe(true); + expect(fromIndex.isUserAdminFn({role: 'ROLE_USER'})).toBe(false); + expect(fromIndex.isUserAdminFn(null)).toBe(false); + }); + }); }); diff --git a/ui/src/app/core/reducer/index.ts b/ui/src/app/core/reducer/index.ts index f2d64e934..f5e5b94c2 100644 --- a/ui/src/app/core/reducer/index.ts +++ b/ui/src/app/core/reducer/index.ts @@ -40,7 +40,7 @@ export const getVersionLoading = createSelector(getVersionState, fromVersion.get export const getVersionError = createSelector(getVersionState, fromVersion.getVersionError); export const filterRolesFn = (roles: string[]) => roles.filter(r => r !== 'ROLE_NONE'); -export const isUserAdminFn = (user) => user ? user.role === 'ROLE_ADMIN' : null; +export const isUserAdminFn = (user) => user ? user.role === 'ROLE_ADMIN' : false; export const getConfigState = createSelector(getCoreFeature, getConfigStateFn); export const getRoles = createSelector(getConfigState, fromConfig.getRoles); diff --git a/ui/src/app/metadata/configuration/component/array-property.component.html b/ui/src/app/metadata/configuration/component/array-property.component.html index c2f976657..d51a8e0fb 100644 --- a/ui/src/app/metadata/configuration/component/array-property.component.html +++ b/ui/src/app/metadata/configuration/component/array-property.component.html @@ -13,7 +13,7 @@ container="body" [ngStyle]="{'width': width}" class="text-truncate" - popoverClass="popover-lg"> + popoverClass="popover-lg popover-info"> {{ version[i][prop] }}
@@ -59,7 +59,7 @@ class="list-unstyled py-2 m-0" [ngbPopover]="popContent" triggers="mouseenter:mouseleave" - popoverClass="popover-lg" + popoverClass="popover-lg popover-info" *ngIf="v && v.length > 0">
  • diff --git a/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html b/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html index a08d9de7a..42ed9652e 100644 --- a/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html +++ b/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html @@ -38,7 +38,8 @@ [editable]="false" [configuration]="configuration" [entity]="filter" - [definition]="definition"> + [definition]="definition" + (preview)="onPreview($event)">
  • - Current (v{{ i + 1 }}) - v{{ i + 1 }} - {{ version.date | date }} + Current (v{{ history.length - i }}) + v{{ history.length - (i) }} + {{ version.date | date:'medium' }} {{ version.creator }}
    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 10ec0eed8..86e8bd23b 100644 --- a/ui/src/app/metadata/configuration/component/metadata-configuration.component.ts +++ b/ui/src/app/metadata/configuration/component/metadata-configuration.component.ts @@ -1,12 +1,7 @@ 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'; -import { Observable, of } from 'rxjs'; import { Metadata } from '../../domain/domain.type'; -import { PreviewEntity } from '../../domain/action/entity.action'; -import { ConfigurationState } from '../reducer'; -import { Store } from '@ngrx/store'; @Component({ selector: 'metadata-configuration', @@ -32,6 +27,10 @@ export class MetadataConfigurationComponent { this.router.navigate(['../', 'edit', id], { relativeTo: this.activatedRoute.parent }); } + onPreview($event): void { + this.preview.emit($event); + } + 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 7ccb135fe..8817711c9 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 @@ -1,13 +1,13 @@ -import { Component, ViewChild, Input } from '@angular/core'; +import { Component, ViewChild } from '@angular/core'; import { TestBed, async, ComponentFixture } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; -import { NgbDropdownModule, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; +import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; import { Property } from '../../domain/model/property'; import { MockI18nModule } from '../../../../testing/i18n.stub'; import { ObjectPropertyComponent } from './object-property.component'; import { SCHEMA } from '../../../../testing/form-schema.stub'; -import { getStepProperties, getStepProperty } from '../../domain/utility/configuration'; +import { getStepProperty } from '../../domain/utility/configuration'; import { PrimitivePropertyComponent } from './primitive-property.component'; import { ArrayPropertyComponent } from './array-property.component'; import { FilterTargetPropertyComponent } from './filter-target-property.component'; diff --git a/ui/src/app/metadata/configuration/component/primitive-property.component.ts b/ui/src/app/metadata/configuration/component/primitive-property.component.ts index 951d2c72a..e18b525af 100644 --- a/ui/src/app/metadata/configuration/component/primitive-property.component.ts +++ b/ui/src/app/metadata/configuration/component/primitive-property.component.ts @@ -6,7 +6,6 @@ import { ConfigurationPropertyComponent } from './configuration-property.compone templateUrl: './primitive-property.component.html', styleUrls: [] }) - export class PrimitivePropertyComponent extends ConfigurationPropertyComponent { constructor() { super(); diff --git a/ui/src/app/metadata/configuration/container/metadata-history.component.spec.ts b/ui/src/app/metadata/configuration/container/metadata-history.component.spec.ts index 43d8cc11b..4a322ee3c 100644 --- a/ui/src/app/metadata/configuration/container/metadata-history.component.spec.ts +++ b/ui/src/app/metadata/configuration/container/metadata-history.component.spec.ts @@ -117,10 +117,10 @@ describe('Metadata Version History Component', () => { ]; const sorted = instance.sortVersionsByDate(versions); - expect(sorted[0].id).toEqual('bar'); - expect(sorted[1].id).toEqual('baz'); - expect(sorted[2].id).toEqual('foo'); - expect(sorted[3].id).toEqual('baz2'); + expect(sorted[0].id).toEqual('baz2'); + expect(sorted[1].id).toEqual('foo'); + expect(sorted[2].id).toEqual('baz'); + expect(sorted[3].id).toEqual('bar'); }); }); }); diff --git a/ui/src/app/metadata/configuration/container/metadata-history.component.ts b/ui/src/app/metadata/configuration/container/metadata-history.component.ts index 6d62e6ed7..c49e0c70f 100644 --- a/ui/src/app/metadata/configuration/container/metadata-history.component.ts +++ b/ui/src/app/metadata/configuration/container/metadata-history.component.ts @@ -5,6 +5,7 @@ import { ConfigurationState, getVersionCollection } from '../reducer'; import { MetadataVersion } from '../model/version'; import { CompareVersionRequest } from '../action/compare.action'; import { Router, ActivatedRoute } from '@angular/router'; +import { map } from 'rxjs/operators'; @Component({ selector: 'metadata-history', @@ -21,7 +22,8 @@ export class MetadataHistoryComponent { private router: Router, private route: ActivatedRoute ) { - this.history$ = this.store.select(getVersionCollection); + this.history$ = this.store.select(getVersionCollection) + .pipe(map(versions => this.sortVersionsByDate(versions))); } sortVersionsByDate(versions: MetadataVersion[]): MetadataVersion[] { @@ -29,7 +31,7 @@ export class MetadataHistoryComponent { const aDate = new Date(a.date).getTime(); const bDate = new Date(b.date).getTime(); return aDate === bDate ? 0 : aDate < bDate ? -1 : 1; - }); + }).reverse(); } compareVersions(versions: MetadataVersion[]): void { 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 f10147755..d99166c11 100644 --- a/ui/src/app/metadata/configuration/container/metadata-options.component.html +++ b/ui/src/app/metadata/configuration/container/metadata-options.component.html @@ -29,7 +29,6 @@
    @@ -49,6 +48,7 @@

    (onUpdateOrderDown)="updateOrderDown($event)" (onUpdateOrderUp)="updateOrderUp($event)" (onRemove)="removeFilter($event)" + (preview)="onPreview($event)" [filters]="filters$ | async">

    \ No newline at end of file diff --git a/ui/src/app/schema-form/widget/button/icon-button.component.ts b/ui/src/app/schema-form/widget/button/icon-button.component.ts index 01efc1f74..f023330b6 100644 --- a/ui/src/app/schema-form/widget/button/icon-button.component.ts +++ b/ui/src/app/schema-form/widget/button/icon-button.component.ts @@ -1,9 +1,7 @@ import { Component, AfterViewInit, ChangeDetectorRef } from '@angular/core'; -import { ButtonWidget } from 'ngx-schema-form'; -import { ActionRegistry } from 'ngx-schema-form'; -import { interval } from 'rxjs'; +import { ButtonWidget, ActionRegistry } from 'ngx-schema-form'; @Component({ selector: 'icon-button', diff --git a/ui/src/app/schema-form/widget/check/checkbox.component.html b/ui/src/app/schema-form/widget/check/checkbox.component.html index 8ad2962ab..9188b4a6d 100644 --- a/ui/src/app/schema-form/widget/check/checkbox.component.html +++ b/ui/src/app/schema-form/widget/check/checkbox.component.html @@ -8,9 +8,9 @@ [indeterminate]="control.value !== false && control.value !== true ? true :null" type="checkbox" [attr.disabled]="schema.readOnly?true:null" - id="{{ name }}" + [id]="formProperty._canonicalPath" [disableValidation]="true"> -
    @@ -21,8 +21,10 @@
    - {{ schema.description }}