Skip to content

Commit 34d7a1c

Browse files
fix(Unit Library): Thumbnail flicker and filter issues (#2163)
Co-authored-by: Aaron Detre <[email protected]>
1 parent b4e465a commit 34d7a1c

File tree

14 files changed

+50
-63
lines changed

14 files changed

+50
-63
lines changed

src/app/domain/project.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export class Project {
1818
run: Run;
1919
sharedOwners: User[] = [];
2020
selected: boolean;
21-
tags: Tag[];
21+
tags: Tag[] = [];
2222
thumbStyle: any;
2323
uri: String;
2424
wiseVersion: number;
@@ -95,11 +95,11 @@ export class Project {
9595
}
9696

9797
hasTagWithText(tagText: string): boolean {
98-
return this.tags?.some((tag: Tag) => tag.text === tagText);
98+
return this.tags.some((tag: Tag) => tag.text === tagText);
9999
}
100100

101101
hasTag(tag: Tag): boolean {
102-
return this.tags?.some((projectTag: Tag) => projectTag.id === tag.id);
102+
return this.tags.some((projectTag: Tag) => projectTag.id === tag.id);
103103
}
104104

105105
updateArchivedStatus(archived: boolean, tag: Tag): void {

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ export class MockLibraryService {
1313
communityLibraryProjectsSource$ = fakeAsyncResponse([]);
1414
filterValuesUpdated$ = of();
1515
numberOfPublicProjectsVisible = new BehaviorSubject<number>(0);
16-
getFilterValues() {
17-
return new ProjectFilterValues();
18-
}
16+
filterValues = new ProjectFilterValues();
1917
}
2018

2119
describe('CommunityLibraryComponent', () => {

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

Lines changed: 8 additions & 8 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]="filterValues.searchValue" (update)="searchUpdated($event)" />
4+
<app-search-bar [value]="getFilterValues().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]="!filterValues.hasFilters()"
18+
[matBadgeHidden]="!getFilterValues().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 (filterValues.hasFilters()) {
28+
@if (getFilterValues().hasFilters()) {
2929
<a href="#" (click)="!!clearFilterValues()" i18n>Clear all</a>
3030
}
3131
</div>
@@ -43,7 +43,7 @@ <h3 class="mat-subtitle-2" i18n>Filters</h3>
4343
[options]="unitTypeOptions"
4444
i18n-placeholderText
4545
placeholderText="Type"
46-
[value]="filterValues.unitTypeValue"
46+
[value]="getFilterValues().unitTypeValue"
4747
(update)="filterUpdated($event, 'unitType')"
4848
[valueProp]="'name'"
4949
[viewValueProp]="'name'"
@@ -61,7 +61,7 @@ <h3 class="mat-subtitle-2" i18n>Filters</h3>
6161
[options]="disciplineOptions"
6262
i18n-placeholderText
6363
placeholderText="Discipline"
64-
[value]="filterValues.disciplineValue"
64+
[value]="getFilterValues().disciplineValue"
6565
(update)="filterUpdated($event, 'discipline')"
6666
[valueProp]="'id'"
6767
[viewValueProp]="'name'"
@@ -79,7 +79,7 @@ <h3 class="mat-subtitle-2" i18n>Filters</h3>
7979
[options]="gradeLevelOptions"
8080
i18n-placeholderText
8181
placeholderText="Grade Level"
82-
[value]="filterValues.gradeLevelValue"
82+
[value]="getFilterValues().gradeLevelValue"
8383
(update)="filterUpdated($event, 'gradeLevel')"
8484
valueProp="grade"
8585
viewValueProp="grade"
@@ -98,7 +98,7 @@ <h3 class="mat-subtitle-2" i18n>Filters</h3>
9898
[possibleLabels]="possibleStandardLabels"
9999
i18n-placeholderText
100100
placeholderText="Standards Addressed"
101-
[value]="filterValues.standardValue"
101+
[value]="getFilterValues().standardValue"
102102
(update)="filterUpdated($event, 'standard')"
103103
[valueProp]="'id'"
104104
[viewValueProp]="'name'"
@@ -115,7 +115,7 @@ <h3 class="mat-subtitle-2" i18n>Filters</h3>
115115
[options]="featureOptions"
116116
i18n-placeholderText
117117
placeholderText="Features"
118-
[value]="filterValues.featureValue"
118+
[value]="getFilterValues().featureValue"
119119
(update)="filterUpdated($event, 'feature')"
120120
valueProp="name"
121121
viewValueProp="name"

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe('LibraryFiltersComponent', () => {
2323
sharedLibraryProjectsSource$: of([] as LibraryProject[]),
2424
personalLibraryProjectsSource$: of([] as LibraryProject[]),
2525
filterValuesUpdated$: of(),
26-
getFilterValues: () => new ProjectFilterValues()
26+
filterValues: new ProjectFilterValues()
2727
})
2828
]
2929
});

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

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ export class LibraryFiltersComponent {
3333
private communityProjects: LibraryProject[] = [];
3434
protected disciplineOptions: Discipline[] = [];
3535
protected featureOptions: Feature[] = [];
36-
protected filterValues: ProjectFilterValues;
3736
protected gradeLevelOptions: GradeLevel[] = [];
3837
@Input() showAdvancedFilteringOptions: boolean = true;
3938
@Input() isSplitScreen: boolean = false;
@@ -52,7 +51,6 @@ export class LibraryFiltersComponent {
5251
private libraryService: LibraryService,
5352
private utilService: UtilService
5453
) {
55-
this.filterValues = this.libraryService.getFilterValues();
5654
libraryService.officialLibraryProjectsSource$.subscribe((projects: LibraryProject[]) => {
5755
this.libraryProjects = projects;
5856
this.populateFilterOptions();
@@ -145,37 +143,41 @@ export class LibraryFiltersComponent {
145143
}
146144

147145
protected searchUpdated(value: string): void {
148-
this.filterValues.searchValue = value.toLocaleLowerCase();
146+
this.getFilterValues().searchValue = value.toLocaleLowerCase();
149147
this.emitFilterValues();
150148
}
151149

152150
protected filterUpdated(value: any[], context: string = ''): void {
153151
switch (context) {
154152
case 'discipline':
155-
this.filterValues.disciplineValue = value;
153+
this.getFilterValues().disciplineValue = value;
156154
break;
157155
case 'gradeLevel':
158-
this.filterValues.gradeLevelValue = value;
156+
this.getFilterValues().gradeLevelValue = value;
159157
break;
160158
case 'standard':
161-
this.filterValues.standardValue = value;
159+
this.getFilterValues().standardValue = value;
162160
break;
163161
case 'feature':
164-
this.filterValues.featureValue = value;
162+
this.getFilterValues().featureValue = value;
165163
break;
166164
case 'unitType':
167-
this.filterValues.unitTypeValue = value;
165+
this.getFilterValues().unitTypeValue = value;
168166
break;
169167
}
170168
this.emitFilterValues();
171169
}
172170

171+
protected getFilterValues(): ProjectFilterValues {
172+
return this.libraryService.filterValues;
173+
}
174+
173175
private emitFilterValues(): void {
174176
this.libraryService.filterValuesUpdated();
175177
}
176178

177179
protected clearFilterValues(): void {
178-
this.filterValues.clear();
180+
this.getFilterValues().clear();
179181
this.emitFilterValues();
180182
}
181183
}

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import { OnInit, QueryList, ViewChildren, Directive, Input } from '@angular/core';
2-
import { ProjectFilterValues } from '../../../domain/projectFilterValues';
32
import { LibraryService } from '../../../services/library.service';
43
import { LibraryProject } from '../libraryProject';
54
import { PageEvent, MatPaginator } from '@angular/material/paginator';
65
import { BehaviorSubject, Subscription } from 'rxjs';
76
import { MatDialog } from '@angular/material/dialog';
7+
import { ProjectFilterValues } from '../../../domain/projectFilterValues';
88

99
@Directive()
1010
export abstract class LibraryComponent implements OnInit {
1111
protected filteredProjects: LibraryProject[] = [];
12-
protected filterValues: ProjectFilterValues;
1312
protected highIndex: number = 0;
1413
protected lowIndex: number = 0;
1514
protected pageSizeOptions: number[] = [12, 24, 48, 96];
@@ -26,14 +25,13 @@ export abstract class LibraryComponent implements OnInit {
2625
) {}
2726

2827
ngOnInit(): void {
29-
this.filterValues = this.libraryService.getFilterValues();
3028
this.subscriptions.add(
3129
this.libraryService.filterValuesUpdated$.subscribe(() => this.filterUpdated())
3230
);
3331
}
3432

3533
ngOnDestroy(): void {
36-
this.filterValues.clear();
34+
this.getFilterValues().clear();
3735
this.subscriptions.unsubscribe();
3836
}
3937

@@ -65,7 +63,7 @@ export abstract class LibraryComponent implements OnInit {
6563
protected filterUpdated(): void {
6664
this.filteredProjects = this.projects
6765
.map((project) => {
68-
project.visible = this.filterValues.matches(project);
66+
project.visible = this.getFilterValues().matches(project);
6967
return project;
7068
})
7169
.filter((project) => project.visible)
@@ -97,4 +95,8 @@ export abstract class LibraryComponent implements OnInit {
9795
}
9896

9997
protected abstract getDetailsComponent(): any;
98+
99+
private getFilterValues(): ProjectFilterValues {
100+
return this.libraryService.filterValues;
101+
}
100102
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ export class MockLibraryService {
1616
implementationModelOptions: LibraryGroup[] = [];
1717
numberOfPublicProjectsVisible = new BehaviorSubject<number>(0);
1818
getOfficialLibraryProjects() {}
19-
getFilterValues() {
20-
return new ProjectFilterValues();
21-
}
19+
filterValues = new ProjectFilterValues();
2220
}
2321

2422
describe('OfficialLibraryComponent', () => {

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { PersonalLibraryHarness } from './personal-library.harness';
1212
import { ProjectTagService } from '../../../../assets/wise5/services/projectTagService';
1313
import { provideHttpClientTesting } from '@angular/common/http/testing';
1414
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
15-
import { ProjectFilterValues } from '../../../domain/projectFilterValues';
1615

1716
const archivedTag = { id: 1, text: 'archived', color: null };
1817
let archiveProjectService: ArchiveProjectService;
@@ -43,9 +42,6 @@ describe('PersonalLibraryComponent', () => {
4342
beforeEach(async () => {
4443
fixture = TestBed.createComponent(PersonalLibraryComponent);
4544
component = fixture.componentInstance;
46-
spyOn(TestBed.inject(LibraryService), 'getFilterValues').and.returnValue(
47-
new ProjectFilterValues()
48-
);
4945
setUpFiveProjects();
5046
archiveProjectService = TestBed.inject(ArchiveProjectService);
5147
http = TestBed.inject(HttpClient);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ describe('PublicLibraryComponent', () => {
2424
{ id: 1, name: 'P1' },
2525
{ id: 3, name: 'P3' }
2626
] as LibraryProject[]),
27-
getFilterValues: () => new ProjectFilterValues()
27+
filterValues: new ProjectFilterValues()
2828
})
2929
]
3030
}).compileComponents();

src/app/modules/library/public-unit-type-selector/public-unit-type-selector.component.spec.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,16 @@ describe('PublicUnitTypeSelectorComponent', () => {
1717
beforeEach(async () => {
1818
await TestBed.configureTestingModule({
1919
imports: [PublicUnitTypeSelectorComponent],
20-
providers: [MockProvider(LibraryService)]
20+
providers: [
21+
MockProvider(LibraryService, {
22+
filterValues: new ProjectFilterValues()
23+
})
24+
]
2125
}).compileComponents();
2226

2327
fixture = TestBed.createComponent(PublicUnitTypeSelectorComponent);
2428
loader = TestbedHarnessEnvironment.loader(fixture);
2529
component = fixture.componentInstance;
26-
spyOn(TestBed.inject(LibraryService), 'getFilterValues').and.returnValue({
27-
publicUnitTypeValue: []
28-
} as ProjectFilterValues);
2930
fixture.detectChanges();
3031
[checkbox1, checkbox2] = await loader.getAllHarnesses(MatCheckboxHarness);
3132
});
@@ -39,9 +40,7 @@ describe('PublicUnitTypeSelectorComponent', () => {
3940
it('should update filterValues and emit event when checkbox is clicked', async () => {
4041
const spy = spyOn(component.publicUnitTypeUpdatedEvent, 'emit');
4142
await checkbox1.check();
42-
expect(TestBed.inject(LibraryService).getFilterValues().publicUnitTypeValue).toEqual([
43-
'wiseTested'
44-
]);
43+
expect(TestBed.inject(LibraryService).filterValues.publicUnitTypeValue).toEqual(['wiseTested']);
4544
expect(spy).toHaveBeenCalled();
4645
});
4746

0 commit comments

Comments
 (0)