Skip to content

Commit

Permalink
feat(workspace): add intermediate view (DSP-1834) (#494)
Browse files Browse the repository at this point in the history
* feat(workspace): add intermediate view (DSP-1834)

* test(workspace): test intermediate view

* refactor(workspace): clean up code

* test(workspace): bug fix in tests
  • Loading branch information
kilchenmann committed Aug 4, 2021
1 parent 5505d4f commit d0e475a
Show file tree
Hide file tree
Showing 7 changed files with 342 additions and 10 deletions.
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Expand Up @@ -96,6 +96,7 @@ import { SelectResourceClassComponent } from './workspace/resource/resource-inst
import { ResourceComponent } from './workspace/resource/resource.component';
import { ResultsComponent } from './workspace/results/results.component';
import { AudioComponent } from './workspace/resource/representation/audio/audio.component';
import { IntermediateComponent } from './workspace/intermediate/intermediate.component';

// translate: AoT requires an exported function for factories
export function httpLoaderFactory(httpClient: HttpClient) {
Expand Down Expand Up @@ -178,6 +179,7 @@ export function httpLoaderFactory(httpClient: HttpClient) {
UsersListComponent,
VisualizerComponent,
AudioComponent,
IntermediateComponent,
],
imports: [
AppRoutingModule,
Expand Down
41 changes: 41 additions & 0 deletions src/app/workspace/intermediate/intermediate.component.html
@@ -0,0 +1,41 @@
<div class="card-container" *ngIf="resources">
<div class="card front">
<div class="mock title"></div>
<div class="mock title"></div>
<div class="mock content">
<p class="count">{{resources.count}}</p>
<p class="text">{{resources.count | i18nPlural: itemPluralMapping['resource']}} Selected</p>
</div>
<div class="action">
<span class="fill-remaining-space"></span>
<span>
<!-- link button to create a link resource (linkObj); TODO: add function to create link object -->
<!-- at the moment the button is disabled because of the missing functionality; it needs a "span-tag-hack" to display the tooltip -->
<span matTooltip="Create a link object from this selection | Currently not implemented"
[matTooltipPosition]="'above'">
<button mat-mini-fab color="primary"
class="link"
matTooltip="Create a link object from this selection"
[matTooltipPosition]="'above'"
[disabled]="true"
(click)="action.emit('link')">
<mat-icon>link</mat-icon>
</button>
</span>
<!-- compare button to compare more than two resources -->
<button mat-mini-fab color="primary"
class="compare"
matTooltip="Compare the selected resources"
[matTooltipPosition]="'above'"
[disabled]="resources.count < 2"
(click)="action.emit('compare')">
<mat-icon>compare_arrows</mat-icon>
</button>
</span>
<span class="fill-remaining-space"></span>
</div>
</div>
<div *ngIf="resources.count > 1" class="card background two"></div>
<div *ngIf="resources.count > 2" class="card background three"></div>
<div *ngIf="resources.count > 3" class="card background more"></div>
</div>
75 changes: 75 additions & 0 deletions src/app/workspace/intermediate/intermediate.component.scss
@@ -0,0 +1,75 @@
@import '../../../assets/style/config';
@import '../../../assets/style/mixins';

.card-container {
position: relative;
width: 18em;
margin: 4em auto;
}

.card {
height: 20.5em;
width: 20em;
position: absolute;
border-radius: $border-radius;
background: #cecece;
padding: 32px 16px;
box-shadow: 1px 1px 7px rgba(0,0,0,.65);

&.front {
z-index: 10;
}

&.background {
z-index: -1;

&.two {
transform: rotateZ(4deg);
}

&.three {
transform: rotateZ(-4deg);
}

&.more {
transform: rotateZ(-8deg);
}

}

.mock {
background: rgba(0,0,0,.375);
min-height: 1em;
color: $primary_100;

&.title {
width: 70%;
margin: 8px 0;
}

&.content {
height: 14em;
margin-top: -3em;
text-align: center;

.count {
font-size: 4em;
line-height:0.75em;
margin-bottom:0;
padding-top: 72px;
}
}
}

.action {
height: 2em;
display: inline-flex;
margin: 1em 0;
width: 100%;

button {
margin: 0 16px;
}

}
}
178 changes: 178 additions & 0 deletions src/app/workspace/intermediate/intermediate.component.spec.ts
@@ -0,0 +1,178 @@
import { Component, DebugElement, ViewChild } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { By } from '@angular/platform-browser';
import { FilteredResouces } from '@dasch-swiss/dsp-ui';
import { IntermediateComponent } from './intermediate.component';

/**
* test host component to simulate parent component
*/
@Component({
template: '<app-intermediate #intermediateView [resources]="resources"></app-intermediate>'
})
class OneSelectedResourcesComponent {

@ViewChild('intermediateView') intermediateComponent: IntermediateComponent;

resources: FilteredResouces = {
'count': 1,
'resListIndex': [1],
'resIds': [
'http://rdfh.ch/0803/83616f8d8501'
],
'selectionType': 'multiple'
};

constructor() { }

}

/**
* test host component to simulate parent component
*/
@Component({
template: '<app-intermediate #intermediateView [resources]="resources"></app-intermediate>'
})
class ThreeSelectedResourcesComponent {

@ViewChild('intermediateView') intermediateComponent: IntermediateComponent;

resources: FilteredResouces = {
'count': 3,
'resListIndex': [3, 2, 1],
'resIds': [
'http://rdfh.ch/0803/83616f8d8501',
'http://rdfh.ch/0803/71e0b9958a01',
'http://rdfh.ch/0803/683d5cd26f01'
],
'selectionType': 'multiple'
};

constructor() { }

}

describe('IntermediateComponent', () => {

let host1Component: OneSelectedResourcesComponent;
let host1Fixture: ComponentFixture<OneSelectedResourcesComponent>;

let host3Component: ThreeSelectedResourcesComponent;
let host3Fixture: ComponentFixture<ThreeSelectedResourcesComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
IntermediateComponent,
OneSelectedResourcesComponent,
ThreeSelectedResourcesComponent
],
imports: [
MatButtonModule,
MatIconModule,
MatTooltipModule
]
})
.compileComponents();
});

beforeEach(() => {
host1Fixture = TestBed.createComponent(OneSelectedResourcesComponent);
host1Component = host1Fixture.componentInstance;
host1Fixture.detectChanges();

expect(host1Component).toBeTruthy();

host3Fixture = TestBed.createComponent(ThreeSelectedResourcesComponent);
host3Component = host3Fixture.componentInstance;
host3Fixture.detectChanges();

expect(host3Component).toBeTruthy();

});

describe('One selected resource', () => {

it('expect count to be "1" and text to be "Resource Selected', () => {
expect(host1Component.intermediateComponent).toBeTruthy();
expect(host1Component.intermediateComponent.resources).toBeDefined();

const hostCompDe = host1Fixture.debugElement;

const count: DebugElement = hostCompDe.query(By.css('.count'));
expect(count.nativeElement.innerText).toEqual('1');
const text: DebugElement = hostCompDe.query(By.css('.text'));
expect(text.nativeElement.innerText).toEqual('Resource Selected');

});

it('expect compare button to be disabled', () => {
expect(host1Component.intermediateComponent).toBeTruthy();
expect(host1Component.intermediateComponent.resources).toBeDefined();

const hostCompDe = host1Fixture.debugElement;

const button: DebugElement = hostCompDe.query(By.css('.compare'));
expect(button.nativeElement.disabled).toBeTruthy();
});

it('expect no card stack', () => {
expect(host1Component.intermediateComponent).toBeTruthy();
expect(host1Component.intermediateComponent.resources).toBeDefined();

const hostCompDe = host1Fixture.debugElement;

const twoCards: DebugElement = hostCompDe.query(By.css('.two'));
expect(twoCards).toBeFalsy();
const threeCards: DebugElement = hostCompDe.query(By.css('.three'));
expect(threeCards).toBeFalsy();
const moreCards: DebugElement = hostCompDe.query(By.css('.more'));
expect(moreCards).toBeFalsy();
});

});

describe('Three selected resources', () => {

it('expect count to be "3" and text to be "Resources Selected', () => {
expect(host3Component.intermediateComponent).toBeTruthy();
expect(host3Component.intermediateComponent.resources).toBeDefined();

const hostCompDe = host3Fixture.debugElement;

const count: DebugElement = hostCompDe.query(By.css('.count'));
expect(count.nativeElement.innerText).toEqual('3');
const text: DebugElement = hostCompDe.query(By.css('.text'));
expect(text.nativeElement.innerText).toEqual('Resources Selected');

});

it('expect compare button to be enabled', () => {
expect(host3Component.intermediateComponent).toBeTruthy();
expect(host3Component.intermediateComponent.resources).toBeDefined();

const hostCompDe = host3Fixture.debugElement;

const button: DebugElement = hostCompDe.query(By.css('.compare'));
expect(button.nativeElement.disabled).toBeFalsy();
});

it('expect card stack of more than 2', () => {
expect(host3Component.intermediateComponent).toBeTruthy();
expect(host3Component.intermediateComponent.resources).toBeDefined();

const hostCompDe = host3Fixture.debugElement;

const twoCards: DebugElement = hostCompDe.query(By.css('.two'));
expect(twoCards.nativeElement).toBeDefined();
const threeCards: DebugElement = hostCompDe.query(By.css('.three'));
expect(threeCards.nativeElement).toBeDefined();
const moreCards: DebugElement = hostCompDe.query(By.css('.more'));
expect(moreCards).toBeFalsy();
});
});

});
27 changes: 27 additions & 0 deletions src/app/workspace/intermediate/intermediate.component.ts
@@ -0,0 +1,27 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FilteredResouces } from '@dasch-swiss/dsp-ui';

@Component({
selector: 'app-intermediate',
templateUrl: './intermediate.component.html',
styleUrls: ['./intermediate.component.scss']
})
export class IntermediateComponent implements OnInit {

@Input() resources: FilteredResouces;

@Output() action: EventEmitter<string> = new EventEmitter<string>();

// i18n plural mapping
itemPluralMapping = {
resource: {
'=1': 'Resource',
other: 'Resources'
}
};

constructor() { }

ngOnInit(): void { }

}
17 changes: 11 additions & 6 deletions src/app/workspace/results/results.component.html
Expand Up @@ -10,13 +10,18 @@
</as-split-area>
<as-split-area [size]="60" *ngIf="resourceIri">

<!-- single resource view -->
<app-resource [resourceIri]="resourceIri" *ngIf="!multipleSelection"></app-resource>
<div [ngSwitch]="viewMode">
<!-- single resource view -->
<app-resource *ngSwitchCase="'single'" [resourceIri]="resourceIri"></app-resource>

<!-- multiple resources view / comparison viewer -->
<dsp-multiple-resources-view *ngIf="multipleSelection" [noOfResources]="multipleResources.count"
[resourceIds]="multipleResources.resIds">
</dsp-multiple-resources-view>
<!-- intermediate view -->
<app-intermediate *ngSwitchCase="'intermediate'" [resources]="multipleResources" (action)="viewMode=$event"></app-intermediate>

<!-- multiple resources view / comparison viewer -->
<dsp-multiple-resources-view *ngSwitchCase="'compare'" [noOfResources]="multipleResources.count"
[resourceIds]="multipleResources.resIds">
</dsp-multiple-resources-view>
</div>
</as-split-area>
</as-split>

Expand Down

0 comments on commit d0e475a

Please sign in to comment.