Skip to content

Commit

Permalink
Fix merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
dima767 committed Dec 5, 2018
2 parents 3f14ef4 + 3e2bfde commit e0fcb55
Show file tree
Hide file tree
Showing 20 changed files with 171 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import edu.internet2.tier.shibboleth.admin.ui.domain.exceptions.MetadataFileNotFoundException;
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver;
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand All @@ -12,6 +13,7 @@
import org.springframework.web.client.HttpClientErrorException;

import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.NOT_FOUND;

/**
Expand Down Expand Up @@ -42,6 +44,11 @@ public ResponseEntity<?> notFoundHandler(HttpClientErrorException ex) {
throw ex;
}

@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<ErrorResponse> handleDatabaseConstraintViolation(ConstraintViolationException ex) {
return ResponseEntity.status(BAD_REQUEST).body(new ErrorResponse("400", "message.database-constraint"));
}

@ExceptionHandler(Exception.class)
public final ResponseEntity<ErrorResponse> handleAllOtherExceptions(Exception ex) {
ErrorResponse errorResponse = new ErrorResponse("400", ex.getLocalizedMessage());
Expand Down
1 change: 1 addition & 0 deletions backend/src/main/resources/i18n/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ message.entity-id-min-unique=You must add at least one entity id target and they
message.required-for-scripts=Required for Scripts
message.required-for-regex=Required for Regex
message.file-doesnt-exist=The requested file to be processed does not exist on the server.
message.database-constraint=There was a database constraint problem processing the request. Check the request to ensure that fields that must be unique are truly unique.

tooltip.entity-id=Entity ID
tooltip.service-provider-name=Service Provider Name (Dashboard Display Only)
Expand Down
1 change: 1 addition & 0 deletions backend/src/main/resources/i18n/messages_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ message.entity-id-min-unique=You must add at least one entity id target and they
message.required-for-scripts=Required for Scripts
message.required-for-regex=Required for Regex
message.file-doesnt-exist=The requested file to be processed does not exist on the server.
message.database-constraint=There was a database constraint problem processing the request. Check the request to ensure that fields that must be unique are truly unique.

tooltip.entity-id=Entity ID
tooltip.service-provider-name=Service Provider Name (Dashboard Display Only)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<sf-form
[schema]="schema$ | async"
[model]="model$ | async"
[validators]="definition.getValidators()"
[validators]="validators$ | async"
[actions]="actions"
(onChange)="valueChangeSubject.next($event)"
(onErrorChange)="statusChangeSubject.next($event)"></sf-form>
Expand Down
13 changes: 12 additions & 1 deletion ui/src/app/metadata/filter/container/edit-filter.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -33,6 +33,8 @@ export class EditFilterComponent {
filter: MetadataFilter;
isValid: boolean;

validators$: Observable<{ [key: string]: any }>;

actions: any;

constructor(
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/metadata/filter/container/filter.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<ng-container *ngIf="filter$ | async">
<ng-container>
<router-outlet></router-outlet>
</ng-container>
16 changes: 6 additions & 10 deletions ui/src/app/metadata/filter/container/filter.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<MetadataFilter>;
filters$: Observable<MetadataFilter[]>;

constructor(
private store: Store<fromFilter.State>,
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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<sf-form
[schema]="schema$ | async"
[model]="model$ | async"
[validators]="definition.getValidators()"
[validators]="validators$ | async"
(onChange)="valueChangeSubject.next($event)"
(onErrorChange)="statusChangeSubject.next($event)"></sf-form>
</div>
Expand Down
8 changes: 7 additions & 1 deletion ui/src/app/metadata/filter/container/new-filter.component.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -33,6 +33,8 @@ export class NewFilterComponent implements OnDestroy, OnInit {
filter: MetadataFilter;
isValid: boolean;

validators$: Observable<{ [key: string]: any }>;

constructor(
private store: Store<fromFilter.State>,
private schemaService: SchemaService
Expand All @@ -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(<MetadataFilter>{});

this.validators$ = this.store.select(fromFilter.getFilterNames).pipe(
map((names) => this.definition.getValidators(names))
);
}

ngOnInit(): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<ng-container *ngIf="filter$ | async">
<router-outlet></router-outlet>
</ng-container>
Empty file.
39 changes: 39 additions & 0 deletions ui/src/app/metadata/filter/container/select-filter.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Component, OnDestroy } from '@angular/core';
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 * as fromFilter from '../reducer';

@Component({
selector: 'select-filter-page',
templateUrl: './select-filter.component.html',
styleUrls: ['./select-filter.component.scss'],
providers: [NgbPopoverConfig]
})
export class SelectFilterComponent implements OnDestroy {
actionsSubscription: Subscription;
filter$: Observable<MetadataFilter>;

constructor(
private store: Store<fromFilter.State>,
private route: ActivatedRoute
) {
this.actionsSubscription = this.route.params.pipe(
distinctUntilChanged(),
map(params => {
return new SelectFilter(params.id);
})
).subscribe(store);

this.filter$ = this.store.select(fromFilter.getSelectedFilter);
}

ngOnDestroy() {
this.actionsSubscription.unsubscribe();
}
} /* istanbul ignore next */
8 changes: 0 additions & 8 deletions ui/src/app/metadata/filter/effect/collection.effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,6 @@ export class FilterCollectionEffects {
)
);

/*
@Effect()
reloadOrderAfterChange$ = this.actions$.pipe(
ofType<SetOrderFilterSuccess>(FilterCollectionActionTypes.SET_ORDER_FILTER_SUCCESS),
map(() => new GetOrderFilterRequest())
);
*/

@Effect()
setOrder$ = this.actions$.pipe(
ofType<SetOrderFilterRequest>(FilterCollectionActionTypes.SET_ORDER_FILTER_REQUEST),
Expand Down
8 changes: 5 additions & 3 deletions ui/src/app/metadata/filter/filter.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,23 @@ 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';
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
Expand Down
33 changes: 31 additions & 2 deletions ui/src/app/metadata/filter/model/entity-attributes.filter.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,37 @@
import { EntityAttributesFilter } from './entity-attributes.filter';

describe('Entity Attributes filter form', () => {
it('should return an empty object for validators', () => {
expect(EntityAttributesFilter.getValidators()).toEqual({});
describe('getValidators', () => {
it('should return an empty object for validators', () => {
expect(Object.keys(EntityAttributesFilter.getValidators())).toEqual([
'/',
'/name'
]);
});

describe('name `/name` validator', () => {
const validators = EntityAttributesFilter.getValidators(['foo', 'bar']);

it('should return an invalid object when provided values are invalid based on name', () => {
expect(validators['/name']('foo', { path: '/name' })).toBeDefined();
});

it('should return null when provided values are valid based on name', () => {
expect(validators['/name']('baz', { path: '/name' })).toBeNull();
});
});

describe('parent `/` validator', () => {
const validators = EntityAttributesFilter.getValidators(['foo', 'bar']);

it('should return a list of child errors', () => {
expect(validators['/']({ name: 'foo' }, { path: '/name' }, {}).length).toBe(1);
});

it('should ignore properties that don\'t exist a list of child errors', () => {
expect(validators['/']({ foo: 'bar' }, { path: '/foo' }, {})).toBeUndefined();
});
});
});

describe('transformer', () => {
Expand Down
30 changes: 28 additions & 2 deletions ui/src/app/metadata/filter/model/entity-attributes.filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,34 @@ export const EntityAttributesFilter: FormDefinition<MetadataFilter> = {
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,
Expand Down
3 changes: 3 additions & 0 deletions ui/src/app/metadata/filter/reducer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ export class ProviderSelectComponent implements OnDestroy {
map(params => new SelectProviderRequest(params.providerId))
).subscribe(store);

this.route.params.subscribe(params => console.log(params));

this.provider$ = this.store.select(fromProviders.getSelectedProvider).pipe(skipWhile(p => !p));

this.provider$.subscribe(provider => this.setDefinition(provider));
Expand Down
Loading

0 comments on commit e0fcb55

Please sign in to comment.