Skip to content

Commit

Permalink
Merged in feature/SHIBUI-1364 (pull request #378)
Browse files Browse the repository at this point in the history
SHIBUI-1364 Implemented filter comparison

Approved-by: Dmitriy Kopylenko <dkopylenko@unicon.net>
  • Loading branch information
rmathis committed Sep 26, 2019
2 parents b2c5fee + 0f65f74 commit 0d48b13
Show file tree
Hide file tree
Showing 21 changed files with 605 additions and 15 deletions.
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 @@ -280,6 +280,7 @@ label.filter-enable=Enable this Filter?
label.search-criteria=Search Criteria
label.metadata-filter=Metadata Filter
label.metadata-filter-type=Metadata Filter Type
label.filter-versions=Filter Versions

label.http-connection-attributes=HTTP Connection Attributes
label.http-security-attributes=HTTP Security Attributes
Expand Down
2 changes: 0 additions & 2 deletions ui/src/app/metadata/configuration/action/compare.action.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { Action } from '@ngrx/store';
import { MetadataHistory } from '../model/history';
import { MetadataVersion } from '../model/version';
import { Metadata } from '../../domain/domain.type';

export enum CompareActionTypes {
Expand Down
62 changes: 62 additions & 0 deletions ui/src/app/metadata/configuration/action/filter.action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Action } from '@ngrx/store';
import { Metadata } from '../../domain/domain.type';
import { FormDefinition } from '../../../wizard/model/form-definition';
import { FilterComparison } from '../model/compare';
import { Schema } from '../model/schema';

export enum FilterCompareActionTypes {
LOAD_SCHEMA_REQUEST = '[Filter Compare Version] Compare Version Request',
LOAD_SCHEMA_SUCCESS = '[Filter Compare Version] Compare Version Success',
LOAD_SCHEMA_ERROR = '[Filter Compare Version] Compare Version Error',
SET_SCHEMA = '[Filter Compare Version] Set Schema',
SET_DEFINITION = '[Filter Compare Version] Set Definition',
COMPARE_FILTERS = '[Filter Compare Version] Compare Filters',
CLEAR = '[Filter Compare Version] Clear Filter Comparison'
}

export class LoadFilterSchemaRequest implements Action {
readonly type = FilterCompareActionTypes.LOAD_SCHEMA_REQUEST;

constructor(public payload: string) { }
}

export class LoadFilterSchemaSuccess implements Action {
readonly type = FilterCompareActionTypes.LOAD_SCHEMA_SUCCESS;

constructor(public payload: Schema) { }
}

export class LoadFilterSchemaError implements Action {
readonly type = FilterCompareActionTypes.LOAD_SCHEMA_ERROR;

constructor(public payload: any) { }
}

export class SetFilterComparisonSchema implements Action {
readonly type = FilterCompareActionTypes.SET_SCHEMA;
constructor(public payload: any) { }
}

export class SetFilterComparisonDefinition implements Action {
readonly type = FilterCompareActionTypes.SET_DEFINITION;
constructor(public payload: FormDefinition<Metadata>) { }
}

export class ClearFilterComparison implements Action {
readonly type = FilterCompareActionTypes.CLEAR;
}

export class CompareFilterVersions implements Action {
readonly type = FilterCompareActionTypes.COMPARE_FILTERS;

constructor(public payload: FilterComparison) { }
}

export type FilterCompareActionsUnion =
| LoadFilterSchemaRequest
| LoadFilterSchemaSuccess
| LoadFilterSchemaError
| SetFilterComparisonSchema
| SetFilterComparisonDefinition
| CompareFilterVersions
| ClearFilterComparison;
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<ng-container *ngIf="filters && filters.dates.length > 0">
<div class="d-flex border-bottom border-light border-2 py-2">
<span [ngStyle]="{'width.%': width}" *ngIf="!comparing">Order</span>
<span [ngStyle]="{'width.%': width}" *ngIf="comparing">Option</span>
<strong *ngFor="let date of filters.dates" [ngStyle]="{'width.%': width}">
{{ date | date:DATE_FORMAT }}
</strong>
</div>
<div class="">
<ng-container *ngFor="let version of filters.filters; let i = index; first as isFirst; last as isLast;">
<div class="d-flex border-bottom border-light">
<div [ngStyle]="{'width.%': width}" class="py-2">
{{ i + 1 }}
</div>
<div *ngFor="let filter of version; let i = index; even as isEven"
[ngStyle]="{'width.%': width}"
class="border-primary">
<div class="p-2 w-100" *ngIf="!filter">-</div>
<div *ngIf="filter"
class="p-2 d-flex align-items-center"
[ngClass]="{
'bg-lighter': isEven && selected !== filter.resourceId,
'bg-primary-light': selected === filter.resourceId
}">
<div class="w-50">
<p class="mb-0">{{ filter.name }}</p>
<p class="mb-0 text-muted">{{ filter['@type'] }}</p>
</div>
<button class="btn btn-link mx-auto" *ngIf="filter.comparable"
(click)="selected = (selected !== filter.resourceId) ? filter.resourceId : null">
<i class="fa fa-lg"
[ngClass]="{'fa-check-square-o': selected === filter.resourceId, 'fa-square-o': selected !== filter.resourceId}"
aria-hidden="true"></i>
<span class="sr-only">Compare</span>
</button>
</div>
</div>

</div>
</ng-container>
</div>
<div class="d-flex justify-content-end my-2">
<button class="btn btn-primary" [disabled]="!selected" (click)="compareSelected()">
<translate-i18n key="label.compare-selected">Compare Selected</translate-i18n>
</button>
</div>
</ng-container>
<div class="alert alert-info m-4" *ngIf="filters && filters.dates.length < 1">
<h3 translate="message.no-filters">No Filters</h3>
<p translate="message.no-filters-added">No filters have been added to this Metadata Provider</p>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { Component, ViewChild } from '@angular/core';
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';

import { MockI18nModule } from '../../../../testing/i18n.stub';
import { FilterVersionListComponent } from './filter-version-list.component';
import { FilterComparison } from '../model/compare';
import { FilterConfiguration } from '../model/metadata-configuration';

export const TestData: FilterConfiguration = {
dates: ['2019-09-23T20:54:31.081Z', '2019-10-23T20:54:31.081Z'],
filters: [
[
{
resourceId: 'foo',
name: 'Test 1',
type: 'EntityAttributesFilter',
comparable: false
},
{
resourceId: 'bar',
name: 'Test 2',
type: 'EntityAttributesFilter',
comparable: false
}
]
]
};

@Component({
template: `<filter-version-list [filters]="filters" (compare)="compare($event)"></filter-version-list>`
})
class TestHostComponent {
@ViewChild(FilterVersionListComponent)
public componentUnderTest: FilterVersionListComponent;

filters = TestData;

compare(versions: FilterComparison): void { }
}

describe('Filter Version List Component', () => {
let fixture: ComponentFixture<TestHostComponent>;
let instance: TestHostComponent;
let list: FilterVersionListComponent;

beforeEach(() => {
TestBed.configureTestingModule({
providers: [],
imports: [
MockI18nModule,
RouterTestingModule
],
declarations: [
FilterVersionListComponent,
TestHostComponent
],
});

fixture = TestBed.createComponent(TestHostComponent);
instance = fixture.componentInstance;
list = instance.componentUnderTest;
fixture.detectChanges();
});

it('should compile', () => {
expect(list).toBeDefined();
});

describe('compareSelected', () => {
it('should emit an event with the selected filter data', () => {
spyOn(instance, 'compare');
list.selected = 'foo';
fixture.detectChanges();
list.compareSelected();
fixture.detectChanges();
expect(instance.compare).toHaveBeenCalled();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { FilterConfiguration, MetadataConfiguration } from '../model/metadata-configuration';
import { CONFIG_DATE_FORMAT } from '../configuration.values';
import { Observable } from 'rxjs';
import { FilterComparison } from '../model/compare';

@Component({
selector: 'filter-version-list',
templateUrl: './filter-version-list.component.html'
})
export class FilterVersionListComponent {

@Input() filters: FilterConfiguration;
@Output() compare: EventEmitter<FilterComparison> = new EventEmitter();

selected: string;
comparing: string;
selectedFilters$: Observable<MetadataConfiguration>;

DATE_FORMAT = CONFIG_DATE_FORMAT;

constructor() {}

compareSelected() {
const reduced = this.filters.filters.reduce((acc, l) => acc.concat(l), []);
const filtered = reduced.filter(f => f && f.resourceId === this.selected);
const type = filtered[0]['@type'];

this.compare.emit({
modelId: this.selected,
modelType: type,
models: filtered
});
}

get width(): string {
const columns = this.filters.dates.length;
return `${Math.floor(100 / (columns + 1))}`;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@
[translate]="property.name"
[ngStyle]="{'width': width}">{{ property.name }}</span>
<span *ngFor="let v of property.value"
class="d-block"
class="d-block text-truncate"
role="definition"
[ngbPopover]="v"
[openDelay]="500"
triggers="mouseenter:mouseleave"
popoverClass="popover popover-info"
[ngStyle]="{'width': width}">{{ v ? v : (v === false) ? v : '-' }}</span>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Component, ViewChild, Input } from '@angular/core';
import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';

import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
import { NgbDropdownModule, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap';
import { Property } from '../../../domain/model/property';
import { MockI18nModule } from '../../../../../testing/i18n.stub';
import { PrimitivePropertyComponent } from './primitive-property.component';
Expand Down Expand Up @@ -39,6 +39,7 @@ describe('Primitive Property Component', () => {
TestBed.configureTestingModule({
imports: [
NgbDropdownModule,
NgbPopoverModule,
MockI18nModule,
RouterTestingModule
],
Expand Down
6 changes: 5 additions & 1 deletion ui/src/app/metadata/configuration/configuration.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ import { RestoreEditComponent } from './container/restore-edit.component';
import { RestoreEditStepComponent } from './container/restore-edit-step.component';

import { IndexResolver } from './service/index-resolver.service';
import { FilterVersionListComponent } from './component/filter-version-list.component';
import { FilterCompareVersionEffects } from './effect/filter.effect';

@NgModule({
declarations: [
Expand All @@ -67,7 +69,8 @@ import { IndexResolver } from './service/index-resolver.service';
VersionOptionsComponent,
MetadataEditorComponent,
RestoreEditComponent,
RestoreEditStepComponent
RestoreEditStepComponent,
FilterVersionListComponent
],
entryComponents: [],
imports: [
Expand Down Expand Up @@ -109,6 +112,7 @@ export class MetadataConfigurationModule {
MetadataHistoryEffects,
CompareVersionEffects,
RestoreEffects,
FilterCompareVersionEffects,
VersionEffects
])
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,32 @@ <h2 class="mb-4" [ngSwitch]="type$ | async">
<metadata-configuration
[configuration]="versions$ | async"
[editable]="false"></metadata-configuration>

<div class="numbered-header d-flex justify-content-start bg-light align-items-center py-1">
<h2 class="title h4 m-0 flex-grow-1">
<span class="text ml-2" translate="label.metadata-filter">Metadata Filter</span>
</h2>
</div>
<ng-container *ngIf="!(filterCompare$ | async)">
<filter-version-list
class="d-block p-2"
[filters]="filters$ | async"
(compare)="compareFilters($event)">
</filter-version-list>
</ng-container>
<ng-container *ngIf="(filterCompare$ | async)">
<br />
<metadata-configuration
[configuration]="filterCompare$ | async"
[editable]="false"></metadata-configuration>
<div class="d-flex justify-content-end my-2">
<button class="btn btn-success" (click)="resetCompareFilters()">
<i class="fa fa-arrow-left" aria-hidden="true"></i>&nbsp;
<translate-i18n key="label.filter-versions">Filter Versions</translate-i18n>
</button>
</div>
</ng-container>

</div>
<div *ngIf="loading$ | async" class="d-flex justify-content-center">
<i class="fa fa-spinner fa-pulse fa-4x fa-fw"></i>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Component, ChangeDetectionStrategy, OnDestroy } from '@angular/core';
import { Observable, BehaviorSubject, Subscription, combineLatest } from 'rxjs';
import { Observable, BehaviorSubject, Subscription } from 'rxjs';
import { Store } from '@ngrx/store';
import { ActivatedRoute } from '@angular/router';
import { map, withLatestFrom } from 'rxjs/operators';
import { ConfigurationState, getComparisonConfigurationCount } from '../reducer';
import { CompareVersionRequest, ClearVersions, ViewChanged } from '../action/compare.action';
import { MetadataConfiguration } from '../model/metadata-configuration';
import { MetadataConfiguration, FilterConfiguration } from '../model/metadata-configuration';
import * as fromReducer from '../reducer';
import { CompareFilterVersions, ClearFilterComparison } from '../action/filter.action';
import { FilterComparison } from '../model/compare';

@Component({
selector: 'metadata-comparison',
Expand All @@ -24,6 +26,8 @@ export class MetadataComparisonComponent implements OnDestroy {
loading$: Observable<boolean> = this.store.select(fromReducer.getComparisonLoading);
limited$: Observable<boolean> = this.store.select(fromReducer.getViewChangedOnly);
sub: Subscription;
filters$: Observable<FilterConfiguration> = this.store.select(fromReducer.getComparisonFilterConfiguration);
filterCompare$: Observable<MetadataConfiguration> = this.store.select(fromReducer.getLimitedFilterComparisonConfiguration);

constructor(
private store: Store<ConfigurationState>,
Expand All @@ -45,8 +49,17 @@ export class MetadataComparisonComponent implements OnDestroy {
).subscribe(this.store);
}

compareFilters (comparison: FilterComparison) {
this.store.dispatch(new CompareFilterVersions(comparison));
}

resetCompareFilters () {
this.store.dispatch(new ClearFilterComparison());
}

ngOnDestroy(): void {
this.sub.unsubscribe();
this.store.dispatch(new ClearVersions());
this.resetCompareFilters();
}
}
Loading

0 comments on commit 0d48b13

Please sign in to comment.