Skip to content

Commit 80366d0

Browse files
authored
Fix - Ang-838 (#537)
* fix(global-search): Adjusted state and service for multiple selected options by the key * fix(global-search): Adjusted filter-ships component to handle multiple options for one key * fix(global-search): Refactored and adjusted components for multiple selection of filter options * fix(global-search): Resolved todo, fixed boolean filters mapping to query params * fix(global-search): Fixed logic for building params for index-card-search
1 parent 7840a5d commit 80366d0

26 files changed

+384
-669
lines changed

src/app/features/admin-institutions/components/filters-section/filters-section.component.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,16 @@ <h2>{{ 'adminInstitutions.common.filterBy' | translate }}</h2>
2121
/>
2222

2323
<div class="filters-section overflow-auto px-4">
24-
<osf-reusable-filters
24+
<osf-search-filters
2525
[plainStyle]="true"
2626
[filters]="filters()"
2727
[selectedOptions]="selectedFilterOptions()"
2828
[filterSearchResults]="filterSearchCache()"
2929
[isLoading]="areResourcesLoading()"
3030
[showEmptyState]="true"
3131
(loadFilterOptions)="onLoadFilterOptions($event)"
32-
(filterOptionChanged)="onFilterChanged($event)"
33-
(filterSearchChanged)="onFilterSearchChanged($event)"
32+
(filterOptionSelected)="onSelectedFilterOptionsChanged($event)"
33+
(filterOptionsSearch)="onSearchFilterOptions($event)"
3434
(loadMoreFilterOptions)="onLoadMoreFilterOptions($event)"
3535
/>
3636
</div>

src/app/features/admin-institutions/components/filters-section/filters-section.component.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Card } from 'primeng/card';
77

88
import { ChangeDetectionStrategy, Component, model } from '@angular/core';
99

10-
import { FilterChipsComponent, ReusableFilterComponent } from '@shared/components';
10+
import { FilterChipsComponent, SearchFiltersComponent } from '@shared/components';
1111
import { DiscoverableFilter, FilterOption } from '@shared/models';
1212
import {
1313
ClearFilterSearchResults,
@@ -23,7 +23,7 @@ import {
2323

2424
@Component({
2525
selector: 'osf-institution-resource-table-filters',
26-
imports: [Button, Card, FilterChipsComponent, TranslatePipe, ReusableFilterComponent],
26+
imports: [Button, Card, FilterChipsComponent, TranslatePipe, SearchFiltersComponent],
2727
templateUrl: './filters-section.component.html',
2828
styleUrl: './filters-section.component.scss',
2929
changeDetection: ChangeDetectionStrategy.OnPush,
@@ -46,7 +46,7 @@ export class FiltersSectionComponent {
4646
filterSearchCache = select(GlobalSearchSelectors.getFilterSearchCache);
4747
areResourcesLoading = select(GlobalSearchSelectors.getResourcesLoading);
4848

49-
onFilterChanged(event: { filter: DiscoverableFilter; filterOption: FilterOption | null }): void {
49+
onSelectedFilterOptionsChanged(event: { filter: DiscoverableFilter; filterOption: FilterOption[] }): void {
5050
this.actions.updateSelectedFilterOption(event.filter.key, event.filterOption);
5151
this.actions.fetchResources();
5252
}
@@ -59,16 +59,19 @@ export class FiltersSectionComponent {
5959
this.actions.loadMoreFilterOptions(filter.key);
6060
}
6161

62-
onFilterSearchChanged(event: { searchText: string; filter: DiscoverableFilter }): void {
62+
onSearchFilterOptions(event: { searchText: string; filter: DiscoverableFilter }): void {
6363
if (event.searchText.trim()) {
6464
this.actions.loadFilterOptionsWithSearch(event.filter.key, event.searchText);
6565
} else {
6666
this.actions.clearFilterSearchResults(event.filter.key);
6767
}
6868
}
6969

70-
onFilterChipRemoved(filterKey: string): void {
71-
this.actions.updateSelectedFilterOption(filterKey, null);
70+
onFilterChipRemoved(event: { filterKey: string; optionRemoved: FilterOption }): void {
71+
const updatedOptions = this.selectedFilterOptions()[event.filterKey].filter(
72+
(option) => option.value === event.optionRemoved.value
73+
);
74+
this.actions.updateSelectedFilterOption(event.filterKey, updatedOptions);
7275
this.actions.fetchResources();
7376
}
7477
}

src/app/features/preprints/components/browse-by-subjects/browse-by-subjects.component.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ export class BrowseBySubjectsComponent {
2121
linksToSearchPageForSubject = computed(() => {
2222
return this.subjects().map((subject) => ({
2323
tab: ResourceType.Preprint,
24-
filter_subject: JSON.stringify({
25-
label: subject.name,
26-
value: subject.iri,
27-
}),
24+
filter_subject: JSON.stringify([
25+
{
26+
label: subject.name,
27+
value: subject.iri,
28+
},
29+
]),
2830
}));
2931
});
3032
areSubjectsLoading = input.required<boolean>();

src/app/features/preprints/pages/landing/preprints-landing.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export class PreprintsLandingComponent implements OnInit, OnDestroy {
9090
const searchValue = this.searchControl.value;
9191

9292
this.router.navigate(['/search'], {
93-
queryParams: { search: searchValue, resourceTab: ResourceType.Preprint },
93+
queryParams: { search: searchValue, tab: ResourceType.Preprint },
9494
});
9595
}
9696
}

src/app/shared/components/filter-chips/filter-chips.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
@if (chips().length > 0) {
22
<div class="flex flex-wrap gap-2">
3-
@for (chip of chips(); track chip.key) {
3+
@for (chip of chips(); track chip.key + chip.displayValue) {
44
<p-chip
55
[label]="chip.label + ': ' + chip.displayValue"
66
removeIcon="fas fa-close"
77
removable
8-
(onRemove)="removeFilter(chip.key)"
8+
(onRemove)="removeFilter(chip.key, chip.option)"
99
/>
1010
}
1111
</div>

src/app/shared/components/filter-chips/filter-chips.component.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import { DiscoverableFilter, FilterOption } from '@shared/models';
1212
changeDetection: ChangeDetectionStrategy.OnPush,
1313
})
1414
export class FilterChipsComponent {
15-
filterOptions = input<Record<string, FilterOption | null>>({});
15+
filterOptions = input<Record<string, FilterOption[]>>({});
1616
filters = input.required<DiscoverableFilter[]>();
1717

18-
selectedOptionRemoved = output<string>();
18+
selectedOptionRemoved = output<{ filterKey: string; optionRemoved: FilterOption }>();
1919

2020
filterLabels = computed(() => {
2121
return this.filters()
@@ -31,20 +31,24 @@ export class FilterChipsComponent {
3131
const labels = this.filterLabels();
3232

3333
return Object.entries(options)
34-
.filter(([, value]) => value !== null)
35-
.map(([key, option]) => {
34+
.filter(([, value]) => (value?.length ?? 0) > 0)
35+
.flatMap(([key, option]) => {
3636
const filterLabel = labels.find((l) => l.key === key)?.label || key;
37-
const displayValue = option?.label || option?.value;
37+
const optionArray = option as FilterOption[];
3838

39-
return {
39+
return optionArray.map((opt) => ({
4040
key,
4141
label: filterLabel,
42-
displayValue,
43-
};
42+
displayValue: opt?.label || opt?.value,
43+
option: opt,
44+
}));
4445
});
4546
});
4647

47-
removeFilter(filterKey: string): void {
48-
this.selectedOptionRemoved.emit(filterKey);
48+
removeFilter(filterKey: string, option: FilterOption): void {
49+
this.selectedOptionRemoved.emit({
50+
filterKey,
51+
optionRemoved: option,
52+
});
4953
}
5054
}

src/app/shared/components/generic-filter/generic-filter.component.html

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,30 @@
44
<osf-loading-spinner />
55
</div>
66
} @else {
7-
<div class="relative">
8-
<p-select
9-
[id]="filterType()"
10-
[options]="filterOptions()"
11-
optionLabel="label"
12-
optionValue="value"
13-
[ngModel]="selectedValue()"
14-
[placeholder]="currentSelectedOption() ? currentSelectedOption()?.label : placeholder()"
15-
styleClass="w-full"
16-
panelStyleClass="max-w-30rem scrollable-panel"
17-
appendTo="body"
18-
filter
19-
resetFilterOnHide="false"
20-
[virtualScroll]="true"
21-
[virtualScrollItemSize]="25"
22-
[lazy]="true"
23-
scrollHeight="200px"
24-
[autoOptionFocus]="false"
25-
[loading]="isPaginationLoading() || isSearchLoading()"
26-
(onLazyLoad)="loadMoreItems($event)"
27-
(onChange)="onOptionChange($event)"
28-
(onFilter)="onFilterChange($event)"
29-
[showClear]="!!selectedValue()"
30-
>
31-
<ng-template #item let-item>
32-
<p class="text-base">{{ item.label }} ({{ item.cardSearchResultCount }})</p>
33-
</ng-template>
34-
</p-select>
35-
</div>
7+
<p-multiSelect
8+
[id]="filterOperator()"
9+
[options]="filterOptions()"
10+
optionLabel="label"
11+
optionValue="value"
12+
[ngModel]="selectedOptionValues()"
13+
[placeholder]="placeholder()"
14+
styleClass="w-full"
15+
appendTo="body"
16+
filter
17+
resetFilterOnHide="false"
18+
[showToggleAll]="false"
19+
[virtualScroll]="true"
20+
[virtualScrollItemSize]="40"
21+
scrollHeight="200px"
22+
[autoOptionFocus]="false"
23+
[loading]="isPaginationLoading() || isSearchLoading()"
24+
(onFilter)="onFilterChange($event)"
25+
(onChange)="onMultiChange($event)"
26+
(onLazyLoad)="loadMoreItems($event)"
27+
>
28+
<ng-template #item let-item>
29+
<p class="text-base">{{ item.label }} ({{ item.cardSearchResultCount }})</p>
30+
</ng-template>
31+
</p-multiSelect>
3632
}
3733
</div>

0 commit comments

Comments
 (0)