Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(workspace): add intermediate view (DSP-1834) #494

Merged
merged 5 commits into from Aug 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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