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 c17a469af..3feb146b5 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 @@ -66,10 +66,10 @@ describe('Metadata Configuration Component', () => { })); describe('edit method', () => { - it('should call router.navigate', () => { - spyOn(router, 'navigate'); + it('should call onEdit.emit', () => { + spyOn(app.onEdit, 'emit'); app.edit('foo'); - expect(router.navigate).toHaveBeenCalled(); + expect(app.onEdit.emit).toHaveBeenCalled(); }); }); diff --git a/ui/src/app/metadata/configuration/reducer/index.spec.ts b/ui/src/app/metadata/configuration/reducer/index.spec.ts index 8a1aa3cb7..d9dff5a83 100644 --- a/ui/src/app/metadata/configuration/reducer/index.spec.ts +++ b/ui/src/app/metadata/configuration/reducer/index.spec.ts @@ -1,143 +1,31 @@ import { - getConfigurationSectionsFn, getConfigurationModelNameFn, getConfigurationModelEnabledFn, - assignValueToProperties, - getLimitedPropertiesFn, getConfigurationModelTypeFn, getSelectedVersionNumberFn, getSelectedIsCurrentFn } from './index'; -import { SCHEMA as schema } from '../../../../testing/form-schema.stub'; + import { Metadata } from '../../domain/domain.type'; -import { MockMetadataWizard } from '../../../../testing/mockMetadataWizard'; describe('Configuration Reducer', () => { - const model = { - name: 'foo', - serviceEnabled: true, - foo: { - bar: 'bar', - baz: 'baz' - }, - list: [ - 'super', - 'cool' - ] - }; - - const props = [ - { - id: 'name', - items: null, - name: 'label.metadata-provider-name-dashboard-display-only', - properties: [], - type: 'string', - value: null, - widget: { id: 'string', help: 'message.must-be-unique' } - }, - { - id: 'serviceEnabled', - items: null, - name: 'serviceEnabled', - properties: [], - type: 'string', - value: null, - widget: { id: 'select', disabled: true } - }, - { - id: 'foo', - items: null, - name: 'foo', - type: 'object', - properties: [ - { - id: 'bar', - name: 'bar', - type: 'string', - properties: [] - }, - { - id: 'baz', - name: 'baz', - type: 'string', - properties: [] - } - ] - }, - { - id: 'list', - name: 'list', - type: 'array', - items: { - type: 'string' - }, - widget: { - id: 'datalist', - data: [ - { key: 'super', label: 'super' }, - { key: 'cool', label: 'cool' }, - { key: 'notcool', label: 'notcool' } - ] - } - } - ]; - - const definition = MockMetadataWizard; - - describe('getConfigurationSectionsFn', () => { - it('should parse the schema, definition, and model into a MetadataConfiguration', () => { - const config = getConfigurationSectionsFn([model], definition, schema); - 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); + expect(getConfigurationModelNameFn(null)).toBe(''); }); }); describe('getConfigurationModelEnabledFn function', () => { - it('should return the name attribute', () => { + it('should return the enabled attribute', () => { expect(getConfigurationModelEnabledFn({ serviceEnabled: true } as Metadata)).toBe(true); expect(getConfigurationModelEnabledFn({ enabled: true } as Metadata)).toBe(true); expect(getConfigurationModelEnabledFn(null)).toBe(false); }); }); - describe('assignValueToProperties function', () => { - it('should assign appropriate values to the given schema properties', () => { - const assigned = assignValueToProperties([model], props, definition); - expect(assigned[0].value).toEqual(['foo']); - expect(assigned[1].value).toEqual([true]); - }); - - it('should assign differences when passed multiple models', () => { - const assigned = assignValueToProperties([model, { - ...model, - name: 'bar', - list: [ - 'super', - 'notcool' - ] - }], props, definition); - expect(assigned[0].differences).toBe(true); - }); - }); - - describe('getLimitedPropertiesFn function', () => { - it('should filter properties without differences', () => { - const assigned = assignValueToProperties([model, { - ...model, - name: 'bar' - }], props, definition); - expect(getLimitedPropertiesFn(assigned).length).toBe(1); - }); - }); - describe('getConfigurationModelTypeFn function ', () => { it('should return provider type if the object has an @type property', () => { const md = { '@type': 'FilebackedHttpMetadataResolver' } as Metadata; diff --git a/ui/src/app/metadata/configuration/reducer/index.ts b/ui/src/app/metadata/configuration/reducer/index.ts index 1053ada29..58e92562f 100644 --- a/ui/src/app/metadata/configuration/reducer/index.ts +++ b/ui/src/app/metadata/configuration/reducer/index.ts @@ -8,15 +8,13 @@ import * as fromVersion from './version.reducer'; import * as fromRestore from './restore.reducer'; import * as fromFilter from './filter.reducer'; -import * as utils from '../../domain/utility/configuration'; -import { getConfigurationSectionsFn } from './utilities'; +import { getConfigurationSectionsFn, getLimitedPropertiesFn } from './utilities'; import { getModel } from '../../../wizard/reducer'; import { getInCollectionFn } from '../../domain/domain.util'; import { Metadata } from '../../domain/domain.type'; import * as fromResolver from '../../resolver/reducer'; import * as fromProvider from '../../provider/reducer'; -import { SectionProperty } from '../model/section'; export interface ConfigurationState { configuration: fromConfiguration.State; @@ -136,26 +134,6 @@ export const getComparisonConfigurationCount = createSelector(getComparisonConfi export const getViewChangedOnly = createSelector(getCompareState, fromCompare.getViewChangedOnly); -export const getLimitedPropertiesFn = (properties: SectionProperty[]) => { - return ([ - ...properties - .filter(p => p.differences) - .map(p => { - const parsed = { ...p }; - if (p.widget && p.widget.data) { - parsed.widget = { - ...p.widget, - data: p.widget.data.filter(item => item.differences) - }; - } - if (p.properties) { - parsed.properties = getLimitedPropertiesFn(p.properties); - } - return parsed; - }) - ]); -}; - export const getLimitedConfigurationsFn = (configurations, limited) => configurations ? ({ ...configurations, sections: limited ? configurations.sections : diff --git a/ui/src/app/metadata/configuration/reducer/utilities.spec.ts b/ui/src/app/metadata/configuration/reducer/utilities.spec.ts new file mode 100644 index 000000000..0d8234bb5 --- /dev/null +++ b/ui/src/app/metadata/configuration/reducer/utilities.spec.ts @@ -0,0 +1,120 @@ +import { + getConfigurationSectionsFn, + getLimitedPropertiesFn, + assignValueToProperties +} from './utilities'; + +import { SCHEMA as schema } from '../../../../testing/form-schema.stub'; +import { MockMetadataWizard } from '../../../../testing/mockMetadataWizard'; + +describe('config reducer utilities', () => { + + const model = { + name: 'foo', + serviceEnabled: true, + foo: { + bar: 'bar', + baz: 'baz' + }, + list: [ + 'super', + 'cool' + ] + }; + + const props = [ + { + id: 'name', + items: null, + name: 'label.metadata-provider-name-dashboard-display-only', + properties: [], + type: 'string', + value: null, + widget: { id: 'string', help: 'message.must-be-unique' } + }, + { + id: 'serviceEnabled', + items: null, + name: 'serviceEnabled', + properties: [], + type: 'string', + value: null, + widget: { id: 'select', disabled: true } + }, + { + id: 'foo', + items: null, + name: 'foo', + type: 'object', + properties: [ + { + id: 'bar', + name: 'bar', + type: 'string', + properties: [] + }, + { + id: 'baz', + name: 'baz', + type: 'string', + properties: [] + } + ] + }, + { + id: 'list', + name: 'list', + type: 'array', + items: { + type: 'string' + }, + widget: { + id: 'datalist', + data: [ + { key: 'super', label: 'super' }, + { key: 'cool', label: 'cool' }, + { key: 'notcool', label: 'notcool' } + ] + } + } + ]; + + const definition = MockMetadataWizard; + + describe('assignValueToProperties function', () => { + it('should assign appropriate values to the given schema properties', () => { + const assigned = assignValueToProperties([model], props, definition); + expect(assigned[0].value).toEqual(['foo']); + expect(assigned[1].value).toEqual([true]); + }); + + it('should assign differences when passed multiple models', () => { + const assigned = assignValueToProperties([model, { + ...model, + name: 'bar', + list: [ + 'super', + 'notcool' + ] + }], props, definition); + expect(assigned[0].differences).toBe(true); + }); + }); + + describe('getLimitedPropertiesFn function', () => { + it('should filter properties without differences', () => { + const assigned = assignValueToProperties([model, { + ...model, + name: 'bar' + }], props, definition); + expect(getLimitedPropertiesFn(assigned).length).toBe(1); + }); + }); + + describe('getConfigurationSectionsFn', () => { + it('should parse the schema, definition, and model into a MetadataConfiguration', () => { + const config = getConfigurationSectionsFn([model], definition, schema); + expect(config.sections).toBeDefined(); + }); + }); +}); diff --git a/ui/src/app/metadata/configuration/reducer/utilities.ts b/ui/src/app/metadata/configuration/reducer/utilities.ts index 16668a027..f2481e99c 100644 --- a/ui/src/app/metadata/configuration/reducer/utilities.ts +++ b/ui/src/app/metadata/configuration/reducer/utilities.ts @@ -2,6 +2,7 @@ import { MetadataConfiguration } from '../model/metadata-configuration'; import { WizardStep } from '../../../wizard/model'; import * as utils from '../../domain/utility/configuration'; import { getSplitSchema } from '../../../wizard/reducer'; +import { SectionProperty } from '../model/section'; export const getConfigurationSectionsFn = (models, definition, schema): MetadataConfiguration => { return !definition || !schema || !models ? null : @@ -82,3 +83,23 @@ export const assignValueToProperties = (models, properties, definition: any): an } }); }; + +export const getLimitedPropertiesFn = (properties: SectionProperty[]) => { + return ([ + ...properties + .filter(p => p.differences) + .map(p => { + const parsed = { ...p }; + if (p.widget && p.widget.data) { + parsed.widget = { + ...p.widget, + data: p.widget.data.filter(item => item.differences) + }; + } + if (p.properties) { + parsed.properties = getLimitedPropertiesFn(p.properties); + } + return parsed; + }) + ]); +}; \ No newline at end of file diff --git a/ui/src/app/metadata/configuration/service/configuration.service.spec.ts b/ui/src/app/metadata/configuration/service/configuration.service.spec.ts index 43fd99c05..e191471a0 100644 --- a/ui/src/app/metadata/configuration/service/configuration.service.spec.ts +++ b/ui/src/app/metadata/configuration/service/configuration.service.spec.ts @@ -9,7 +9,7 @@ import { of } from 'rxjs'; import { MetadataProviderService } from '../../domain/service/provider.service'; import { Metadata } from '../../domain/domain.type'; import { SCHEMA } from '../../../../testing/form-schema.stub'; -import { getConfigurationSectionsFn } from '../reducer'; +import { getConfigurationSectionsFn } from '../reducer/utilities'; describe(`Configuration Service`, () => { diff --git a/ui/src/app/metadata/domain/component/wizard-summary.component.html b/ui/src/app/metadata/domain/component/wizard-summary.component.html new file mode 100644 index 000000000..349f7cb74 --- /dev/null +++ b/ui/src/app/metadata/domain/component/wizard-summary.component.html @@ -0,0 +1,14 @@ +
+
+
+ + + + +
+
+
\ No newline at end of file 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 new file mode 100644 index 000000000..43712bd48 --- /dev/null +++ b/ui/src/app/metadata/domain/component/wizard-summary.component.spec.ts @@ -0,0 +1,103 @@ +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('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 new file mode 100644 index 000000000..73a701491 --- /dev/null +++ b/ui/src/app/metadata/domain/component/wizard-summary.component.ts @@ -0,0 +1,80 @@ +import { Component, Input, SimpleChanges, OnChanges, Output, EventEmitter } from '@angular/core'; + +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 b109734a6..49e1fe685 100644 --- a/ui/src/app/metadata/domain/domain.module.ts +++ b/ui/src/app/metadata/domain/domain.module.ts @@ -22,8 +22,10 @@ import { UnsavedEntityComponent } from './component/unsaved-entity.dialog'; import { EditorNavComponent } from './component/editor-nav.component'; import { RouterModule } from '@angular/router'; import { SharedModule } from '../../shared/shared.module'; +import { WizardSummaryComponent } from './component/wizard-summary.component'; export const COMPONENTS = [ + WizardSummaryComponent, PreviewDialogComponent, UnsavedEntityComponent, SummaryPropertyComponent, diff --git a/ui/src/app/metadata/provider/model/dynamic-http.provider.form.spec.ts b/ui/src/app/metadata/provider/model/dynamic-http.provider.form.spec.ts index bafe25f4b..f561b4e99 100644 --- a/ui/src/app/metadata/provider/model/dynamic-http.provider.form.spec.ts +++ b/ui/src/app/metadata/provider/model/dynamic-http.provider.form.spec.ts @@ -1,5 +1,51 @@ import { DynamicHttpMetadataProviderWizard } from './dynamic-http.provider.form'; +const schema = { + 'type': 'object', + 'required': [ + '@type', + 'content' + ], + 'properties': { + '@type': { + 'title': 'label.md-request-type', + 'description': 'tooltip.md-request-type', + 'type': 'string', + 'widget': { + 'id': 'select' + }, + 'oneOf': [ + { + 'enum': [ + 'MetadataQueryProtocol' + ], + 'description': 'value.md-query-protocol' + }, + { + 'enum': [ + 'Regex' + ], + 'description': 'value.regex' + } + ] + }, + 'content': { + 'title': 'label.md-request-value', + 'description': 'tooltip.md-request-value', + 'type': 'string' + }, + 'match': { + 'title': 'label.match', + 'description': 'tooltip.match', + 'type': 'string', + 'visibleIf': { + '@type': [ + 'Regex' + ] + } + } + } +}; describe('DynamicHttpMetadataProviderWizard', () => { @@ -122,4 +168,43 @@ describe('DynamicHttpMetadataProviderWizard', () => { ]); }); }); + + describe('validators', () => { + let validators, + metadataRequestURLConstructionScheme, + metadataRequestURLConstructionSchemeContent, + metadataRequestURLConstructionSchemeType, + metadataRequestURLConstructionSchemeMatch; + + beforeEach(() => { + validators = getValidators([], []); + }); + + describe('metadataRequestURLConstructionScheme', () => { + it('should check other validators and propagate those errors up', () => { + const value = { + content: null, + '@type': null, + match: 'foo' + }; + const property = { value, schema, properties: null }; + property.properties = { + content: { + path: 'content', + parent: property + }, + '@type': { + path: '@type', + parent: property + }, + match: { + path: 'match', + parent: property + } + }; + const validator = validators['/metadataRequestURLConstructionScheme']; + expect(validator(value, property, null).length).toBe(2); + }); + }); + }); }); diff --git a/ui/src/app/metadata/provider/model/utilities.spec.ts b/ui/src/app/metadata/provider/model/utilities.spec.ts new file mode 100644 index 000000000..5affea1ae --- /dev/null +++ b/ui/src/app/metadata/provider/model/utilities.spec.ts @@ -0,0 +1,33 @@ +import { metadataFilterProcessor } from './utilities'; + +describe('provider model utilities', () => { + describe('metadata filter processor function', () => { + it('should return null if no schema provided', () => { + expect(metadataFilterProcessor(null)).toBe(null); + }); + + it('should return the schema if no properties are detected', () => { + const schema = {}; + expect(metadataFilterProcessor(schema)).toBe(schema); + }); + + it('should return the schema if no metadataFilters property exists in the schema', () => { + const schema = { properties: { foo: 'bar' } }; + expect(metadataFilterProcessor(schema)).toBe(schema); + }); + + it('should turn the filters into an object if provided ', () => { + const schema = { properties: { metadataFilters: { + type: 'array', + items: [ + { + $id: 'foo', + type: 'string' + } + ] + } } }; + const processed = metadataFilterProcessor(schema); + expect(processed.properties.metadataFilters.properties.foo.type).toBe('string'); + }); + }); +}); diff --git a/ui/src/app/metadata/provider/model/utilities.ts b/ui/src/app/metadata/provider/model/utilities.ts index aea90bc21..dc415bae1 100644 --- a/ui/src/app/metadata/provider/model/utilities.ts +++ b/ui/src/app/metadata/provider/model/utilities.ts @@ -1,5 +1,4 @@ export const metadataFilterProcessor = (schema) => { - console.log(schema); if (!schema) { return null; } @@ -20,6 +19,5 @@ export const metadataFilterProcessor = (schema) => { } } }); - console.log(processed); return processed; }; diff --git a/ui/src/app/metadata/resolver/container/resolver-wizard.component.spec.ts b/ui/src/app/metadata/resolver/container/resolver-wizard.component.spec.ts index 3cec9bf25..58191efeb 100644 --- a/ui/src/app/metadata/resolver/container/resolver-wizard.component.spec.ts +++ b/ui/src/app/metadata/resolver/container/resolver-wizard.component.spec.ts @@ -2,7 +2,7 @@ import { Component, ViewChild } from '@angular/core'; import { TestBed, async, ComponentFixture } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { StoreModule, Store, combineReducers } from '@ngrx/store'; -import { RouterStateSnapshot, ActivatedRouteSnapshot } from '@angular/router'; +import { RouterStateSnapshot } from '@angular/router'; import { NgbDropdownModule, NgbPopoverModule, NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { of } from 'rxjs'; @@ -18,6 +18,7 @@ import { MockWizardModule } from '../../../../testing/wizard.stub'; import { NgbModalStub } from '../../../../testing/modal.stub'; import { MetadataResolver } from '../../domain/model'; import { DifferentialService } from '../../../core/service/differential.service'; +import { MetadataConfigurationComponentStub } from '../../../../testing/metadata-configuration.stub'; @Component({ template: ` @@ -85,7 +86,8 @@ describe('Resolver Wizard Component', () => { ], declarations: [ ResolverWizardComponent, - TestHostComponent + TestHostComponent, + MetadataConfigurationComponentStub ], providers: [ DifferentialService, diff --git a/ui/src/app/wizard/reducer/index.ts b/ui/src/app/wizard/reducer/index.ts index 027ac1673..255710be0 100644 --- a/ui/src/app/wizard/reducer/index.ts +++ b/ui/src/app/wizard/reducer/index.ts @@ -129,7 +129,7 @@ export const getSchemaLockedFn = (step, locked) => step ? step.locked ? locked : export const getLocked = createSelector(getCurrent, getLockedStatus, getSchemaLockedFn); export const getSchemaProcessedFn = (schema, definition) => - definition.schemaPreprocessor ? definition.schemaPreprocessor(schema) : schema; + definition && definition.schemaPreprocessor ? definition.schemaPreprocessor(schema) : schema; export const getSchemaObject = createSelector(getState, fromWizard.getSchema); export const getProcessedSchema = createSelector(getSchemaObject, getWizardDefinition, getSchemaProcessedFn);