From bfceb8c9caa24711d9ea9b25d00e35606aa07197 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 29 Nov 2018 14:23:30 -0700 Subject: [PATCH] SHIBUI-996 Added name unique validation --- .../container/edit-filter.component.html | 2 +- .../filter/container/edit-filter.component.ts | 13 ++++- .../filter/container/filter.component.html | 2 +- .../filter/container/filter.component.scss | 0 .../filter/container/filter.component.ts | 16 +++---- .../container/new-filter.component.html | 2 +- .../filter/container/new-filter.component.ts | 8 +++- ui/src/app/metadata/filter/filter.module.ts | 8 ++-- .../filter/model/entity-attributes.filter.ts | 30 +++++++++++- ui/src/app/metadata/filter/reducer/index.ts | 3 ++ .../filter/service/filter-resolver.service.ts | 7 --- .../app/metadata/provider/provider.routing.ts | 47 +++++++++++-------- 12 files changed, 91 insertions(+), 47 deletions(-) delete mode 100644 ui/src/app/metadata/filter/container/filter.component.scss delete mode 100644 ui/src/app/metadata/filter/service/filter-resolver.service.ts diff --git a/ui/src/app/metadata/filter/container/edit-filter.component.html b/ui/src/app/metadata/filter/container/edit-filter.component.html index 60790fdff..e42137ebf 100644 --- a/ui/src/app/metadata/filter/container/edit-filter.component.html +++ b/ui/src/app/metadata/filter/container/edit-filter.component.html @@ -28,7 +28,7 @@ diff --git a/ui/src/app/metadata/filter/container/edit-filter.component.ts b/ui/src/app/metadata/filter/container/edit-filter.component.ts index a98cbc62d..21983f5a9 100644 --- a/ui/src/app/metadata/filter/container/edit-filter.component.ts +++ b/ui/src/app/metadata/filter/container/edit-filter.component.ts @@ -11,7 +11,7 @@ import { UpdateFilterRequest } from '../action/collection.action'; import { CancelCreateFilter, UpdateFilterChanges } from '../action/filter.action'; import { PreviewEntity } from '../../domain/action/entity.action'; import { EntityAttributesFilterEntity } from '../../domain/entity'; -import { shareReplay } from 'rxjs/operators'; +import { shareReplay, map, withLatestFrom } from 'rxjs/operators'; @Component({ selector: 'edit-filter-page', @@ -33,6 +33,8 @@ export class EditFilterComponent { filter: MetadataFilter; isValid: boolean; + validators$: Observable<{ [key: string]: any }>; + actions: any; constructor( @@ -50,6 +52,15 @@ export class EditFilterComponent { this.isValid = valid.value ? valid.value.length === 0 : true; }); + this.validators$ = this.store.select(fromFilter.getFilterNames).pipe( + withLatestFrom( + this.store.select(fromFilter.getSelectedFilter) + ), + map(([names, provider]) => this.definition.getValidators( + names.filter(n => n !== provider.name) + )) + ); + this.store .select(fromFilter.getFilter) .subscribe(filter => this.filter = filter); diff --git a/ui/src/app/metadata/filter/container/filter.component.html b/ui/src/app/metadata/filter/container/filter.component.html index 3793ba3bf..eb3040a74 100644 --- a/ui/src/app/metadata/filter/container/filter.component.html +++ b/ui/src/app/metadata/filter/container/filter.component.html @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/ui/src/app/metadata/filter/container/filter.component.scss b/ui/src/app/metadata/filter/container/filter.component.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/ui/src/app/metadata/filter/container/filter.component.ts b/ui/src/app/metadata/filter/container/filter.component.ts index 2f2d0aa44..6dc02e037 100644 --- a/ui/src/app/metadata/filter/container/filter.component.ts +++ b/ui/src/app/metadata/filter/container/filter.component.ts @@ -3,35 +3,31 @@ import { ActivatedRoute } from '@angular/router'; import { Observable, Subscription } from 'rxjs'; import { distinctUntilChanged, map } from 'rxjs/operators'; import { Store } from '@ngrx/store'; -import { NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap'; import { MetadataFilter } from '../../domain/model/metadata-filter'; -import { SelectFilter } from '../action/collection.action'; +import { LoadFilterRequest } from '../action/collection.action'; import * as fromFilter from '../reducer'; - @Component({ selector: 'filter-page', templateUrl: './filter.component.html', - styleUrls: ['./filter.component.scss'], - providers: [NgbPopoverConfig] + styleUrls: [], + providers: [] }) export class FilterComponent implements OnDestroy { actionsSubscription: Subscription; - filter$: Observable; + filters$: Observable; constructor( private store: Store, private route: ActivatedRoute ) { - this.actionsSubscription = this.route.params.pipe( + this.actionsSubscription = this.route.parent.params.pipe( distinctUntilChanged(), map(params => { - return new SelectFilter(params.id); + return new LoadFilterRequest(params.providerId); }) ).subscribe(store); - - this.filter$ = this.store.select(fromFilter.getSelectedFilter); } ngOnDestroy() { diff --git a/ui/src/app/metadata/filter/container/new-filter.component.html b/ui/src/app/metadata/filter/container/new-filter.component.html index 1b0d62945..e56dc4634 100644 --- a/ui/src/app/metadata/filter/container/new-filter.component.html +++ b/ui/src/app/metadata/filter/container/new-filter.component.html @@ -28,7 +28,7 @@ diff --git a/ui/src/app/metadata/filter/container/new-filter.component.ts b/ui/src/app/metadata/filter/container/new-filter.component.ts index aeb56e019..043936fc2 100644 --- a/ui/src/app/metadata/filter/container/new-filter.component.ts +++ b/ui/src/app/metadata/filter/container/new-filter.component.ts @@ -1,7 +1,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import { Subject, Observable, of } from 'rxjs'; -import { takeUntil, shareReplay } from 'rxjs/operators'; +import { takeUntil, shareReplay, withLatestFrom, map, filter } from 'rxjs/operators'; import * as fromFilter from '../reducer'; import { MetadataFilterTypes } from '../model'; @@ -33,6 +33,8 @@ export class NewFilterComponent implements OnDestroy, OnInit { filter: MetadataFilter; isValid: boolean; + validators$: Observable<{ [key: string]: any }>; + constructor( private store: Store, private schemaService: SchemaService @@ -42,6 +44,10 @@ export class NewFilterComponent implements OnDestroy, OnInit { this.schema$ = this.schemaService.get(this.definition.schema).pipe(shareReplay()); this.isSaving$ = this.store.select(fromFilter.getCollectionSaving); this.model$ = of({}); + + this.validators$ = this.store.select(fromFilter.getFilterNames).pipe( + map((names) => this.definition.getValidators(names)) + ); } ngOnInit(): void { diff --git a/ui/src/app/metadata/filter/filter.module.ts b/ui/src/app/metadata/filter/filter.module.ts index 34997c563..e090745f2 100644 --- a/ui/src/app/metadata/filter/filter.module.ts +++ b/ui/src/app/metadata/filter/filter.module.ts @@ -13,7 +13,7 @@ import { NgbPopoverModule, NgbModalModule } from '@ng-bootstrap/ng-bootstrap'; import { SearchDialogComponent } from './component/search-dialog.component'; import { SharedModule } from '../../shared/shared.module'; import { EditFilterComponent } from './container/edit-filter.component'; -import { FilterComponent } from './container/filter.component'; +import { SelectFilterComponent } from './container/select-filter.component'; import { SearchIdEffects } from './effect/search.effect'; import { FilterExistsGuard } from './guard/filter-exists.guard'; import { DomainModule } from '../domain/domain.module'; @@ -21,13 +21,15 @@ import { ModuleWithProviders } from '@angular/compiler/src/core'; import { FilterCollectionEffects } from './effect/collection.effect'; import { FormModule } from '../../schema-form/schema-form.module'; import { I18nModule } from '../../i18n/i18n.module'; +import { FilterComponent } from './container/filter.component'; @NgModule({ declarations: [ NewFilterComponent, EditFilterComponent, - FilterComponent, - SearchDialogComponent + SelectFilterComponent, + SearchDialogComponent, + FilterComponent ], entryComponents: [ SearchDialogComponent diff --git a/ui/src/app/metadata/filter/model/entity-attributes.filter.ts b/ui/src/app/metadata/filter/model/entity-attributes.filter.ts index 0d559c094..5c40ecfb1 100644 --- a/ui/src/app/metadata/filter/model/entity-attributes.filter.ts +++ b/ui/src/app/metadata/filter/model/entity-attributes.filter.ts @@ -5,8 +5,34 @@ export const EntityAttributesFilter: FormDefinition = { label: 'EntityAttributes', type: 'EntityAttributes', schema: '/api/ui/EntityAttributesFilters', - getValidators(): any { - const validators = {}; + getValidators(namesList: string[] = []): any { + const validators = { + '/': (value, property, form_current) => { + let errors; + // iterate all customer + Object.keys(value).forEach((key) => { + const item = value[key]; + const validatorKey = `/${key}`; + const validator = validators.hasOwnProperty(validatorKey) ? validators[validatorKey] : null; + const error = validator ? validator(item, { path: `/${key}` }, form_current) : null; + if (error) { + errors = errors || []; + errors.push(error); + } + }); + return errors; + }, + '/name': (value, property, form) => { + console.log(namesList); + const err = namesList.indexOf(value) > -1 ? { + code: 'INVALID_NAME', + path: `#${property.path}`, + message: 'message.name-must-be-unique', + params: [value] + } : null; + return err; + } + }; return validators; }, parser: (changes: any): MetadataFilter => changes, diff --git a/ui/src/app/metadata/filter/reducer/index.ts b/ui/src/app/metadata/filter/reducer/index.ts index caacf0254..495bf1e52 100644 --- a/ui/src/app/metadata/filter/reducer/index.ts +++ b/ui/src/app/metadata/filter/reducer/index.ts @@ -4,6 +4,7 @@ import * as fromFilter from './filter.reducer'; import * as fromSearch from './search.reducer'; import * as fromCollection from './collection.reducer'; import * as utils from '../../domain/domain.util'; +import { MetadataFilter } from '../../domain/model'; export interface FilterState { filter: fromFilter.FilterState; @@ -71,6 +72,8 @@ export const getAdditionalFilterOrder = createSelector(getFilterEntities, getCol export const getAdditionalFilters = createSelector(getFilterList, getAdditionalFilterOrder, utils.mergeOrderFn); export const getPluginFilterOrder = createSelector(getFilterEntities, getCollectionOrder, pluginOrderFn); +export const getFilterNames = createSelector(getAllFilters, (filters: MetadataFilter[]) => filters.map(f => f.name).filter(f => !!f)); + /* * Combine pieces of State */ diff --git a/ui/src/app/metadata/filter/service/filter-resolver.service.ts b/ui/src/app/metadata/filter/service/filter-resolver.service.ts deleted file mode 100644 index e6b2e76f6..000000000 --- a/ui/src/app/metadata/filter/service/filter-resolver.service.ts +++ /dev/null @@ -1,7 +0,0 @@ -this.provider$ - .pipe( - takeUntil(this.ngUnsubscribe) - ) - .subscribe(p => { - this.store.dispatch(new LoadFilterRequest(p.resourceId)); - }); \ No newline at end of file diff --git a/ui/src/app/metadata/provider/provider.routing.ts b/ui/src/app/metadata/provider/provider.routing.ts index 7acd52fec..fa1a4c3b5 100644 --- a/ui/src/app/metadata/provider/provider.routing.ts +++ b/ui/src/app/metadata/provider/provider.routing.ts @@ -8,9 +8,10 @@ import { ProviderEditStepComponent } from './container/provider-edit-step.compon import { ProviderSelectComponent } from './container/provider-select.component'; import { ProviderFilterListComponent } from './container/provider-filter-list.component'; import { NewFilterComponent } from '../filter/container/new-filter.component'; -import { FilterComponent } from '../filter/container/filter.component'; +import { SelectFilterComponent } from '../filter/container/select-filter.component'; import { EditFilterComponent } from '../filter/container/edit-filter.component'; import { CanDeactivateGuard } from '../../core/service/can-deactivate.guard'; +import { FilterComponent } from '../filter/container/filter.component'; export const ProviderRoutes: Routes = [ { @@ -36,6 +37,31 @@ export const ProviderRoutes: Routes = [ path: ':providerId', component: ProviderSelectComponent, children: [ + { + path: '', + component: FilterComponent, + children: [ + { + path: 'filters', + component: ProviderFilterListComponent + }, + { + path: 'filter/new', + component: NewFilterComponent + }, + { + path: 'filter/:id', + component: SelectFilterComponent, + canActivate: [], + children: [ + { + path: 'edit', + component: EditFilterComponent + } + ] + } + ] + }, { path: 'edit', component: ProviderEditComponent, @@ -49,25 +75,6 @@ export const ProviderRoutes: Routes = [ canDeactivate: [ CanDeactivateGuard ] - }, - { - path: 'filters', - component: ProviderFilterListComponent - }, - { - path: 'filter/new', - component: NewFilterComponent - }, - { - path: 'filter/:id', - component: FilterComponent, - canActivate: [], - children: [ - { - path: 'edit', - component: EditFilterComponent - } - ] } ] }