Skip to content

Commit d34691a

Browse files
refactor(LibraryProjectDetailsComponent): Convert to standalone (#2125)
1 parent fc95e60 commit d34691a

File tree

5 files changed

+236
-237
lines changed

5 files changed

+236
-237
lines changed

src/app/modules/library/library-project-details/library-project-details.component.html

Lines changed: 128 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,22 @@
66
<div class="flex flex-col">
77
<div class="mat-mdc-card-title mat-body-1">{{ project.metadata.title }}</div>
88
<div class="mat-mdc-card-subtitle mat-caption">
9-
<div *ngIf="project.metadata.grades.length || project.metadata.totalTime">
10-
<ng-container *ngIf="project.metadata.grades.length" i18n>Grade level:</ng-container>
11-
<span *ngFor="let g of project.metadata.grades; let isLast = last">
12-
{{ g }}{{ isLast ? '' : ', ' }}</span
13-
>
14-
<ng-container *ngIf="project.metadata.grades.length && project.metadata.totalTime"
15-
>&nbsp;|&nbsp;</ng-container
16-
>
17-
<ng-container *ngIf="project.metadata.totalTime" i18n
18-
>Duration: {{ project.metadata.totalTime }}</ng-container
19-
>
20-
</div>
9+
@if (project.metadata.grades.length || project.metadata.totalTime) {
10+
<div>
11+
@if (project.metadata.grades.length) {
12+
<span i18n>Grade level:</span>
13+
}
14+
@for (grade of project.metadata.grades; track grade; let last = $last) {
15+
<span>{{ grade }}{{ last ? '' : ', ' }}</span>
16+
}
17+
@if (project.metadata.grades.length && project.metadata.totalTime) {
18+
&nbsp;|&nbsp;
19+
}
20+
@if (project.metadata.totalTime) {
21+
<ng-container i18n>Duration: {{ project.metadata.totalTime }}</ng-container>
22+
}
23+
</div>
24+
}
2125
<div>
2226
<ng-container i18n>Unit ID: {{ project.id }}</ng-container>
2327
</div>
@@ -27,112 +31,130 @@
2731
</div>
2832
</div>
2933
<span class="flex-auto"></span>
30-
<app-library-project-menu
31-
*ngIf="isTeacher && project.wiseVersion !== 4"
32-
[project]="project"
33-
[isRun]="isRunProject"
34-
/>
34+
@if (isTeacher && project.wiseVersion !== 4) {
35+
<app-library-project-menu [project]="project" [isRun]="isRunProject" />
36+
}
3537
</div>
3638
<div class="info-block">
3739
<div class="details">
38-
<p *ngIf="project.wiseVersion === 4" class="warn flex justify-start items-center">
39-
<mat-icon color="warn">warning</mat-icon>&nbsp;
40-
<strong
41-
class="more-info"
42-
tabindex="0"
43-
i18n-matTooltip
44-
matTooltip="This unit is from an old version of WISE that is no longer supported. Please find an alternate unit to use in the future or contact us for upgrade options."
45-
[matTooltipPosition]="'after'"
46-
i18n
47-
>Legacy Unit</strong
48-
>
49-
</p>
50-
<div *ngIf="project.metadata.summary" [innerHTML]="project.metadata.summary"></div>
51-
<p *ngIf="ngss.disciplines.length">
52-
<strong i18n>Discipline:</strong>
53-
<ng-container *ngFor="let discipline of ngss.disciplines; let isLast = last">
54-
{{ discipline.name }}{{ isLast ? '' : ' / ' }}
55-
</ng-container>
56-
</p>
57-
<p *ngIf="project.metadata.features">
58-
<strong i18n>Features:</strong> {{ project.metadata.features }}
59-
</p>
60-
<p *ngIf="ngss.dciArrangements.length">
61-
<strong i18n>NGSS Performance Expectations: </strong>
62-
<ng-container *ngFor="let dcia of ngss.dciArrangements; let isLast = last">
63-
<a href="{{ ngssWebUrl }}{{ dcia.id }}" target="_blank">{{ dcia.id }} {{ dcia.name }}</a>
64-
<ng-container *ngIf="dcia.children.length">
65-
(<ng-container *ngFor="let pe of dcia.children; let isLastChild = last"
66-
><a
67-
class="pe"
68-
href="{{ ngssWebUrl }}{{ pe.id }}"
69-
target="_blank"
70-
matTooltip="{{ pe.name }}"
71-
[matTooltipPosition]="'above'"
72-
>{{ pe.id }}</a
73-
>{{ isLastChild ? '' : ', ' }}</ng-container
74-
>) </ng-container
75-
>{{ isLast ? '' : ' / ' }}
76-
</ng-container>
77-
</p>
40+
@if (project.wiseVersion === 4) {
41+
<p class="warn flex justify-start items-center">
42+
<mat-icon color="warn">warning</mat-icon>&nbsp;
43+
<strong
44+
class="more-info"
45+
tabindex="0"
46+
i18n-matTooltip
47+
matTooltip="This unit is from an old version of WISE that is no longer supported. Please find an alternate unit to use in the future or contact us for upgrade options."
48+
[matTooltipPosition]="'after'"
49+
i18n
50+
>Legacy Unit</strong
51+
>
52+
</p>
53+
}
54+
@if (project.metadata.summary) {
55+
<div [innerHTML]="project.metadata.summary"></div>
56+
}
57+
@if (ngss.disciplines.length) {
58+
<p>
59+
<strong i18n>Discipline:</strong>
60+
@for (discipline of ngss.disciplines; track discipline.name; let last = $last) {
61+
{{ discipline.name }}{{ last ? '' : ' / ' }}
62+
}
63+
</p>
64+
}
65+
@if (project.metadata.features) {
66+
<p><strong i18n>Features:</strong> {{ project.metadata.features }}</p>
67+
}
68+
@if (ngss.dciArrangements.length) {
69+
<p>
70+
<strong i18n>NGSS Performance Expectations: </strong>
71+
@for (dcia of ngss.dciArrangements; track dcia.id; let last = $last) {
72+
<a href="{{ ngssWebUrl }}{{ dcia.id }}" target="_blank"
73+
>{{ dcia.id }} {{ dcia.name }}</a
74+
>
75+
@if (dcia.children.length) {
76+
(
77+
@for (pe of dcia.children; track pe.id; let lastChild = $last) {
78+
<a
79+
class="pe"
80+
href="{{ ngssWebUrl }}{{ pe.id }}"
81+
target="_blank"
82+
matTooltip="{{ pe.name }}"
83+
[matTooltipPosition]="'above'"
84+
>{{ pe.id }}</a
85+
>{{ lastChild ? '' : ', ' }}
86+
}
87+
)
88+
}
89+
{{ last ? '' : ' / ' }}
90+
}
91+
</p>
92+
}
7893
<unit-tags [tags]="project.tags" />
7994
</div>
80-
<discourse-category-activity
81-
*ngIf="project.metadata.discourseCategoryURL"
82-
[categoryURL]="project.metadata.discourseCategoryURL"
83-
/>
95+
@if (project.metadata.discourseCategoryURL) {
96+
<discourse-category-activity [categoryURL]="project.metadata.discourseCategoryURL" />
97+
}
8498
<div class="license notice-bg-bg mat-caption secondary-text">
8599
<img src="../../../../assets/img/by-sa.png" alt="CC BY-SA" />&nbsp;
86-
<span *ngIf="!isCopy" [ngSwitch]="authorsString.length">
87-
<ng-container *ngSwitchCase="0" i18n
88-
><a href="{{ project.uri }}" target="_blank">This unit</a> is licensed under
89-
<a href="{{ licenseUrl }}" target="_blank">CC BY-SA</a>.</ng-container
90-
>
91-
<ng-container *ngSwitchDefault i18n
92-
><a href="{{ project.uri }}" target="_blank">This unit</a> is licensed under
93-
<a href="{{ licenseUrl }}" target="_blank">CC BY-SA</a> by
94-
{{ authorsString }}.</ng-container
95-
>
96-
</span>
97-
<span *ngIf="isCopy" [ngSwitch]="parentAuthorsString.length">
98-
<ng-container *ngSwitchCase="0" i18n
99-
><a href="{{ project.uri }}" target="_blank">This unit</a> is a copy of
100-
<a href="{{ parentProject.uri }}" target="_blank">{{ parentProject.title }}</a> (used
101-
under <a href="{{ licenseUrl }}" target="_blank">CC BY-SA</a>).</ng-container
102-
>
103-
<ng-container *ngSwitchDefault i18n
104-
><a href="{{ project.uri }}" target="_blank">This unit</a> is a copy of
105-
<a href="{{ parentProject.uri }}" target="_blank">{{ parentProject.title }}</a> by
106-
{{ parentAuthorsString }} (used under
107-
<a href="{{ licenseUrl }}" target="_blank">CC BY-SA</a>).</ng-container
108-
>
109-
</span>
100+
@if (isCopy) {
101+
<span>
102+
@if (parentAuthorsString.length == 0) {
103+
<ng-container i18n
104+
><a href="{{ project.uri }}" target="_blank">This unit</a> is a copy of
105+
<a href="{{ parentProject.uri }}" target="_blank">{{ parentProject.title }}</a> (used
106+
under <a href="{{ licenseUrl }}" target="_blank">CC BY-SA</a>).</ng-container
107+
>
108+
} @else {
109+
<ng-container i18n
110+
><a href="{{ project.uri }}" target="_blank">This unit</a> is a copy of
111+
<a href="{{ parentProject.uri }}" target="_blank">{{ parentProject.title }}</a> by
112+
{{ parentAuthorsString }} (used under
113+
<a href="{{ licenseUrl }}" target="_blank">CC BY-SA</a>).</ng-container
114+
>
115+
}
116+
</span>
117+
} @else {
118+
<span>
119+
@if (authorsString.length == 0) {
120+
<ng-container i18n
121+
><a href="{{ project.uri }}" target="_blank">This unit</a> is licensed under
122+
<a href="{{ licenseUrl }}" target="_blank">CC BY-SA</a>.</ng-container
123+
>
124+
} @else {
125+
<ng-container i18n
126+
><a href="{{ project.uri }}" target="_blank">This unit</a> is licensed under
127+
<a href="{{ licenseUrl }}" target="_blank">CC BY-SA</a> by
128+
{{ authorsString }}.</ng-container
129+
>
130+
}
131+
</span>
132+
}
110133
/
111-
<span
112-
*ngIf="!project.license"
113-
class="more-info"
114-
[matTooltip]="licenseInfo"
115-
matTooltipPosition="above"
116-
tabindex="0"
117-
i18n
118-
>More</span
119-
>
120-
<a *ngIf="project.license" href="{{ project.license }}" target="_blank" i18n>View License</a>
134+
@if (project.license) {
135+
<a href="{{ project.license }}" target="_blank" i18n>View License</a>
136+
} @else {
137+
<span
138+
class="more-info"
139+
[matTooltip]="licenseInfo"
140+
matTooltipPosition="above"
141+
tabindex="0"
142+
i18n
143+
>More</span
144+
>
145+
}
121146
</div>
122147
</div>
123148
</div>
124149
<div mat-dialog-actions class="flex flex-col sm:flex-row gap-2 sm:gap-4 !items-stretch" align="end">
125-
<button mat-button cdkFocusInitial (click)="onClose()" i18n>Close</button>
126-
<button
127-
*ngIf="isTeacher && !isRunProject && project.wiseVersion !== 4"
128-
mat-flat-button
129-
color="accent"
130-
(click)="runProject()"
131-
>
132-
<mat-icon>supervised_user_circle</mat-icon>&nbsp;<ng-container i18n
133-
>Use with Class</ng-container
134-
>
135-
</button>
150+
<button mat-button cdkFocusInitial (click)="close()" i18n>Close</button>
151+
@if (isTeacher && !isRunProject && project.wiseVersion !== 4) {
152+
<button mat-flat-button color="accent" (click)="runProject()">
153+
<mat-icon>supervised_user_circle</mat-icon>&nbsp;<ng-container i18n
154+
>Use with Class</ng-container
155+
>
156+
</button>
157+
}
136158
<button mat-flat-button color="primary" (click)="previewProject()">
137159
<mat-icon>preview</mat-icon>&nbsp;<ng-container i18n>Preview</ng-container>
138160
</button>

src/app/modules/library/library-project-details/library-project-details.component.spec.ts

Lines changed: 17 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,24 @@
11
import { ComponentFixture, TestBed } from '@angular/core/testing';
2-
import { Observable } from 'rxjs';
32
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
43
import { LibraryProjectDetailsComponent } from './library-project-details.component';
54
import { UserService } from '../../../services/user.service';
65
import { Project } from '../../../domain/project';
76
import { NGSSStandards } from '../ngssStandards';
8-
import { NO_ERRORS_SCHEMA } from '@angular/core';
97
import { ConfigService } from '../../../services/config.service';
108
import { ParentProject } from '../../../domain/parentProject';
11-
12-
export class MockMatDialog {}
13-
14-
export class MockUserService {
15-
isTeacher(): Observable<boolean> {
16-
const isTeacher: boolean = true;
17-
return Observable.create((observer) => {
18-
observer.next(isTeacher);
19-
observer.complete();
20-
});
21-
}
22-
}
23-
24-
export class MockConfigService {
25-
getContextPath(): string {
26-
return '';
27-
}
28-
}
29-
30-
const parentProject = new ParentProject({
31-
id: 1000,
32-
title: 'Photosynthesis',
33-
uri: 'http://localhost:8080/project/1000',
34-
authors: [{ id: 6, firstName: 'Susie', lastName: 'Derkins', username: 'SusieDerkins' }]
35-
});
9+
import { MockProviders } from 'ng-mocks';
3610

3711
describe('LibraryProjectDetailsComponent', () => {
3812
let component: LibraryProjectDetailsComponent;
3913
let fixture: ComponentFixture<LibraryProjectDetailsComponent>;
4014

4115
beforeEach(() => {
4216
TestBed.configureTestingModule({
43-
declarations: [LibraryProjectDetailsComponent],
17+
imports: [LibraryProjectDetailsComponent],
4418
providers: [
45-
{ provide: UserService, useClass: MockUserService },
46-
{ provide: ConfigService, useClass: MockConfigService },
47-
{ provide: MatDialogRef, useValue: {} },
48-
{ provide: MAT_DIALOG_DATA, useValue: [] },
49-
{ provide: MatDialog, useClass: MockMatDialog }
50-
],
51-
schemas: [NO_ERRORS_SCHEMA]
19+
MockProviders(ConfigService, MatDialog, MatDialogRef, UserService),
20+
{ provide: MAT_DIALOG_DATA, useValue: {} }
21+
]
5222
});
5323
fixture = TestBed.createComponent(LibraryProjectDetailsComponent);
5424
component = fixture.componentInstance;
@@ -93,10 +63,10 @@ describe('LibraryProjectDetailsComponent', () => {
9363
const ngss: NGSSStandards = new NGSSStandards();
9464
ngss.disciplines = ngssObject.disciplines;
9565
ngss.dciArrangements = ngssObject.dciArrangements;
96-
component.ngss = ngss;
97-
component.project = new Project(project);
98-
component.parentProject = new ParentProject();
99-
component.setLicenseInfo();
66+
component['ngss'] = ngss;
67+
component['project'] = new Project(project);
68+
component['parentProject'] = new ParentProject();
69+
component['setLicenseInfo']();
10070
fixture.detectChanges();
10171
});
10272

@@ -121,9 +91,14 @@ describe('LibraryProjectDetailsComponent', () => {
12191
});
12292

12393
it('should show copied project info', () => {
124-
component.project.metadata.authors = [];
125-
component.parentProject = parentProject;
126-
component.setLicenseInfo();
94+
component['project'].metadata.authors = [];
95+
component['parentProject'] = new ParentProject({
96+
id: 1000,
97+
title: 'Photosynthesis',
98+
uri: 'http://localhost:8080/project/1000',
99+
authors: [{ id: 6, firstName: 'Susie', lastName: 'Derkins', username: 'SusieDerkins' }]
100+
});
101+
component['setLicenseInfo']();
127102
fixture.detectChanges();
128103
const compiled = fixture.debugElement.nativeElement;
129104
expect(compiled.textContent).toContain('is a copy of Photosynthesis');

0 commit comments

Comments
 (0)