From 1166ba4edf048ef68cd298531e942e6407697d2e Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 26 Sep 2019 13:02:36 -0700 Subject: [PATCH] SHIBUI-1437 Integrated config component to replace summary --- .../configuration/configuration.module.ts | 7 +- .../metadata/configuration/reducer/index.ts | 83 +------------- .../configuration/reducer/utilities.ts | 84 ++++++++++++++ .../service/configuration.service.ts | 2 +- .../component/wizard-summary.component.html | 13 --- .../wizard-summary.component.spec.ts | 103 ------------------ .../component/wizard-summary.component.ts | 81 -------------- ui/src/app/metadata/domain/domain.module.ts | 2 - .../container/provider-wizard.component.html | 6 +- .../container/resolver-wizard.component.html | 10 +- .../container/resolver-wizard.component.ts | 18 +-- ui/src/app/metadata/resolver/reducer/index.ts | 9 ++ .../app/metadata/resolver/resolver.module.ts | 4 +- 13 files changed, 112 insertions(+), 310 deletions(-) create mode 100644 ui/src/app/metadata/configuration/reducer/utilities.ts delete mode 100644 ui/src/app/metadata/domain/component/wizard-summary.component.html delete mode 100644 ui/src/app/metadata/domain/component/wizard-summary.component.spec.ts delete mode 100644 ui/src/app/metadata/domain/component/wizard-summary.component.ts diff --git a/ui/src/app/metadata/configuration/configuration.module.ts b/ui/src/app/metadata/configuration/configuration.module.ts index 338c39ccb..6430886b8 100644 --- a/ui/src/app/metadata/configuration/configuration.module.ts +++ b/ui/src/app/metadata/configuration/configuration.module.ts @@ -84,7 +84,9 @@ import { FilterCompareVersionEffects } from './effect/filter.effect'; WizardModule, FormModule ], - exports: [], + exports: [ + MetadataConfigurationComponent + ], providers: [ DatePipe, IndexResolver @@ -114,7 +116,8 @@ export class MetadataConfigurationModule { RestoreEffects, FilterCompareVersionEffects, VersionEffects - ]) + ] + ) ], providers: [] }) diff --git a/ui/src/app/metadata/configuration/reducer/index.ts b/ui/src/app/metadata/configuration/reducer/index.ts index 13daf9b34..3b08a9367 100644 --- a/ui/src/app/metadata/configuration/reducer/index.ts +++ b/ui/src/app/metadata/configuration/reducer/index.ts @@ -10,6 +10,7 @@ import * as fromFilter from './filter.reducer'; import { WizardStep } from '../../../wizard/model'; import * as utils from '../../domain/utility/configuration'; +import { getConfigurationSectionsFn, assignValueToProperties } from './utilities'; import { getSplitSchema, getModel } from '../../../wizard/reducer'; import { getInCollectionFn } from '../../domain/domain.util'; import { MetadataConfiguration } from '../model/metadata-configuration'; @@ -58,88 +59,6 @@ export const getConfigurationDefinition = createSelector(getConfigurationState, export const getConfigurationSchema = createSelector(getConfigurationState, fromConfiguration.getSchema); export const getConfigurationXml = createSelector(getConfigurationState, fromConfiguration.getXml); -export const assignValueToProperties = (models, properties, definition: any): any[] => { - return properties.map(prop => { - const differences = models.some((model, index, array) => { - if (!array) { - return false; - } - return JSON.stringify(model[prop.id]) !== JSON.stringify(array[0][prop.id]); - }); - - const widget = prop.type === 'array' && prop.widget && prop.widget.data ? ({ - ...prop.widget, - data: prop.widget.data.map(item => ({ - ...item, - differences: models - .map((model) => { - const value = model[prop.id]; - return value ? value.indexOf(item.key) > -1 : false; - }) - .reduce((current, val) => current !== val ? true : false, false) - })) - }) : null; - - switch (prop.type) { - case 'object': - return { - ...prop, - differences, - properties: assignValueToProperties( - models.map(model => definition.formatter(model)[prop.id] || {}), - prop.properties, - definition - ) - }; - default: - return { - ...prop, - differences, - value: models.map(model => { - return model[prop.id]; - }), - widget - }; - } - }); -}; - -export const getConfigurationSectionsFn = (models, definition, schema): MetadataConfiguration => { - return !definition || !schema || !models ? null : - ({ - dates: models.map(m => m ? m.modifiedDate : 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({}), - schema.definitions || {} - ) - }); - } - ) - .map((section: any) => { - return { - ...section, - properties: assignValueToProperties(models, section.properties, definition) - }; - }) - .map((section: any) => ({ - ...section, - differences: section.properties.some(prop => prop.differences) - })) - }); - }; - - - export const getConfigurationModelEnabledFn = (config: Metadata) => config ? ('serviceEnabled' in config) ? config.serviceEnabled : config.enabled : false; diff --git a/ui/src/app/metadata/configuration/reducer/utilities.ts b/ui/src/app/metadata/configuration/reducer/utilities.ts new file mode 100644 index 000000000..16668a027 --- /dev/null +++ b/ui/src/app/metadata/configuration/reducer/utilities.ts @@ -0,0 +1,84 @@ +import { MetadataConfiguration } from '../model/metadata-configuration'; +import { WizardStep } from '../../../wizard/model'; +import * as utils from '../../domain/utility/configuration'; +import { getSplitSchema } from '../../../wizard/reducer'; + +export const getConfigurationSectionsFn = (models, definition, schema): MetadataConfiguration => { + return !definition || !schema || !models ? null : + ({ + dates: models.map(m => m ? m.modifiedDate : 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({}), + schema.definitions || {} + ) + }); + } + ) + .map((section: any) => { + return { + ...section, + properties: assignValueToProperties(models, section.properties, definition) + }; + }) + .map((section: any) => ({ + ...section, + differences: section.properties.some(prop => prop.differences) + })) + }); +}; + +export const assignValueToProperties = (models, properties, definition: any): any[] => { + return properties.map(prop => { + const differences = models.some((model, index, array) => { + if (!array) { + return false; + } + return JSON.stringify(model[prop.id]) !== JSON.stringify(array[0][prop.id]); + }); + + const widget = prop.type === 'array' && prop.widget && prop.widget.data ? ({ + ...prop.widget, + data: prop.widget.data.map(item => ({ + ...item, + differences: models + .map((model) => { + const value = model[prop.id]; + return value ? value.indexOf(item.key) > -1 : false; + }) + .reduce((current, val) => current !== val ? true : false, false) + })) + }) : null; + + switch (prop.type) { + case 'object': + return { + ...prop, + differences, + properties: assignValueToProperties( + models.map(model => definition.formatter(model)[prop.id] || {}), + prop.properties, + definition + ) + }; + default: + return { + ...prop, + differences, + value: models.map(model => { + return model[prop.id]; + }), + widget + }; + } + }); +}; diff --git a/ui/src/app/metadata/configuration/service/configuration.service.ts b/ui/src/app/metadata/configuration/service/configuration.service.ts index ef03fc2e5..df8a3dba0 100644 --- a/ui/src/app/metadata/configuration/service/configuration.service.ts +++ b/ui/src/app/metadata/configuration/service/configuration.service.ts @@ -10,7 +10,7 @@ import { TYPES } from '../configuration.values'; import { ResolverService } from '../../domain/service/resolver.service'; import { MetadataProviderService } from '../../domain/service/provider.service'; import { MetadataFilterEditorTypes } from '../../filter/model'; -import { getConfigurationSectionsFn } from '../reducer'; +import { getConfigurationSectionsFn } from '../reducer/utilities'; @Injectable() export class MetadataConfigurationService { diff --git a/ui/src/app/metadata/domain/component/wizard-summary.component.html b/ui/src/app/metadata/domain/component/wizard-summary.component.html deleted file mode 100644 index e7ea5dbf6..000000000 --- a/ui/src/app/metadata/domain/component/wizard-summary.component.html +++ /dev/null @@ -1,13 +0,0 @@ -
-
-
- - - - -
-
-
diff --git a/ui/src/app/metadata/domain/component/wizard-summary.component.spec.ts b/ui/src/app/metadata/domain/component/wizard-summary.component.spec.ts deleted file mode 100644 index ecd51b1b9..000000000 --- a/ui/src/app/metadata/domain/component/wizard-summary.component.spec.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { Component, ViewChild } from '@angular/core'; -import { TestBed, async, ComponentFixture } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { NgbDropdownModule, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; - -import { WizardSummaryComponent } from './wizard-summary.component'; -import { SchemaFormModule, WidgetRegistry, DefaultWidgetRegistry } from 'ngx-schema-form'; -import { Wizard } from '../../../wizard/model'; -import { MetadataProvider } from '../../domain/model'; -import { SummaryPropertyComponent } from './summary-property.component'; -import { SCHEMA } from '../../../../testing/form-schema.stub'; -import { MockI18nModule } from '../../../../testing/i18n.stub'; -import { MetadataProviderWizard } from '../../provider/model'; -import { AttributesService } from '../service/attributes.service'; -import { MockAttributeService } from '../../../../testing/attributes.stub'; - -@Component({ - template: ` - - ` -}) -class TestHostComponent { - @ViewChild(WizardSummaryComponent) - public componentUnderTest: WizardSummaryComponent; - - private _summary; - - get summary(): { definition: Wizard, schema: { [id: string]: any }, model: any } { - return this._summary; - } - - set summary(summary: { definition: Wizard, schema: { [id: string]: any }, model: any }) { - this._summary = summary; - } -} - -describe('Provider Wizard Summary Component', () => { - - let fixture: ComponentFixture; - let instance: TestHostComponent; - let app: WizardSummaryComponent; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - NgbDropdownModule, - NgbPopoverModule, - RouterTestingModule, - SchemaFormModule.forRoot(), - MockI18nModule - ], - declarations: [ - WizardSummaryComponent, - SummaryPropertyComponent, - TestHostComponent - ], - providers: [ - { provide: WidgetRegistry, useClass: DefaultWidgetRegistry }, - { provide: AttributesService, useClass: MockAttributeService } - ] - }).compileComponents(); - - fixture = TestBed.createComponent(TestHostComponent); - instance = fixture.componentInstance; - app = instance.componentUnderTest; - fixture.detectChanges(); - })); - - it('should instantiate the component', async(() => { - expect(app).toBeTruthy(); - })); - - describe('gotoPage function', () => { - it('should emit an empty string if page is null', () => { - spyOn(app.onPageSelect, 'emit'); - app.gotoPage(); - expect(app.onPageSelect.emit).toHaveBeenCalledWith(''); - }); - - it('should emit the provided page', () => { - spyOn(app.onPageSelect, 'emit'); - app.gotoPage('foo'); - expect(app.onPageSelect.emit).toHaveBeenCalledWith('foo'); - }); - }); - - describe('ngOnChanges', () => { - it('should set columns and sections if summary is provided', () => { - instance.summary = { - model: { - name: 'foo', - '@type': 'MetadataProvider' - }, - schema: SCHEMA, - definition: MetadataProviderWizard - }; - fixture.detectChanges(); - expect(app.sections).toBeDefined(); - expect(app.columns).toBeDefined(); - }); - }); -}); diff --git a/ui/src/app/metadata/domain/component/wizard-summary.component.ts b/ui/src/app/metadata/domain/component/wizard-summary.component.ts deleted file mode 100644 index 80f246c83..000000000 --- a/ui/src/app/metadata/domain/component/wizard-summary.component.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Component, Input, SimpleChanges, OnChanges, Output, EventEmitter } from '@angular/core'; -import merge from 'deepmerge'; - -import { Wizard, WizardStep } from '../../../wizard/model'; -import { MetadataProvider, MetadataResolver } from '../../domain/model'; -import { Property } from '../model/property'; -import { getSplitSchema } from '../../../wizard/reducer'; -import { getStepProperties } from '../utility/configuration'; - -interface Section { - id: string; - index: number; - label: string; - pageNumber: number; - properties: Property[]; -} - -@Component({ - selector: 'wizard-summary', - templateUrl: './wizard-summary.component.html', - styleUrls: [] -}) - -export class WizardSummaryComponent implements OnChanges { - @Input() summary: { definition: Wizard, schema: { [id: string]: any }, model: any }; - - @Output() onPageSelect: EventEmitter = new EventEmitter(); - - sections: Section[]; - columns: Array
[]; - steps: WizardStep[]; - - constructor() {} - - ngOnChanges(changes: SimpleChanges): void { - if (changes.summary && this.summary) { - const schema = this.summary.schema; - const model = this.summary.model; - const def = this.summary.definition; - const steps = def.steps; - - this.sections = steps - .filter(step => step.id !== 'summary') - .map( - (step: WizardStep, num: number) => { - const { id, index, label } = step; - const split = getSplitSchema(schema, step); - const properties = getStepProperties( - split, - def.formatter(model), - schema.definitions || {} - ); - return ({ - id, - pageNumber: num + 1, - index, - label, - properties - }); - } - ); - - this.columns = this.sections.reduce((resultArray, item, index) => { - const chunkIndex = Math.floor(index / Math.round(this.sections.length / 2)); - - if (!resultArray[chunkIndex]) { - resultArray[chunkIndex] = []; - } - - resultArray[chunkIndex].push(item); - - return resultArray; - }, []); - } - } - - gotoPage(page: string = ''): void { - this.onPageSelect.emit(page); - } -} - diff --git a/ui/src/app/metadata/domain/domain.module.ts b/ui/src/app/metadata/domain/domain.module.ts index ffee8cf1d..b109734a6 100644 --- a/ui/src/app/metadata/domain/domain.module.ts +++ b/ui/src/app/metadata/domain/domain.module.ts @@ -16,7 +16,6 @@ import { PreviewDialogComponent } from './component/preview-dialog.component'; import { MetadataFilterService } from './service/filter.service'; import { AttributesService } from './service/attributes.service'; import { I18nModule } from '../../i18n/i18n.module'; -import { WizardSummaryComponent } from './component/wizard-summary.component'; import { SummaryPropertyComponent } from './component/summary-property.component'; import { UnsavedEntityComponent } from './component/unsaved-entity.dialog'; @@ -26,7 +25,6 @@ import { SharedModule } from '../../shared/shared.module'; export const COMPONENTS = [ PreviewDialogComponent, - WizardSummaryComponent, UnsavedEntityComponent, SummaryPropertyComponent, EditorNavComponent diff --git a/ui/src/app/metadata/provider/container/provider-wizard.component.html b/ui/src/app/metadata/provider/container/provider-wizard.component.html index 366bb70d5..58766e536 100644 --- a/ui/src/app/metadata/provider/container/provider-wizard.component.html +++ b/ui/src/app/metadata/provider/container/provider-wizard.component.html @@ -19,11 +19,7 @@ - - +
diff --git a/ui/src/app/metadata/resolver/container/resolver-wizard.component.html b/ui/src/app/metadata/resolver/container/resolver-wizard.component.html index 87100a871..867ac0584 100644 --- a/ui/src/app/metadata/resolver/container/resolver-wizard.component.html +++ b/ui/src/app/metadata/resolver/container/resolver-wizard.component.html @@ -5,8 +5,8 @@ - - + + + diff --git a/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts b/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts index 56848ad5e..7a3bfc781 100644 --- a/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts +++ b/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts @@ -29,6 +29,8 @@ import { LoadSchemaRequest } from '../../../wizard/action/wizard.action'; import { UnsavedEntityComponent } from '../../domain/component/unsaved-entity.dialog'; import { Clear } from '../action/entity.action'; import { DifferentialService } from '../../../core/service/differential.service'; +import { getConfigurationSections } from '../../configuration/reducer'; +import { MetadataConfiguration } from '../../configuration/model/metadata-configuration'; @Component({ selector: 'resolver-wizard-page', @@ -60,7 +62,7 @@ export class ResolverWizardComponent implements OnDestroy, CanComponentDeactivat valid$: Observable; schema$: Observable; - summary$: Observable<{ definition: Wizard, schema: { [id: string]: any }, model: any }>; + summary$: Observable = this.store.select(fromCollections.getResolverConfiguration); constructor( private store: Store, @@ -115,20 +117,6 @@ export class ResolverWizardComponent implements OnDestroy, CanComponentDeactivat combineLatest(this.resolver$, (changes, base) => ({ ...base, ...changes })) ).subscribe(latest => this.latest = latest); - this.summary$ = combine( - this.store.select(fromWizard.getWizardDefinition), - this.store.select(fromWizard.getSchemaObject), - this.store.select(fromResolver.getDraftModelWithChanges) - ).pipe( - map(([definition, schema, model]) => ( - { - definition, - schema: schema || {}, - model - } - )) - ); - this.changes$.pipe(takeUntil(this.ngUnsubscribe)).subscribe(c => this.changes = c); this.resolver$.pipe(takeUntil(this.ngUnsubscribe)).subscribe(r => this.resolver = r); } diff --git a/ui/src/app/metadata/resolver/reducer/index.ts b/ui/src/app/metadata/resolver/reducer/index.ts index a1cc5256d..e25643a25 100644 --- a/ui/src/app/metadata/resolver/reducer/index.ts +++ b/ui/src/app/metadata/resolver/reducer/index.ts @@ -8,6 +8,7 @@ import * as fromCollection from './collection.reducer'; import * as fromWizard from '../../../wizard/reducer'; import { combineAllFn, getEntityIdsFn, getInCollectionFn, doesExistFn } from '../../domain/domain.util'; +import { getConfigurationSectionsFn } from '../../configuration/reducer/utilities'; export interface ResolverState { entity: fromEntity.EntityState; @@ -124,3 +125,11 @@ export const getDraftModelWithChanges = createSelector( }) ); +export const getDraftModelList = createSelector(getDraftModelWithChanges, (model) => [model]); + +export const getResolverConfiguration = createSelector( + getDraftModelList, + fromWizard.getWizardDefinition, + fromWizard.getSchema, + getConfigurationSectionsFn +); diff --git a/ui/src/app/metadata/resolver/resolver.module.ts b/ui/src/app/metadata/resolver/resolver.module.ts index e0cb4bb5b..e303181fc 100644 --- a/ui/src/app/metadata/resolver/resolver.module.ts +++ b/ui/src/app/metadata/resolver/resolver.module.ts @@ -36,6 +36,7 @@ import { MetadataSourceEditor } from '../domain/model/wizards/metadata-source-ed import { FinishFormComponent } from './component/finish-form.component'; import { ProviderFormFragmentComponent } from './component/provider-form-fragment.component'; import { MetadataResolverPageComponent } from './resolver.component'; +import { MetadataConfigurationModule } from '../configuration/configuration.module'; @NgModule({ declarations: [ @@ -67,7 +68,8 @@ import { MetadataResolverPageComponent } from './resolver.component'; WizardModule, FormModule, NgbPopoverModule, - NgbModalModule + NgbModalModule, + MetadataConfigurationModule ], exports: [], providers: []