From 1fc94d13c1b9a1768532cbfe5e9d20ffde21e768 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 12 Jul 2019 15:16:11 -0700 Subject: [PATCH] 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: {