Skip to content

Commit

Permalink
Merge branch 'master' into SHIBUI-693
Browse files Browse the repository at this point in the history
  • Loading branch information
dima767 committed Aug 8, 2018
2 parents 24cd0e2 + fed1e48 commit 6b80b62
Show file tree
Hide file tree
Showing 53 changed files with 1,200 additions and 662 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
@EqualsAndHashCode(callSuper = true)
public class EntityAttributesFilterTarget extends AbstractAuditable {
public enum EntityAttributesFilterTargetType {
ENTITY, CONDITION_SCRIPT, CONDITION_REF
ENTITY, CONDITION_SCRIPT, CONDITION_REF, REGEX
}

private static Logger LOGGER = LoggerFactory.getLogger(EntityAttributesFilterTarget.class);
Expand Down
4 changes: 2 additions & 2 deletions ui/src/app/metadata/domain/domain.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import {
} from './model';

import {
EntityAttributesFilter,
EntityAttributesFilterEntity,
FileBackedHttpMetadataResolver
} from './entity';
import {
FileBackedHttpMetadataProvider
} from './model/providers';

export type Filter =
| EntityAttributesFilter;
| EntityAttributesFilterEntity;

export type Resolver =
| FileBackedHttpMetadataResolver;
Expand Down
15 changes: 12 additions & 3 deletions ui/src/app/metadata/domain/effect/entity.effect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { EntityIdService } from '../service/entity-id.service';
import { ResolverService } from '../service/resolver.service';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { NgbModalStub } from '../../../../testing/modal.stub';
import { EntityAttributesFilter } from '../entity';
import { EntityAttributesFilterEntity, FileBackedHttpMetadataResolver } from '../entity';

describe('Entity Effects', () => {
let effects: EntityEffects;
Expand Down Expand Up @@ -45,13 +45,22 @@ describe('Entity Effects', () => {
});

describe('openModal', () => {
it('should open a modal window', fakeAsync(() => {
it('should open a modal window for a filter', fakeAsync(() => {
spyOn(modal, 'open').and.returnValue({componentInstance: <any>{}});
spyOn(idService, 'preview').and.returnValue(of('<foo></foo>'));
effects.openModal(new EntityAttributesFilter());
effects.openModal(new EntityAttributesFilterEntity());
expect(idService.preview).toHaveBeenCalled();
tick(10);
expect(modal.open).toHaveBeenCalled();
}));

it('should open a modal window for a provider', fakeAsync(() => {
spyOn(modal, 'open').and.returnValue({ componentInstance: <any>{} });
spyOn(providerService, 'preview').and.returnValue(of('<foo></foo>'));
effects.openModal(new FileBackedHttpMetadataResolver());
expect(providerService.preview).toHaveBeenCalled();
tick(10);
expect(modal.open).toHaveBeenCalled();
}));
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { EntityAttributesFilterEntity } from './entity-attributes-filter';

describe('EntityAttributesFilter Entity', () => {
let entity: EntityAttributesFilterEntity;
beforeEach(() => {
entity = new EntityAttributesFilterEntity({
resourceId: 'foo',
filterEnabled: false
});
});

it('should be an instance', () => {
expect(entity).toBeDefined();
expect(entity.resourceId).toBe('foo');
expect(entity.enabled).toBe(entity.filterEnabled);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { MetadataFilter, MetadataEntity, RelyingPartyOverrides } from '../../mod
import { MetadataTypes } from '../../domain.type';
import { FilterTarget } from '../../model';

export class EntityAttributesFilter implements MetadataFilter, MetadataEntity {
export class EntityAttributesFilterEntity implements MetadataFilter, MetadataEntity {
createdDate?: string;
modifiedDate?: string;
version: string;
Expand All @@ -25,7 +25,7 @@ export class EntityAttributesFilter implements MetadataFilter, MetadataEntity {
value: ['']
};

constructor(obj?: Partial<EntityAttributesFilter>) {
constructor(obj?: Partial<EntityAttributesFilterEntity>) {
Object.assign(this, { ...obj });
}

Expand Down
3 changes: 1 addition & 2 deletions ui/src/app/metadata/domain/model/metadata-filter.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { MetadataBase } from './metadata-base';

export interface MetadataFilter extends MetadataBase {
entityId: string;
name: string;
filterEnabled?: boolean;
type: string;
resourceId: string;

serialize(): any;
[key: string]: any;
}
6 changes: 3 additions & 3 deletions ui/src/app/metadata/domain/service/filter.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { TestBed, async, inject } from '@angular/core/testing';
import { HttpTestingController, HttpClientTestingModule } from '@angular/common/http/testing';
import { HttpClientModule, HttpRequest } from '@angular/common/http';
import { MetadataFilterService } from './filter.service';
import { EntityAttributesFilter } from '../entity';
import { EntityAttributesFilterEntity } from '../entity';

describe(`Metadata Filter Service`, () => {

Expand Down Expand Up @@ -49,7 +49,7 @@ describe(`Metadata Filter Service`, () => {
it(`should send an expected PUT request`, async(inject([MetadataFilterService, HttpTestingController],
(service: MetadataFilterService, backend: HttpTestingController) => {
const id = 'bar';
const filter = new EntityAttributesFilter({ resourceId: id });
const filter = new EntityAttributesFilterEntity({ resourceId: id });
service.update(provider, filter).subscribe();

backend.expectOne((req: HttpRequest<any>) => {
Expand All @@ -63,7 +63,7 @@ describe(`Metadata Filter Service`, () => {
it(`should send an expected POST request`, async(inject([MetadataFilterService, HttpTestingController],
(service: MetadataFilterService, backend: HttpTestingController) => {
const id = 'bar';
const filter = new EntityAttributesFilter({ id });
const filter = new EntityAttributesFilterEntity({ resourceId: id });
service.save(provider, filter).subscribe();

backend.expectOne((req: HttpRequest<any>) => {
Expand Down
201 changes: 29 additions & 172 deletions ui/src/app/metadata/filter/container/edit-filter.component.html
Original file line number Diff line number Diff line change
@@ -1,184 +1,41 @@
<div class="container-fluid p-3" role="main">
<section class="section" *ngIf="filter$ | async">
<section class="section">
<div class="section-header bg-info p-2 text-white">
<div class="row justify-content-between">
<div class="col-md-12">
<span class="display-6">
<i class="fa fa-fw fa-gears"></i>
<ng-container i18n="@@label--edit-filter">Edit Filter - {{ (filter$ | async).name }}</ng-container>
<ng-container i18n="@@label--new-filter">new EntityAttributesFilter</ng-container>
</span>
</div>
</div>
</div>
<div class="section-body p-4 border border-top-0 border-info">
<form [formGroup]="form">
<div class="row">
<div class="col-lg-6 col-xs-9 ">
<fieldset class="">
<div class="form-group">
<div class="row">
<label for="name" class="col-sm-10">
<span>
<ng-container i18n="@@label--filter-name">
Filter Name
</ng-container>
<ng-container i18n="@@label--dashboard-display-only">
(Dashboard Display Only)
</ng-container>
<i class="fa fa-fw fa-asterisk text-danger" aria-hidden="true"></i>
</span>
</label>
<span class="text-right col-sm-2">
<ng-template #tooltipFilterName i18n="@@tooltip--filter-name">Filter Name</ng-template>
<i class="info-icon fa fa-fw fa-info-circle text-primary fa-lg" [ngbPopover]="tooltipFilterName" i18n-aria-label="@@tooltip--instruction"
aria-label="Information icon - press spacebar to read additional information for this form field"></i>
</span>
</div>
<input id="name" type="text" class="form-control" placeholder="" formControlName="name" />
<ng-container *ngIf="form.get('name').touched && form.get('name').invalid">
<small class="form-text text-danger" *ngIf="form.get('name').hasError('required')">
<ng-container i18n="@@message--filter-name-required">Filter Name is required</ng-container>
</small>
</ng-container>
</div>
<div class="form-group">
<div class="row">
<label for="entityId" class="col-sm-10">
<span>
<ng-container i18n="@@label--search-entity-id">Search Entity ID</ng-container>
<i class="fa fa-fw fa-asterisk text-danger" aria-hidden="true"></i>
<i class="fa fa-fw fa-spinner fa-pulse fa-fw" *ngIf="processing$ | async"></i>
</span>
</label>
<span class="text-right col-sm-2">
<ng-template #tooltipFilterEntityId i18n="@@tooltip--search-entity-id">Search Entity ID</ng-template>
<i class="info-icon fa fa-fw fa-info-circle text-primary fa-lg" [ngbPopover]="tooltipFilterEntityId" i18n-aria-label="@@tooltip--instruction"
aria-label="Information icon - press spacebar to read additional information for this form field"></i>
</span>
</div>
<label for="entityId" class="sr-only" i18n="@@label--search-entity-id">Search Entity ID</label>
<div class="row">
<div class="col-9">
<auto-complete id="entityId"
#entityInput
class="component-control"
formControlName="entityId"
limit="10"
[matches]="entityIds$ | async"
[required]="true"
[processing]="(processing$ | async)"
(more)="onViewMore($event)">
</auto-complete>
<small class="form-text text-muted" i18n="@@label--min-chars">
Minimum 4 characters.
</small>
<ng-container *ngIf="form.get('entityId').touched && form.get('entityId').invalid">
<small class="form-text text-danger">
<ng-container *ngIf="form.get('entityId').hasError('required')" i18n="@@message--entity-id-required">Entity ID is required</ng-container>
<ng-container *ngIf="form.get('entityId').hasError('exists')" i18n="@@message--entity-id-not-found">Entity ID not found</ng-container>
</small>
</ng-container>
</div>
<div class="col-3">
<button
*ngIf="form.get('entityId').disabled"
class="btn btn-block btn-secondary"
type="button"
(click)="onChangeId()">
Change ID
</button>
<button
*ngIf="form.get('entityId').enabled"
class="btn btn-block btn-outline-secondary"
type="button"
(click)="onCancelChangeId()">
Cancel
</button>
</div>
</div>
</div>
</fieldset>
</div>
<div class="col-lg-6 col-xs-3 text-right">
<button (click)="this.preview(filter)" type="submit" class="btn btn-success">
<i class="fa fa-fw fa-eye fa-lg"></i>
<ng-container i18n="@@action--save">Preview XML</ng-container>
</button>
&nbsp;
<button
(click)="this.save($event)"
type="submit"
class="btn btn-primary"
[disabled]="form.invalid || (isSaving$ | async)">
<i class="fa fa-fw fa-lg"
[ngClass]="{
'fa-save': !(isSaving$ | async),
'fa-spinner': (isSaving$ | async),
'fa-pulse': (isSaving$ | async)
}"></i>
<ng-container i18n="@@action--save">Save</ng-container>
</button>
&nbsp;
<button
(click)="this.cancel()"
type="reset"
class="btn btn-secondary"
[disabled]="isSaving$ | async ">
<ng-container i18n="@@action--cancel">Cancel</ng-container>
</button>
</div>
</div>
<section>
<hr />
<div class="row" *ngIf="preview$ | async">
<fieldset class="col-lg-6">
<div class="form-group">
<div class="row">
<label for="name" class="col-sm-10" i18n="@@label--entity-preview">
Entity ID Preview (read-only)
</label>
<span class="text-right col-sm-2">
<ng-template #tooltipName i18n="@@tooltip--entity-preview">Entity Preview</ng-template>
<i class="info-icon fa fa-fw fa-info-circle text-primary fa-lg" [ngbPopover]="tooltipName" i18n-aria-label="@@tooltip--instruction"
aria-label="Information icon - press spacebar to read additional information for this form field"></i>
</span>
</div>
<dl>
<dt class="text-primary" i18n="@@label--display-name">Display Name</dt>
<dd class="value">{{ (preview$ | async).displayName }}</dd>
<dt class="text-primary" i18n="@@label--description">Description</dt>
<dd class="value">{{ (preview$ | async).description || '&mdash;' }}</dd>
</dl>
</div>
<hr />
</fieldset>
</div>
<div class="row">
<div class="col-12">
<div class="form-group">
<div class="custom-control custom-checkbox custom-control-inline custom-control-reverse" for="filterEnabled">
<input disableValidation="true" class="custom-control-input" type="checkbox" formControlName="filterEnabled" id="filterEnabled"
name="filterEnabled" role="checkbox">
<label class="custom-control-label" i18n="@@label--enable-this-filter" for="filterEnabled" aria-label="Enable this filter?">
Enable this filter?
</label>
</div>
<ng-template #tooltipEnableThisFilterUponSaving i18n="@@tooltip--enable-this-filter-upon-saving">Enable this filter upon saving popover</ng-template>
<i class="info-icon fa fa-fw fa-info-circle text-primary fa-lg" [ngbPopover]="tooltipEnableThisFilterUponSaving" i18n-aria-label="@@tooltip--instruction"
role="tooltip"></i>
</div>
</div>
</div>
<div class="row" *ngIf="filter$ | async">
<div class="col-lg-6">
<relying-party-form [resolver]="filter$ | async"></relying-party-form>
</div>
<div class="col-lg-6">
<attribute-release-form [resolver]="filter$ | async"></attribute-release-form>
</div>
</div>
</section>
</form>
<div class="section-body p-4 border border-top-0 border-info" *ngIf="schema$ | async">
<div class="mx-3 my-2 d-flex justify-content-end">
<button (click)="this.preview(filter)" type="submit" class="btn btn-success">
<i class="fa fa-fw fa-eye fa-lg"></i>
<ng-container i18n="@@action--save">Preview XML</ng-container>
</button>
&nbsp;
<button (click)="this.save()" type="submit" class="btn btn-primary" [disabled]="!isValid || (isSaving$ | async)">
<i class="fa fa-fw fa-lg" [ngClass]="{
'fa-save': !(isSaving$ | async),
'fa-spinner': (isSaving$ | async),
'fa-pulse': (isSaving$ | async)
}"></i>
<ng-container i18n="@@action--save">Save</ng-container>
</button>
&nbsp;
<button (click)="this.cancel()" type="reset" class="btn btn-secondary" [disabled]="isSaving$ | async">
<ng-container i18n="@@action--cancel">Cancel</ng-container>
</button>
</div>
<sf-form
[schema]="schema$ | async"
[model]="model$ | async"
[validators]="definition.getValidators()"
(onChange)="valueChangeSubject.next($event)"
(onErrorChange)="statusChangeSubject.next($event)"></sf-form>
</div>
</section>
</div>
</div>
Loading

0 comments on commit 6b80b62

Please sign in to comment.