Skip to content

Commit 3edd3d1

Browse files
Merge pull request #2189 from WISE-Community/grade-by-component-show-all-components
Grade by component show all components
2 parents ebaa1b8 + 237a8a5 commit 3edd3d1

54 files changed

Lines changed: 1357 additions & 677 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/app/curriculum/curriculum.component.spec.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ describe('CurriculumComponent', () => {
2323
providers: [
2424
MockProviders(ConfigService, UserService),
2525
MockProvider(LibraryService, {
26-
filterValuesUpdated$: of(),
2726
communityLibraryProjectsSource$: of([]),
2827
numberOfPublicProjectsVisible$: of(3),
2928
numberOfPersonalProjectsVisible$: of(2)

src/app/curriculum/curriculum.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { Subscription } from 'rxjs';
1111
import { UserService } from '../services/user.service';
1212
import { MatButtonModule } from '@angular/material/button';
1313
import { Router, RouterModule } from '@angular/router';
14+
import { ProjectFilterValues } from '../domain/projectFilterValues';
1415

1516
@Component({
1617
imports: [
@@ -23,6 +24,7 @@ import { Router, RouterModule } from '@angular/router';
2324
PublicLibraryComponent,
2425
RouterModule
2526
],
27+
providers: [ProjectFilterValues],
2628
styleUrl: './curriculum.component.scss',
2729
templateUrl: './curriculum.component.html'
2830
})
@@ -41,7 +43,6 @@ export class CurriculumComponent {
4143

4244
ngOnInit(): void {
4345
this.showMyUnits = this.userService.isTeacher();
44-
this.libraryService.initFilterValues();
4546
this.getLibraryProjects();
4647
this.subscribeNumUnitsVisible();
4748
}

src/app/domain/projectFilterValues.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Subject } from 'rxjs';
12
import { LibraryProject } from '../modules/library/libraryProject';
23

34
export class ProjectFilterValues {
@@ -9,6 +10,8 @@ export class ProjectFilterValues {
910
searchValue: string = '';
1011
standardValue: string[] = [];
1112
unitTypeValue: string[] = [];
13+
private updatedSource = new Subject<void>();
14+
public updated$ = this.updatedSource.asObservable();
1215

1316
matches(project: LibraryProject): boolean {
1417
return (
@@ -57,11 +60,13 @@ export class ProjectFilterValues {
5760
}
5861

5962
clear(): void {
60-
this.standardValue = [];
6163
this.disciplineValue = [];
62-
this.unitTypeValue = [];
63-
this.gradeLevelValue = [];
6464
this.featureValue = [];
65+
this.gradeLevelValue = [];
66+
this.publicUnitTypeValue = [];
67+
this.searchValue = '';
68+
this.standardValue = [];
69+
this.unitTypeValue = [];
6570
}
6671

6772
private matchesUnitType(project: LibraryProject): boolean {
@@ -114,4 +119,8 @@ export class ProjectFilterValues {
114119
)
115120
);
116121
}
122+
123+
emitUpdated(): void {
124+
this.updatedSource.next();
125+
}
117126
}

src/app/modules/library/home-page-project-library/home-page-project-library.component.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ import { LibraryService } from '../../../services/library.service';
33
import { ProjectFilterValues } from '../../../domain/projectFilterValues';
44

55
@Component({
6+
providers: [ProjectFilterValues],
67
selector: 'app-home-page-project-library',
78
styleUrls: ['./home-page-project-library.component.scss', '../library/library.component.scss'],
89
templateUrl: './home-page-project-library.component.html',
910
standalone: false
1011
})
1112
export class HomePageProjectLibraryComponent {
12-
protected filterValues: ProjectFilterValues = new ProjectFilterValues();
13-
1413
constructor(private libraryService: LibraryService) {
1514
libraryService.getOfficialLibraryProjects();
1615
}

src/app/modules/library/library-filters/library-filters.component.html

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<div class="library-filter">
22
<div class="flex flex-row gap-1">
33
<div class="flex-auto max-w-full">
4-
<app-search-bar [value]="getFilterValues().searchValue" (update)="searchUpdated($event)" />
4+
<app-search-bar [value]="filterValues.searchValue" (update)="searchUpdated($event)" />
55
</div>
66
<button
77
mat-icon-button
@@ -15,7 +15,7 @@
1515
matBadgeDescription="Filters applied"
1616
matBadgeOverlap="true"
1717
matBadgeSize="small"
18-
[matBadgeHidden]="!getFilterValues().hasFilters()"
18+
[matBadgeHidden]="!filterValues.hasFilters()"
1919
aria-hidden="false"
2020
>filter_list</mat-icon
2121
>
@@ -25,7 +25,7 @@
2525
<div class="library-filters" [class.expand]="showFilters" [class.isSplitScreen]="isSplitScreen">
2626
<div class="notice flex justify-between">
2727
<h3 class="mat-subtitle-2" i18n>Filters</h3>
28-
@if (getFilterValues().hasFilters()) {
28+
@if (filterValues.hasFilters()) {
2929
<a href="#" (click)="!!clearFilterValues()" i18n>Clear all</a>
3030
}
3131
</div>
@@ -35,20 +35,24 @@ <h3 class="mat-subtitle-2" i18n>Filters</h3>
3535
>
3636
@if (unitTypeOptions.length > 0) {
3737
<div
38-
class="library-filter"
38+
class="library-filter flex items-center gap-1"
3939
[ngClass]="{ 'md:w-full': isSplitScreen, 'md:w-1/4': !isSplitScreen }"
4040
>
4141
<app-select-menu
4242
id="unitTypeSelectMenu"
43+
class="w-full"
4344
[options]="unitTypeOptions"
4445
i18n-placeholderText
4546
placeholderText="Type"
46-
[value]="getFilterValues().unitTypeValue"
47+
[value]="filterValues.unitTypeValue"
4748
(update)="filterUpdated($event, 'unitType')"
4849
[valueProp]="'name'"
4950
[viewValueProp]="'name'"
5051
[multiple]="true"
5152
/>
53+
<a tabindex="0" (click)="showTypeInfo()" (keyup.enter)="showTypeInfo()">
54+
<mat-icon aria-label="Type filter explanation" i18n-aria-label>info</mat-icon>
55+
</a>
5256
</div>
5357
}
5458
@if (disciplineOptions.length > 0) {
@@ -61,7 +65,7 @@ <h3 class="mat-subtitle-2" i18n>Filters</h3>
6165
[options]="disciplineOptions"
6266
i18n-placeholderText
6367
placeholderText="Discipline"
64-
[value]="getFilterValues().disciplineValue"
68+
[value]="filterValues.disciplineValue"
6569
(update)="filterUpdated($event, 'discipline')"
6670
[valueProp]="'id'"
6771
[viewValueProp]="'name'"
@@ -79,7 +83,7 @@ <h3 class="mat-subtitle-2" i18n>Filters</h3>
7983
[options]="gradeLevelOptions"
8084
i18n-placeholderText
8185
placeholderText="Grade Level"
82-
[value]="getFilterValues().gradeLevelValue"
86+
[value]="filterValues.gradeLevelValue"
8387
(update)="filterUpdated($event, 'gradeLevel')"
8488
valueProp="grade"
8589
viewValueProp="grade"
@@ -98,7 +102,7 @@ <h3 class="mat-subtitle-2" i18n>Filters</h3>
98102
[possibleLabels]="possibleStandardLabels"
99103
i18n-placeholderText
100104
placeholderText="Standards Addressed"
101-
[value]="getFilterValues().standardValue"
105+
[value]="filterValues.standardValue"
102106
(update)="filterUpdated($event, 'standard')"
103107
[valueProp]="'id'"
104108
[viewValueProp]="'name'"
@@ -115,7 +119,7 @@ <h3 class="mat-subtitle-2" i18n>Filters</h3>
115119
[options]="featureOptions"
116120
i18n-placeholderText
117121
placeholderText="Features"
118-
[value]="getFilterValues().featureValue"
122+
[value]="filterValues.featureValue"
119123
(update)="filterUpdated($event, 'feature')"
120124
valueProp="name"
121125
viewValueProp="name"

src/app/modules/library/library-filters/library-filters.component.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,7 @@ h3 {
2929
.library-filter {
3030
margin: 0;
3131
}
32+
33+
a {
34+
cursor: pointer;
35+
}

src/app/modules/library/library-filters/library-filters.component.spec.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { LibraryService } from '../../../services/library.service';
44
import sampleLibraryProjects from '../sampleLibraryProjects';
55
import { SimpleChange } from '@angular/core';
66
import { LibraryProject } from '../libraryProject';
7-
import { ProjectFilterValues } from '../../../domain/projectFilterValues';
87
import { MockProvider } from 'ng-mocks';
98
import { of } from 'rxjs';
9+
import { ProjectFilterValues } from '../../../domain/projectFilterValues';
1010

1111
describe('LibraryFiltersComponent', () => {
1212
let component: LibraryFiltersComponent;
@@ -21,10 +21,9 @@ describe('LibraryFiltersComponent', () => {
2121
officialLibraryProjectsSource$: of([] as LibraryProject[]),
2222
communityLibraryProjectsSource$: of([] as LibraryProject[]),
2323
sharedLibraryProjectsSource$: of([] as LibraryProject[]),
24-
personalLibraryProjectsSource$: of([] as LibraryProject[]),
25-
filterValuesUpdated$: of(),
26-
filterValues: new ProjectFilterValues()
27-
})
24+
personalLibraryProjectsSource$: of([] as LibraryProject[])
25+
}),
26+
ProjectFilterValues
2827
]
2928
});
3029
projects = sampleLibraryProjects;
@@ -45,15 +44,15 @@ describe('LibraryFiltersComponent', () => {
4544
expect(component['disciplineOptions'].length).toBe(2);
4645
});
4746

48-
it('should call LibraryService.filterValuesUpdated when the search value changes', waitForAsync(() => {
49-
const libraryServiceFilterValuesSpy = spyOn(TestBed.get(LibraryService), 'filterValuesUpdated');
47+
it('should call ProjectFilterValues.emitUpdated when the search value changes', waitForAsync(() => {
48+
const spy = spyOn(TestBed.inject(ProjectFilterValues), 'emitUpdated');
5049
component['searchUpdated']('photo');
51-
expect(libraryServiceFilterValuesSpy).toHaveBeenCalled();
50+
expect(spy).toHaveBeenCalled();
5251
}));
5352

54-
it('should call LibraryService.filterValuesUpdated when a filter value changes', waitForAsync(() => {
55-
const libraryServiceFilterValuesSpy = spyOn(TestBed.get(LibraryService), 'filterValuesUpdated');
53+
it('should call ProjectFilterValues.emitUpdated when a filter value changes', waitForAsync(() => {
54+
const spy = spyOn(TestBed.inject(ProjectFilterValues), 'emitUpdated');
5655
component['filterUpdated'](['Earth Sciences', 'Physical Sciences'], 'discipline');
57-
expect(libraryServiceFilterValuesSpy).toHaveBeenCalled();
56+
expect(spy).toHaveBeenCalled();
5857
}));
5958
});

src/app/modules/library/library-filters/library-filters.component.ts

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import { SelectMenuComponent } from '../../shared/select-menu/select-menu.compon
1414
import { StandardsSelectMenuComponent } from '../../shared/standards-select-menu/standards-select-menu.component';
1515
import { Feature } from '../Feature';
1616
import { Grade, GradeLevel } from '../GradeLevel';
17+
import { MatDialog } from '@angular/material/dialog';
18+
import { DialogWithCloseComponent } from '../../../../assets/wise5/directives/dialog-with-close/dialog-with-close.component';
1719

1820
@Component({
1921
imports: [
@@ -48,22 +50,24 @@ export class LibraryFiltersComponent {
4850
];
4951

5052
constructor(
53+
private dialog: MatDialog,
54+
protected filterValues: ProjectFilterValues,
5155
private libraryService: LibraryService,
5256
private utilService: UtilService
5357
) {
54-
libraryService.officialLibraryProjectsSource$.subscribe((projects: LibraryProject[]) => {
58+
this.libraryService.officialLibraryProjectsSource$.subscribe((projects: LibraryProject[]) => {
5559
this.libraryProjects = projects;
5660
this.populateFilterOptions();
5761
});
58-
libraryService.communityLibraryProjectsSource$.subscribe((projects: LibraryProject[]) => {
62+
this.libraryService.communityLibraryProjectsSource$.subscribe((projects: LibraryProject[]) => {
5963
this.communityProjects = projects;
6064
this.populateFilterOptions();
6165
});
62-
libraryService.sharedLibraryProjectsSource$.subscribe((projects: LibraryProject[]) => {
66+
this.libraryService.sharedLibraryProjectsSource$.subscribe((projects: LibraryProject[]) => {
6367
this.sharedProjects = projects;
6468
this.populateFilterOptions();
6569
});
66-
libraryService.personalLibraryProjectsSource$.subscribe((projects: LibraryProject[]) => {
70+
this.libraryService.personalLibraryProjectsSource$.subscribe((projects: LibraryProject[]) => {
6771
this.personalProjects = projects;
6872
this.populateFilterOptions();
6973
});
@@ -143,41 +147,51 @@ export class LibraryFiltersComponent {
143147
}
144148

145149
protected searchUpdated(value: string): void {
146-
this.getFilterValues().searchValue = value.toLocaleLowerCase();
150+
this.filterValues.searchValue = value.toLocaleLowerCase();
147151
this.emitFilterValues();
148152
}
149153

150154
protected filterUpdated(value: any[], context: string = ''): void {
151155
switch (context) {
152156
case 'discipline':
153-
this.getFilterValues().disciplineValue = value;
157+
this.filterValues.disciplineValue = value;
154158
break;
155159
case 'gradeLevel':
156-
this.getFilterValues().gradeLevelValue = value;
160+
this.filterValues.gradeLevelValue = value;
157161
break;
158162
case 'standard':
159-
this.getFilterValues().standardValue = value;
163+
this.filterValues.standardValue = value;
160164
break;
161165
case 'feature':
162-
this.getFilterValues().featureValue = value;
166+
this.filterValues.featureValue = value;
163167
break;
164168
case 'unitType':
165-
this.getFilterValues().unitTypeValue = value;
169+
this.filterValues.unitTypeValue = value;
166170
break;
167171
}
168172
this.emitFilterValues();
169173
}
170174

171-
protected getFilterValues(): ProjectFilterValues {
172-
return this.libraryService.filterValues;
173-
}
174-
175175
private emitFilterValues(): void {
176-
this.libraryService.filterValuesUpdated();
176+
this.filterValues.emitUpdated();
177177
}
178178

179179
protected clearFilterValues(): void {
180-
this.getFilterValues().clear();
180+
this.filterValues.clear();
181181
this.emitFilterValues();
182182
}
183+
184+
protected showTypeInfo(): void {
185+
const message = $localize`"Type" indicates the platform on which a unit runs. "WISE Platform" units are created
186+
using the WISE authoring tool. Students use WISE accounts to complete lessons and teachers can review and grade
187+
work on the WISE platform. "Other" units are created using different platforms. Resources for these units
188+
are linked in the unit details.`;
189+
this.dialog.open(DialogWithCloseComponent, {
190+
data: {
191+
content: message,
192+
title: $localize`Unit Type`
193+
},
194+
panelClass: 'dialog-sm'
195+
});
196+
}
183197
}

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

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33
<div>
44
<span i18n>{{ standardsName }}: </span>
55
@for (standard of standards; track standard.id; let last = $last) {
6-
<a href="{{ standard.url }}" target="_blank"
7-
><b>{{ standard.id }}</b> {{ standard.name }}</a
6+
<a
7+
href="{{ standard.url }}"
8+
target="_blank"
9+
[matTooltip]="standard.name"
10+
matTooltipPosition="above"
11+
>{{ standard.id }}</a
812
>{{ last ? '' : ' • ' }}
913
}
1014
</div>
@@ -68,6 +72,12 @@
6872
>
6973
</p>
7074
}
75+
@if (project.metadata.unitType !== 'Platform') {
76+
<p class="notice max-w-none" i18n>
77+
Note: This unit was created outside of the WISE platform. Teaching resources are linked
78+
below.
79+
</p>
80+
}
7181
@if (project.metadata.resources?.length > 0) {
7282
<p>
7383
<strong i18n>Resources:</strong>
@@ -210,7 +220,12 @@
210220
}
211221
@if (canPreview) {
212222
<button mat-flat-button color="primary" (click)="previewProject()">
213-
<mat-icon>preview</mat-icon>&nbsp;<ng-container i18n>Preview</ng-container>
223+
<mat-icon>preview</mat-icon>
224+
@if (project.metadata.unitType === 'Platform') {
225+
<ng-container i18n>Preview</ng-container>
226+
} @else {
227+
<ng-container i18n>Unit Resources</ng-container>
228+
}
214229
</button>
215230
}
216231
</div>

0 commit comments

Comments
 (0)