Skip to content

Commit

Permalink
Merged in feature/SHIBUI-1270 (pull request #340)
Browse files Browse the repository at this point in the history
SHIBUI-1270 Implemented metadata comparison component
  • Loading branch information
rmathis committed Jul 25, 2019
2 parents 4206431 + 08ddd97 commit b6dfeef
Show file tree
Hide file tree
Showing 45 changed files with 635 additions and 142 deletions.
47 changes: 47 additions & 0 deletions ui/src/app/metadata/configuration/action/compare.action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Action } from '@ngrx/store';
import { MetadataHistory } from '../model/history';
import { MetadataVersion } from '../model/version';
import { Metadata } from '../../domain/domain.type';

export enum CompareActionTypes {
COMPARE_METADATA_REQUEST = '[Compare Version] Compare Version Request',
COMPARE_METADATA_SUCCESS = '[Compare Version] Compare Version Success',
COMPARE_METADATA_ERROR = '[Compare Version] Compare Version Error',
SET_VERSIONS = '[Compare Version] Set Versions',
CLEAR_VERSIONS = '[Compare Version] Clear Versions'
}

export class CompareVersionRequest implements Action {
readonly type = CompareActionTypes.COMPARE_METADATA_REQUEST;

constructor(public payload: string[]) { }
}

export class CompareVersionSuccess implements Action {
readonly type = CompareActionTypes.COMPARE_METADATA_SUCCESS;

constructor(public payload: Metadata[]) { }
}

export class CompareVersionError implements Action {
readonly type = CompareActionTypes.COMPARE_METADATA_ERROR;

constructor(public payload: any) { }
}

export class SetMetadataVersions implements Action {
readonly type = CompareActionTypes.SET_VERSIONS;

constructor(public payload: Metadata[]) { }
}

export class ClearVersions implements Action {
readonly type = CompareActionTypes.CLEAR_VERSIONS;
}

export type CompareActionsUnion =
| CompareVersionRequest
| CompareVersionSuccess
| CompareVersionError
| SetMetadataVersions
| ClearVersions;
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
<div>
<ng-container *ngIf="property.items.type === 'object'">
<div class="p-2" role="term" [translate]="property.name">{{ property.name }}</div>
<div class="p-2" *ngIf="property.value && property.value.length">
<div *ngFor="let value of property.value; let i = index;" class="mb-2 bg-lighter">
<div *ngFor="let prop of getKeys(property.items); let n = index;"
class="d-flex p-2">
<div class="w-50">
<span [class.invisible]="n">{{ i + 1 }}.&nbsp;</span>
<span [translate]="property.items.properties[prop].title">{{ property.items.properties[prop].title }}</span>
<div *ngFor="let item of range; let i = index;" class="p-2 bg-lighter border-top">
<div *ngFor="let prop of getKeys(property.items); let n = index;" class="d-flex py-2">
<div [ngStyle]="{'width': width}">
<span [translate]="property.items.properties[prop].title">{{ property.items.properties[prop].title }}</span>
</div>
<ng-container *ngFor="let version of property.value">
<div *ngIf="version[i]"
[ngbPopover]="version[i][prop]"
triggers="mouseenter:mouseleave"
container="body"
placement="left"
[ngStyle]="{'width': width}">
{{ version[i][prop] }}
</div>
<div class="w-50" [ngbPopover]="value[prop]" triggers="mouseenter:mouseleave" container="body" placement="left">
{{ value[prop] }}
<div *ngIf="!version[i]" [ngStyle]="{'width': width}">
&mdash;
</div>
</div>
</ng-container>
</div>
</div>
</ng-container>
Expand All @@ -25,12 +31,14 @@
</ng-container>
<ng-container *ngSwitchDefault>
<div *ngFor="let attr of attributeList$ | async" class="d-flex justify-content-between border-bottom border-light">
<span class="w-50 p-2" role="term" [translate]="attr.label">{{ attr.label }}</span>
<div class="w-50 p-2">
<span *ngIf="property.value && property.value.indexOf(attr.key) > -1" translate="value.true">
<span class="p-2" role="term" [translate]="attr.label" [ngStyle]="{'width': width}">{{ attr.label }}</span>
<div *ngFor="let v of property.value"
class="p-2"
[ngStyle]="{'width': width}">
<span *ngIf="v && v.indexOf(attr.key) > -1" translate="value.true">
true
</span>
<span *ngIf="!property.value || !(property.value.indexOf(attr.key) > -1)" translate="value.false">
<span *ngIf="!v || !(v.indexOf(attr.key) > -1)" translate="value.false">
false
</span>
</div>
Expand All @@ -40,12 +48,14 @@
</div>
<ng-template #listref>
<div class="d-flex border-bottom border-light">
<span class="w-50 p-2" role="term" [translate]="property.name">{{ property.name }}</span>
<p class="text-secondary w-50 p-2" *ngIf="!property.value || !property.value.length">&mdash;</p>
<ul class="list-unstyled w-50 py-2" *ngIf="property.value && property.value.length">
<li *ngFor="let item of property.value">
{{ item }}
</li>
</ul>
<span class="p-2" role="term" [translate]="property.name" [ngStyle]="{'width': width}">{{ property.name }}</span>
<ng-container *ngFor="let v of property.value">
<p [ngStyle]="{'width': width}" class="text-secondary p-2" *ngIf="!v || !v.length">&mdash;</p>
<ul [ngStyle]="{'width': width}" class="list-unstyled py-2" *ngIf="v && v.length">
<li *ngFor="let item of v">
{{ item }}
</li>
</ul>
</ng-container>
</div>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ class TestHostComponent {
@ViewChild(ArrayPropertyComponent)
public componentUnderTest: ArrayPropertyComponent;

property: Property = getStepProperty(SCHEMA.properties.list, {
property: Property = getStepProperty(SCHEMA.properties.list, [{
name: 'foo',
type: 'baz',
description: 'foo bar baz',
list: []
}, SCHEMA.definitions);
}], SCHEMA.definitions);

setProperty(property: Property): void {
this.property = property;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, Input } from '@angular/core';
import { Component, Input, OnChanges } from '@angular/core';
import { Property } from '../../domain/model/property';
import { Observable, of } from 'rxjs';
import { AttributesService } from '../../domain/service/attributes.service';
Expand All @@ -10,15 +10,22 @@ import { ConfigurationPropertyComponent } from './configuration-property.compone
styleUrls: []
})

export class ArrayPropertyComponent extends ConfigurationPropertyComponent {
export class ArrayPropertyComponent extends ConfigurationPropertyComponent implements OnChanges {
@Input() property: Property;

range = [];

constructor(
private attrService: AttributesService
) {
super();
}

ngOnChanges(): void {
const keys = this.property.value.reduce((val, version) => version ? version.length > val ? version.length : val : val, 0);
this.range = [...Array(keys).keys()];
}

get attributeList$(): Observable<{ key: string, label: string }[]> {
if (this.property.widget && this.property.widget.hasOwnProperty('data')) {
return of(this.property.widget.data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { Property } from '../../domain/model/property';

@Component({
selector: 'configuration-property',
template: `{{ property | json }}`,
styleUrls: []
template: `{{ property | json }}`
})

export class ConfigurationPropertyComponent {
@Input() property: Property;
@Input() columns = 1;

constructor() { }

Expand All @@ -19,5 +19,9 @@ export class ConfigurationPropertyComponent {
getItemType(items: Property): string {
return items.widget ? items.widget.id : 'default';
}

get width(): string {
return `${ Math.floor(100 / (this.columns + 1)) }%`;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,14 @@ describe('Metadata History List Component', () => {
expect(instance.restore).toHaveBeenCalledWith(selected);
});
});

describe('toggleVersionSelected method', () => {
it('should add or remove the selected version', () => {
list.toggleVersionSelected(TestData.versions[0]);
fixture.detectChanges();
list.toggleVersionSelected(TestData.versions[0]);
fixture.detectChanges();
expect(list.selected.length).toBe(0);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
<div *ngIf="configuration">
<section *ngFor="let section of configuration.sections; let i = index;">
<section *ngFor="let section of configuration.sections; let i = index;" class="mb-4">
<div class="config-group">
<div class="numbered-header d-flex justify-content-start bg-light align-items-center">
<h2 class="title h4 m-0 flex-grow-1">
<span class="d-inline-block px-2 py-1 mr-2 mb-0 h4 number border border-secondary bg-white rounded-lg"><span *ngIf="i + 1 < 10">0</span>{{ i + 1 }}</span>
<span class="d-inline-block px-2 py-1 mr-2 mb-0 h4 number border border-secondary bg-white rounded-lg">
<span *ngIf="i + 1 < 10">0</span>{{ i + 1 }}
</span>
<span class="text">{{ section.label | translate }}</span>
</h2>
<div class="actions px-2">
<div class="actions px-2" *ngIf="configuration.dates.length === 1">
<button class="btn btn-link edit-link change-view" (click)="edit(section.id)">
<i class="fa fa-edit"></i>&nbsp;
<span translate="action.edit">Edit</span>
</button>
</div>
</div>
<div class="d-flex border-bottom border-light border-2 p-2">
<strong class="w-50" translate="label.option">Option</strong>
<strong class="w-50" translate="label.value">Value</strong>
<strong [ngStyle]="{'width': width}" translate="label.option">Option</strong>
<strong *ngFor="let date of configuration.dates" [ngStyle]="{'width': width}">
<translate-i18n key="label.value" *ngIf="configuration.dates.length <= 1">Value</translate-i18n>
<span *ngIf="configuration.dates.length > 1">{{ date | date:'medium' }}</span>
</strong>
</div>
<object-property class="d-block" *ngIf="section" [property]="section"></object-property>
<object-property
class="d-block"
*ngIf="section"
[property]="section"
[columns]="configuration.dates.length">
</object-property>
</div>
</section>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
import { MetadataConfiguration } from '../model/metadata-configuration';
import { Property } from '../../domain/model/property';
import { MockI18nModule } from '../../../../testing/i18n.stub';
import { Router } from '@angular/router';

@Component({
selector: 'object-property',
template: ``
})
class ObjectPropertyComponent {
@Input() property: Property;
@Input() columns = 1;
}

@Component({
Expand All @@ -25,14 +27,18 @@ class TestHostComponent {
@ViewChild(MetadataConfigurationComponent)
public componentUnderTest: MetadataConfigurationComponent;

configuration: MetadataConfiguration = {sections: []};
configuration: MetadataConfiguration = {
dates: [],
sections: []
};
}

describe('Metadata Configuration Component', () => {

let fixture: ComponentFixture<TestHostComponent>;
let instance: TestHostComponent;
let app: MetadataConfigurationComponent;
let router: Router;

beforeEach(async(() => {
TestBed.configureTestingModule({
Expand All @@ -51,10 +57,36 @@ describe('Metadata Configuration Component', () => {
fixture = TestBed.createComponent(TestHostComponent);
instance = fixture.componentInstance;
app = instance.componentUnderTest;
router = TestBed.get(Router);
fixture.detectChanges();
}));

it('should accept a configuration input', async(() => {
expect(app).toBeTruthy();
}));

describe('edit method', () => {
it('should call router.navigate', () => {
spyOn(router, 'navigate');
app.edit('foo');
expect(router.navigate).toHaveBeenCalled();
});
});

describe('width getter', () => {
it('should default to 100%', () => {
expect(app.width).toBe('100%');
});
it('should calculate the width based on dates', () => {
instance.configuration = {
...instance.configuration,
dates: [
new Date().toISOString(),
new Date().toISOString()
]
};
fixture.detectChanges();
expect(app.width).toBe('33%');
});
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Component, ChangeDetectionStrategy, Input } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { MetadataConfiguration } from '../model/metadata-configuration';
import { Property } from '../../domain/model/property';
import { Observable, of } from 'rxjs';

@Component({
selector: 'metadata-configuration',
Expand All @@ -19,4 +21,9 @@ export class MetadataConfigurationComponent {
edit(id: string): void {
this.router.navigate(['../', 'edit', id], { relativeTo: this.activatedRoute.parent });
}

get width(): string {
const columns = this.configuration.dates.length;
return `${Math.floor(100 / (columns + 1)) }%`;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<ng-container *ngFor="let prop of property.properties">
<ng-container [ngSwitch]="prop.type">
<primitive-property *ngSwitchDefault [property]="prop"></primitive-property>
<array-property *ngSwitchCase="'array'" [property]="prop"></array-property>
<object-property *ngSwitchCase="'object'" [property]="prop"></object-property>
<primitive-property *ngSwitchDefault [property]="prop" [columns]="columns"></primitive-property>
<array-property *ngSwitchCase="'array'" [property]="prop" [columns]="columns"></array-property>
<object-property *ngSwitchCase="'object'" [property]="prop" [columns]="columns"></object-property>
</ng-container>
</ng-container>
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<div *ngIf="property.name" class="d-flex border-bottom border-light p-2">
<span class="w-50 d-block" role="term" [translate]="property.name">{{ property.name }}</span>
<span class="w-50 d-block"
role="definition">{{ property.value || property.value === false ? property.value : '-' }}</span>
<span class="d-block"
role="term"
[translate]="property.name"
[ngStyle]="{'width': width}">{{ property.name }}</span>
<span *ngFor="let v of property.value"
class="d-block"
role="definition"
[ngStyle]="{'width': width}">{{ v ? v : (v === false) ? v : '-' }}</span>
</div>
Loading

0 comments on commit b6dfeef

Please sign in to comment.