Skip to content

Commit d0e475a

Browse files
authored
feat(workspace): add intermediate view (DSP-1834) (#494)
* feat(workspace): add intermediate view (DSP-1834) * test(workspace): test intermediate view * refactor(workspace): clean up code * test(workspace): bug fix in tests
1 parent 5505d4f commit d0e475a

7 files changed

Lines changed: 342 additions & 10 deletions

File tree

‎src/app/app.module.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ import { SelectResourceClassComponent } from './workspace/resource/resource-inst
9696
import { ResourceComponent } from './workspace/resource/resource.component';
9797
import { ResultsComponent } from './workspace/results/results.component';
9898
import { AudioComponent } from './workspace/resource/representation/audio/audio.component';
99+
import { IntermediateComponent } from './workspace/intermediate/intermediate.component';
99100

100101
// translate: AoT requires an exported function for factories
101102
export function httpLoaderFactory(httpClient: HttpClient) {
@@ -178,6 +179,7 @@ export function httpLoaderFactory(httpClient: HttpClient) {
178179
UsersListComponent,
179180
VisualizerComponent,
180181
AudioComponent,
182+
IntermediateComponent,
181183
],
182184
imports: [
183185
AppRoutingModule,
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<div class="card-container" *ngIf="resources">
2+
<div class="card front">
3+
<div class="mock title"></div>
4+
<div class="mock title"></div>
5+
<div class="mock content">
6+
<p class="count">{{resources.count}}</p>
7+
<p class="text">{{resources.count | i18nPlural: itemPluralMapping['resource']}} Selected</p>
8+
</div>
9+
<div class="action">
10+
<span class="fill-remaining-space"></span>
11+
<span>
12+
<!-- link button to create a link resource (linkObj); TODO: add function to create link object -->
13+
<!-- at the moment the button is disabled because of the missing functionality; it needs a "span-tag-hack" to display the tooltip -->
14+
<span matTooltip="Create a link object from this selection | Currently not implemented"
15+
[matTooltipPosition]="'above'">
16+
<button mat-mini-fab color="primary"
17+
class="link"
18+
matTooltip="Create a link object from this selection"
19+
[matTooltipPosition]="'above'"
20+
[disabled]="true"
21+
(click)="action.emit('link')">
22+
<mat-icon>link</mat-icon>
23+
</button>
24+
</span>
25+
<!-- compare button to compare more than two resources -->
26+
<button mat-mini-fab color="primary"
27+
class="compare"
28+
matTooltip="Compare the selected resources"
29+
[matTooltipPosition]="'above'"
30+
[disabled]="resources.count < 2"
31+
(click)="action.emit('compare')">
32+
<mat-icon>compare_arrows</mat-icon>
33+
</button>
34+
</span>
35+
<span class="fill-remaining-space"></span>
36+
</div>
37+
</div>
38+
<div *ngIf="resources.count > 1" class="card background two"></div>
39+
<div *ngIf="resources.count > 2" class="card background three"></div>
40+
<div *ngIf="resources.count > 3" class="card background more"></div>
41+
</div>
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
@import '../../../assets/style/config';
2+
@import '../../../assets/style/mixins';
3+
4+
.card-container {
5+
position: relative;
6+
width: 18em;
7+
margin: 4em auto;
8+
}
9+
10+
.card {
11+
height: 20.5em;
12+
width: 20em;
13+
position: absolute;
14+
border-radius: $border-radius;
15+
background: #cecece;
16+
padding: 32px 16px;
17+
box-shadow: 1px 1px 7px rgba(0,0,0,.65);
18+
19+
&.front {
20+
z-index: 10;
21+
}
22+
23+
&.background {
24+
z-index: -1;
25+
26+
&.two {
27+
transform: rotateZ(4deg);
28+
}
29+
30+
&.three {
31+
transform: rotateZ(-4deg);
32+
}
33+
34+
&.more {
35+
transform: rotateZ(-8deg);
36+
}
37+
38+
}
39+
40+
.mock {
41+
background: rgba(0,0,0,.375);
42+
min-height: 1em;
43+
color: $primary_100;
44+
45+
&.title {
46+
width: 70%;
47+
margin: 8px 0;
48+
}
49+
50+
&.content {
51+
height: 14em;
52+
margin-top: -3em;
53+
text-align: center;
54+
55+
.count {
56+
font-size: 4em;
57+
line-height:0.75em;
58+
margin-bottom:0;
59+
padding-top: 72px;
60+
}
61+
}
62+
}
63+
64+
.action {
65+
height: 2em;
66+
display: inline-flex;
67+
margin: 1em 0;
68+
width: 100%;
69+
70+
button {
71+
margin: 0 16px;
72+
}
73+
74+
}
75+
}
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
import { Component, DebugElement, ViewChild } from '@angular/core';
2+
import { ComponentFixture, TestBed } from '@angular/core/testing';
3+
import { MatButtonModule } from '@angular/material/button';
4+
import { MatIconModule } from '@angular/material/icon';
5+
import { MatTooltipModule } from '@angular/material/tooltip';
6+
import { By } from '@angular/platform-browser';
7+
import { FilteredResouces } from '@dasch-swiss/dsp-ui';
8+
import { IntermediateComponent } from './intermediate.component';
9+
10+
/**
11+
* test host component to simulate parent component
12+
*/
13+
@Component({
14+
template: '<app-intermediate #intermediateView [resources]="resources"></app-intermediate>'
15+
})
16+
class OneSelectedResourcesComponent {
17+
18+
@ViewChild('intermediateView') intermediateComponent: IntermediateComponent;
19+
20+
resources: FilteredResouces = {
21+
'count': 1,
22+
'resListIndex': [1],
23+
'resIds': [
24+
'http://rdfh.ch/0803/83616f8d8501'
25+
],
26+
'selectionType': 'multiple'
27+
};
28+
29+
constructor() { }
30+
31+
}
32+
33+
/**
34+
* test host component to simulate parent component
35+
*/
36+
@Component({
37+
template: '<app-intermediate #intermediateView [resources]="resources"></app-intermediate>'
38+
})
39+
class ThreeSelectedResourcesComponent {
40+
41+
@ViewChild('intermediateView') intermediateComponent: IntermediateComponent;
42+
43+
resources: FilteredResouces = {
44+
'count': 3,
45+
'resListIndex': [3, 2, 1],
46+
'resIds': [
47+
'http://rdfh.ch/0803/83616f8d8501',
48+
'http://rdfh.ch/0803/71e0b9958a01',
49+
'http://rdfh.ch/0803/683d5cd26f01'
50+
],
51+
'selectionType': 'multiple'
52+
};
53+
54+
constructor() { }
55+
56+
}
57+
58+
describe('IntermediateComponent', () => {
59+
60+
let host1Component: OneSelectedResourcesComponent;
61+
let host1Fixture: ComponentFixture<OneSelectedResourcesComponent>;
62+
63+
let host3Component: ThreeSelectedResourcesComponent;
64+
let host3Fixture: ComponentFixture<ThreeSelectedResourcesComponent>;
65+
66+
beforeEach(async () => {
67+
await TestBed.configureTestingModule({
68+
declarations: [
69+
IntermediateComponent,
70+
OneSelectedResourcesComponent,
71+
ThreeSelectedResourcesComponent
72+
],
73+
imports: [
74+
MatButtonModule,
75+
MatIconModule,
76+
MatTooltipModule
77+
]
78+
})
79+
.compileComponents();
80+
});
81+
82+
beforeEach(() => {
83+
host1Fixture = TestBed.createComponent(OneSelectedResourcesComponent);
84+
host1Component = host1Fixture.componentInstance;
85+
host1Fixture.detectChanges();
86+
87+
expect(host1Component).toBeTruthy();
88+
89+
host3Fixture = TestBed.createComponent(ThreeSelectedResourcesComponent);
90+
host3Component = host3Fixture.componentInstance;
91+
host3Fixture.detectChanges();
92+
93+
expect(host3Component).toBeTruthy();
94+
95+
});
96+
97+
describe('One selected resource', () => {
98+
99+
it('expect count to be "1" and text to be "Resource Selected', () => {
100+
expect(host1Component.intermediateComponent).toBeTruthy();
101+
expect(host1Component.intermediateComponent.resources).toBeDefined();
102+
103+
const hostCompDe = host1Fixture.debugElement;
104+
105+
const count: DebugElement = hostCompDe.query(By.css('.count'));
106+
expect(count.nativeElement.innerText).toEqual('1');
107+
const text: DebugElement = hostCompDe.query(By.css('.text'));
108+
expect(text.nativeElement.innerText).toEqual('Resource Selected');
109+
110+
});
111+
112+
it('expect compare button to be disabled', () => {
113+
expect(host1Component.intermediateComponent).toBeTruthy();
114+
expect(host1Component.intermediateComponent.resources).toBeDefined();
115+
116+
const hostCompDe = host1Fixture.debugElement;
117+
118+
const button: DebugElement = hostCompDe.query(By.css('.compare'));
119+
expect(button.nativeElement.disabled).toBeTruthy();
120+
});
121+
122+
it('expect no card stack', () => {
123+
expect(host1Component.intermediateComponent).toBeTruthy();
124+
expect(host1Component.intermediateComponent.resources).toBeDefined();
125+
126+
const hostCompDe = host1Fixture.debugElement;
127+
128+
const twoCards: DebugElement = hostCompDe.query(By.css('.two'));
129+
expect(twoCards).toBeFalsy();
130+
const threeCards: DebugElement = hostCompDe.query(By.css('.three'));
131+
expect(threeCards).toBeFalsy();
132+
const moreCards: DebugElement = hostCompDe.query(By.css('.more'));
133+
expect(moreCards).toBeFalsy();
134+
});
135+
136+
});
137+
138+
describe('Three selected resources', () => {
139+
140+
it('expect count to be "3" and text to be "Resources Selected', () => {
141+
expect(host3Component.intermediateComponent).toBeTruthy();
142+
expect(host3Component.intermediateComponent.resources).toBeDefined();
143+
144+
const hostCompDe = host3Fixture.debugElement;
145+
146+
const count: DebugElement = hostCompDe.query(By.css('.count'));
147+
expect(count.nativeElement.innerText).toEqual('3');
148+
const text: DebugElement = hostCompDe.query(By.css('.text'));
149+
expect(text.nativeElement.innerText).toEqual('Resources Selected');
150+
151+
});
152+
153+
it('expect compare button to be enabled', () => {
154+
expect(host3Component.intermediateComponent).toBeTruthy();
155+
expect(host3Component.intermediateComponent.resources).toBeDefined();
156+
157+
const hostCompDe = host3Fixture.debugElement;
158+
159+
const button: DebugElement = hostCompDe.query(By.css('.compare'));
160+
expect(button.nativeElement.disabled).toBeFalsy();
161+
});
162+
163+
it('expect card stack of more than 2', () => {
164+
expect(host3Component.intermediateComponent).toBeTruthy();
165+
expect(host3Component.intermediateComponent.resources).toBeDefined();
166+
167+
const hostCompDe = host3Fixture.debugElement;
168+
169+
const twoCards: DebugElement = hostCompDe.query(By.css('.two'));
170+
expect(twoCards.nativeElement).toBeDefined();
171+
const threeCards: DebugElement = hostCompDe.query(By.css('.three'));
172+
expect(threeCards.nativeElement).toBeDefined();
173+
const moreCards: DebugElement = hostCompDe.query(By.css('.more'));
174+
expect(moreCards).toBeFalsy();
175+
});
176+
});
177+
178+
});
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
2+
import { FilteredResouces } from '@dasch-swiss/dsp-ui';
3+
4+
@Component({
5+
selector: 'app-intermediate',
6+
templateUrl: './intermediate.component.html',
7+
styleUrls: ['./intermediate.component.scss']
8+
})
9+
export class IntermediateComponent implements OnInit {
10+
11+
@Input() resources: FilteredResouces;
12+
13+
@Output() action: EventEmitter<string> = new EventEmitter<string>();
14+
15+
// i18n plural mapping
16+
itemPluralMapping = {
17+
resource: {
18+
'=1': 'Resource',
19+
other: 'Resources'
20+
}
21+
};
22+
23+
constructor() { }
24+
25+
ngOnInit(): void { }
26+
27+
}

‎src/app/workspace/results/results.component.html‎

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,18 @@
1010
</as-split-area>
1111
<as-split-area [size]="60" *ngIf="resourceIri">
1212

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

16-
<!-- multiple resources view / comparison viewer -->
17-
<dsp-multiple-resources-view *ngIf="multipleSelection" [noOfResources]="multipleResources.count"
18-
[resourceIds]="multipleResources.resIds">
19-
</dsp-multiple-resources-view>
17+
<!-- intermediate view -->
18+
<app-intermediate *ngSwitchCase="'intermediate'" [resources]="multipleResources" (action)="viewMode=$event"></app-intermediate>
19+
20+
<!-- multiple resources view / comparison viewer -->
21+
<dsp-multiple-resources-view *ngSwitchCase="'compare'" [noOfResources]="multipleResources.count"
22+
[resourceIds]="multipleResources.resIds">
23+
</dsp-multiple-resources-view>
24+
</div>
2025
</as-split-area>
2126
</as-split>
2227

0 commit comments

Comments
 (0)