From 59d818e5a4983caf3d05da436aa045206d27ad23 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 11 Jul 2019 07:28:45 -0700 Subject: [PATCH 1/6] 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 2/6] 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 3/6] 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 4/6] 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 5/6] 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 6/6] 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