diff --git a/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html b/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html index cf1cfe3be..6a447d6f3 100644 --- a/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html +++ b/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html @@ -35,7 +35,6 @@ {{ section.label | translate }} -
+
- + [configuration]="versions$ | async">

Metadata Filter @@ -41,8 +39,7 @@


+ [configuration]="filterCompare$ | async">

- + +
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 8b3d3281f..484d03bc5 100644 --- a/ui/src/app/metadata/configuration/container/metadata-options.component.ts +++ b/ui/src/app/metadata/configuration/container/metadata-options.component.ts @@ -2,7 +2,7 @@ import { Store } from '@ngrx/store'; import { Component, ChangeDetectionStrategy, OnDestroy } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { Router } from '@angular/router'; +import { Router, ActivatedRoute } from '@angular/router'; import { ViewportScroller } from '@angular/common'; import { takeUntil, filter } from 'rxjs/operators'; @@ -53,7 +53,9 @@ export class MetadataOptionsComponent implements OnDestroy { constructor( protected store: Store, protected modalService: NgbModal, - protected scroller: ViewportScroller + protected scroller: ViewportScroller, + protected router: Router, + protected activatedRoute: ActivatedRoute ) { this.model$ .pipe( @@ -63,6 +65,10 @@ export class MetadataOptionsComponent implements OnDestroy { .subscribe(p => this.setModel(p)); } + edit(id: string) { + this.router.navigate(['../', 'edit', id], { relativeTo: this.activatedRoute.parent }); + } + setModel(data: Metadata): void { this.id = 'resourceId' in data ? data.resourceId : data.id; this.kind = '@type' in data ? 'provider' : 'resolver'; diff --git a/ui/src/app/metadata/configuration/container/version-options.component.html b/ui/src/app/metadata/configuration/container/version-options.component.html index c4590848f..f18e661bf 100644 --- a/ui/src/app/metadata/configuration/container/version-options.component.html +++ b/ui/src/app/metadata/configuration/container/version-options.component.html @@ -23,7 +23,6 @@

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 26391abd0..58e92562f 100644 --- a/ui/src/app/metadata/configuration/reducer/index.ts +++ b/ui/src/app/metadata/configuration/reducer/index.ts @@ -7,17 +7,14 @@ import * as fromCompare from './compare.reducer'; import * as fromVersion from './version.reducer'; import * as fromRestore from './restore.reducer'; import * as fromFilter from './filter.reducer'; -import { WizardStep } from '../../../wizard/model'; -import * as utils from '../../domain/utility/configuration'; -import { getSplitSchema, getModel } from '../../../wizard/reducer'; +import { getConfigurationSectionsFn, getLimitedPropertiesFn } from './utilities'; +import { getModel } from '../../../wizard/reducer'; import { getInCollectionFn } from '../../domain/domain.util'; -import { MetadataConfiguration } from '../model/metadata-configuration'; 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; @@ -66,87 +63,6 @@ export const processSchemaFn = (definition, schema) => { }; export const getConfigurationSchema = createSelector(getConfigurationDefinition, getSchema, processSchemaFn); - -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 => 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; @@ -218,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 new file mode 100644 index 000000000..f2481e99c --- /dev/null +++ b/ui/src/app/metadata/configuration/reducer/utilities.ts @@ -0,0 +1,105 @@ +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 : + ({ + 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 + }; + } + }); +}; + +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/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 index e7ea5dbf6..349f7cb74 100644 --- a/ui/src/app/metadata/domain/component/wizard-summary.component.html +++ b/ui/src/app/metadata/domain/component/wizard-summary.component.html @@ -1,7 +1,8 @@
- @@ -10,4 +11,4 @@
-
+
\ 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 index ecd51b1b9..43712bd48 100644 --- a/ui/src/app/metadata/domain/component/wizard-summary.component.spec.ts +++ b/ui/src/app/metadata/domain/component/wizard-summary.component.spec.ts @@ -35,7 +35,7 @@ class TestHostComponent { } } -describe('Provider Wizard Summary Component', () => { +describe('Wizard Summary Component', () => { let fixture: ComponentFixture; let instance: TestHostComponent; diff --git a/ui/src/app/metadata/domain/component/wizard-summary.component.ts b/ui/src/app/metadata/domain/component/wizard-summary.component.ts index 80f246c83..73a701491 100644 --- a/ui/src/app/metadata/domain/component/wizard-summary.component.ts +++ b/ui/src/app/metadata/domain/component/wizard-summary.component.ts @@ -1,5 +1,4 @@ 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'; @@ -30,7 +29,7 @@ export class WizardSummaryComponent implements OnChanges { columns: Array
[]; steps: WizardStep[]; - constructor() {} + constructor() { } ngOnChanges(changes: SimpleChanges): void { if (changes.summary && this.summary) { diff --git a/ui/src/app/metadata/domain/domain.module.ts b/ui/src/app/metadata/domain/domain.module.ts index ffee8cf1d..49e1fe685 100644 --- a/ui/src/app/metadata/domain/domain.module.ts +++ b/ui/src/app/metadata/domain/domain.module.ts @@ -16,17 +16,17 @@ 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'; 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 = [ - PreviewDialogComponent, WizardSummaryComponent, + PreviewDialogComponent, 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/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.html b/ui/src/app/metadata/resolver/container/resolver-wizard.component.html index 87100a871..425a84920 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,9 @@ - - +
+ +
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/metadata/resolver/container/resolver-wizard.component.ts b/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts index 56848ad5e..bd7c6e437 100644 --- a/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts +++ b/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts @@ -9,7 +9,7 @@ import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; -import { Observable, Subject, of, combineLatest as combine } from 'rxjs'; +import { Observable, Subject, of } from 'rxjs'; import { skipWhile, startWith, distinctUntilChanged, map, takeUntil, combineLatest, withLatestFrom } from 'rxjs/operators'; import { Store } from '@ngrx/store'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; @@ -28,7 +28,7 @@ import * as fromWizard from '../../../wizard/reducer'; 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 { MetadataConfiguration } from '../../configuration/model/metadata-configuration'; @Component({ selector: 'resolver-wizard-page', @@ -60,14 +60,13 @@ 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, private route: ActivatedRoute, private router: Router, private modalService: NgbModal, - private diffService: DifferentialService, @Inject(METADATA_SOURCE_WIZARD) private sourceWizard: Wizard ) { this.store @@ -115,20 +114,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); } @@ -163,16 +148,16 @@ export class ResolverWizardComponent implements OnDestroy, CanComponentDeactivat this.store.dispatch(new SetIndex(page)); } + get blacklist(): string[] { + return ['id', 'resourceId']; + } + hasChanges(changes: MetadataResolver): boolean { - // const updated = this.diffService.updatedDiff(this.resolver, changes); - // const deleted = this.diffService.deletedDiff(this.resolver, changes); - let blacklist = ['id', 'resourceId']; - return Object.keys(changes).filter(key => !(blacklist.indexOf(key) > -1)).length > 0; + return Object.keys(changes).filter(key => !(this.blacklist.indexOf(key) > -1)).length > 0; } isNew(changes: MetadataResolver): boolean { - let blacklist = ['id', 'resourceId']; - return Object.keys(changes).filter(key => !(blacklist.indexOf(key) > -1)).length === 0; + return Object.keys(changes).filter(key => !(this.blacklist.indexOf(key) > -1)).length === 0; } ngOnDestroy(): void { diff --git a/ui/src/app/metadata/resolver/reducer/index.ts b/ui/src/app/metadata/resolver/reducer/index.ts index a1cc5256d..a22693e4d 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.getProcessedSchema, + 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: [] 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);