diff --git a/src/app/features/admin-institutions/components/filters-section/filters-section.component.spec.ts b/src/app/features/admin-institutions/components/filters-section/filters-section.component.spec.ts
index eb0f8f556..de3770979 100644
--- a/src/app/features/admin-institutions/components/filters-section/filters-section.component.spec.ts
+++ b/src/app/features/admin-institutions/components/filters-section/filters-section.component.spec.ts
@@ -6,7 +6,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FilterChipsComponent } from '@osf/shared/components/filter-chips/filter-chips.component';
import { SearchFiltersComponent } from '@osf/shared/components/search-filters/search-filters.component';
-import { DiscoverableFilter, FilterOption } from '@osf/shared/models/search/discaverable-filter.model';
+import { DiscoverableFilter, FilterOption } from '@osf/shared/models/search/discoverable-filter.model';
import {
ClearFilterSearchResults,
FetchResources,
diff --git a/src/app/features/admin-institutions/components/filters-section/filters-section.component.ts b/src/app/features/admin-institutions/components/filters-section/filters-section.component.ts
index edf9be02a..78dc882dc 100644
--- a/src/app/features/admin-institutions/components/filters-section/filters-section.component.ts
+++ b/src/app/features/admin-institutions/components/filters-section/filters-section.component.ts
@@ -9,16 +9,14 @@ import { ChangeDetectionStrategy, Component, model } from '@angular/core';
import { FilterChipsComponent } from '@osf/shared/components/filter-chips/filter-chips.component';
import { SearchFiltersComponent } from '@osf/shared/components/search-filters/search-filters.component';
-import { DiscoverableFilter, FilterOption } from '@osf/shared/models/search/discaverable-filter.model';
+import { DiscoverableFilter, FilterOption } from '@osf/shared/models/search/discoverable-filter.model';
import {
ClearFilterSearchResults,
FetchResources,
GlobalSearchSelectors,
LoadFilterOptions,
- LoadFilterOptionsAndSetValues,
LoadFilterOptionsWithSearch,
LoadMoreFilterOptions,
- SetDefaultFilterValue,
UpdateSelectedFilterOption,
} from '@osf/shared/stores/global-search';
@@ -32,12 +30,10 @@ import {
export class FiltersSectionComponent {
private actions = createDispatchMap({
loadFilterOptions: LoadFilterOptions,
- loadFilterOptionsAndSetValues: LoadFilterOptionsAndSetValues,
loadFilterOptionsWithSearch: LoadFilterOptionsWithSearch,
loadMoreFilterOptions: LoadMoreFilterOptions,
updateSelectedFilterOption: UpdateSelectedFilterOption,
clearFilterSearchResults: ClearFilterSearchResults,
- setDefaultFilterValue: SetDefaultFilterValue,
fetchResources: FetchResources,
});
diff --git a/src/app/shared/components/filter-chips/filter-chips.component.html b/src/app/shared/components/filter-chips/filter-chips.component.html
index 89c86f54b..1e998a540 100644
--- a/src/app/shared/components/filter-chips/filter-chips.component.html
+++ b/src/app/shared/components/filter-chips/filter-chips.component.html
@@ -2,7 +2,7 @@
@for (chip of chips(); track chip.key + chip.displayValue) {
{
let component: FilterChipsComponent;
@@ -18,29 +18,34 @@ describe('FilterChipsComponent', () => {
{
key: 'subject',
label: 'Subject',
- operator: FilterOperatorOption.IsPresent,
- resultCount: 100,
- options: [
- { label: 'Psychology', value: 'psychology', cardSearchResultCount: 50 },
- { label: 'Biology', value: 'biology', cardSearchResultCount: 30 },
- ],
+ operator: FilterOperatorOption.AnyOf,
+ options: [],
},
{
- key: 'resourceType',
- label: 'Resource Type',
+ key: 'hasData',
+ label: 'Has Data',
operator: FilterOperatorOption.IsPresent,
- resultCount: 75,
- options: [
- { label: 'Project', value: 'project', cardSearchResultCount: 40 },
- { label: 'Registration', value: 'registration', cardSearchResultCount: 35 },
- ],
+ options: [],
},
];
+ const biologyOption: FilterOption = {
+ label: 'Biology',
+ value: 'biology',
+ cardSearchResultCount: 10,
+ };
+
+ const trueOption: FilterOption = {
+ label: '',
+ value: 'true',
+ cardSearchResultCount: 5,
+ };
+
beforeEach(async () => {
- await TestBed.configureTestingModule({
- imports: [FilterChipsComponent, OSFTestingModule],
- }).compileComponents();
+ TestBed.configureTestingModule({
+ imports: [FilterChipsComponent],
+ providers: [provideOSFCore()],
+ });
fixture = TestBed.createComponent(FilterChipsComponent);
component = fixture.componentInstance;
@@ -48,227 +53,138 @@ describe('FilterChipsComponent', () => {
it('should create', () => {
fixture.componentRef.setInput('filters', mockFilters);
+ fixture.componentRef.setInput('filterOptions', {});
fixture.detectChanges();
expect(component).toBeTruthy();
});
- describe('Inputs', () => {
- it('should accept filters as required input', () => {
- fixture.componentRef.setInput('filters', mockFilters);
- fixture.detectChanges();
-
- expect(component.filters()).toEqual(mockFilters);
- });
-
- it('should have default empty object for filterOptions', () => {
- fixture.componentRef.setInput('filters', mockFilters);
- fixture.detectChanges();
-
- expect(component.filterOptions()).toEqual({});
+ it('should build chips from selected options', () => {
+ fixture.componentRef.setInput('filters', mockFilters);
+ fixture.componentRef.setInput('filterOptions', {
+ subject: [biologyOption],
});
+ fixture.detectChanges();
- it('should accept filterOptions input', () => {
- const filterOptions: Record = {
- subject: [
- { label: 'Psychology', value: 'psychology', cardSearchResultCount: 50 },
- { label: 'Biology', value: 'biology', cardSearchResultCount: 30 },
- ],
- };
-
- fixture.componentRef.setInput('filters', mockFilters);
- fixture.componentRef.setInput('filterOptions', filterOptions);
- fixture.detectChanges();
-
- expect(component.filterOptions()).toEqual(filterOptions);
- });
+ expect(component.chips()).toEqual([
+ {
+ key: 'subject',
+ label: 'Subject',
+ displayValue: 'Biology',
+ option: biologyOption,
+ },
+ ]);
});
- describe('filterLabels computed', () => {
- it('should create labels from filters', () => {
- fixture.componentRef.setInput('filters', mockFilters);
- fixture.detectChanges();
-
- const labels = component.filterLabels();
- expect(labels.length).toBe(2);
- expect(labels).toContainEqual({ key: 'subject', label: 'Subject' });
- expect(labels).toContainEqual({ key: 'resourceType', label: 'Resource Type' });
- });
-
- it('should filter out filters without key or label', () => {
- const filtersWithMissing: DiscoverableFilter[] = [
- ...mockFilters,
- { key: '', label: 'No Key', operator: FilterOperatorOption.IsPresent, resultCount: 10, options: [] },
- { key: 'noLabel', label: '', operator: FilterOperatorOption.IsPresent, resultCount: 10, options: [] },
- ];
-
- fixture.componentRef.setInput('filters', filtersWithMissing);
- fixture.detectChanges();
-
- const labels = component.filterLabels();
- expect(labels.length).toBe(2);
- expect(labels.map((l) => l.key)).toEqual(['subject', 'resourceType']);
- });
-
- it('should return empty array when filters are empty', () => {
- fixture.componentRef.setInput('filters', []);
- fixture.detectChanges();
+ it('should keep only filters with key and label in filterLabels', () => {
+ fixture.componentRef.setInput('filters', [
+ ...mockFilters,
+ { key: '', label: 'Invalid', operator: FilterOperatorOption.AnyOf, options: [] } as DiscoverableFilter,
+ { key: 'invalid', label: '', operator: FilterOperatorOption.AnyOf, options: [] } as DiscoverableFilter,
+ ]);
+ fixture.componentRef.setInput('filterOptions', {});
+ fixture.detectChanges();
- const labels = component.filterLabels();
- expect(labels).toEqual([]);
- });
+ expect(component.filterLabels()).toEqual([
+ { key: 'subject', label: 'Subject' },
+ { key: 'hasData', label: 'Has Data' },
+ ]);
});
- describe('chips computed', () => {
- it('should create chips from filterOptions', () => {
- const filterOptions: Record = {
- subject: [{ label: 'Psychology', value: 'psychology', cardSearchResultCount: 50 }],
- resourceType: [{ label: 'Project', value: 'project', cardSearchResultCount: 40 }],
- };
-
- fixture.componentRef.setInput('filters', mockFilters);
- fixture.componentRef.setInput('filterOptions', filterOptions);
- fixture.detectChanges();
-
- const chips = component.chips();
- expect(chips.length).toBe(2);
- });
-
- it('should filter out empty filter options', () => {
- const filterOptions: Record = {
- subject: [{ label: 'Psychology', value: 'psychology', cardSearchResultCount: 50 }],
- resourceType: [],
- };
-
- fixture.componentRef.setInput('filters', mockFilters);
- fixture.componentRef.setInput('filterOptions', filterOptions);
- fixture.detectChanges();
-
- const chips = component.chips();
- expect(chips.length).toBe(1);
- expect(chips[0].key).toBe('subject');
+ it('should use filter key when label is missing for a selected option', () => {
+ fixture.componentRef.setInput('filters', mockFilters);
+ fixture.componentRef.setInput('filterOptions', {
+ unknownFilter: [biologyOption],
});
+ fixture.detectChanges();
- it('should use filter label from filterLabels', () => {
- const filterOptions: Record = {
- subject: [{ label: 'Psychology', value: 'psychology', cardSearchResultCount: 50 }],
- };
+ expect(component.chips()).toEqual([
+ {
+ key: 'unknownFilter',
+ label: 'unknownFilter',
+ displayValue: 'Biology',
+ option: biologyOption,
+ },
+ ]);
+ });
- fixture.componentRef.setInput('filters', mockFilters);
- fixture.componentRef.setInput('filterOptions', filterOptions);
- fixture.detectChanges();
+ it('should use option value when option label is empty', () => {
+ const valueOnlyOption: FilterOption = {
+ label: '',
+ value: 'custom-value',
+ cardSearchResultCount: 1,
+ };
- const chips = component.chips();
- expect(chips[0].label).toBe('Subject');
+ fixture.componentRef.setInput('filters', mockFilters);
+ fixture.componentRef.setInput('filterOptions', {
+ subject: [valueOnlyOption],
});
+ fixture.detectChanges();
- it('should use key as label when filter label not found', () => {
- const filterOptions: Record = {
- unknownKey: [{ label: 'Unknown', value: 'unknown', cardSearchResultCount: 10 }],
- };
-
- fixture.componentRef.setInput('filters', mockFilters);
- fixture.componentRef.setInput('filterOptions', filterOptions);
- fixture.detectChanges();
+ expect(component.chips()).toEqual([
+ {
+ key: 'subject',
+ label: 'Subject',
+ displayValue: 'custom-value',
+ option: valueOnlyOption,
+ },
+ ]);
+ });
- const chips = component.chips();
- expect(chips[0].label).toBe('unknownKey');
+ it('should ignore filter options with empty arrays', () => {
+ fixture.componentRef.setInput('filters', mockFilters);
+ fixture.componentRef.setInput('filterOptions', {
+ subject: [],
+ hasData: [trueOption],
});
+ fixture.detectChanges();
- it('should use option label as displayValue', () => {
- const filterOptions: Record = {
- subject: [{ label: 'Psychology', value: 'psychology', cardSearchResultCount: 50 }],
- };
-
- fixture.componentRef.setInput('filters', mockFilters);
- fixture.componentRef.setInput('filterOptions', filterOptions);
- fixture.detectChanges();
+ expect(component.chips()).toEqual([
+ {
+ key: 'hasData',
+ label: 'Has Data',
+ displayValue: 'true',
+ option: trueOption,
+ },
+ ]);
+ });
- const chips = component.chips();
- expect(chips[0].displayValue).toBe('Psychology');
+ it('should render label with displayValue for non-true values', () => {
+ fixture.componentRef.setInput('filters', mockFilters);
+ fixture.componentRef.setInput('filterOptions', {
+ subject: [biologyOption],
});
+ fixture.detectChanges();
- it('should use option value as displayValue when label is missing', () => {
- const filterOptions: Record = {
- subject: [{ value: 'psychology', cardSearchResultCount: 50 } as FilterOption],
- };
-
- fixture.componentRef.setInput('filters', mockFilters);
- fixture.componentRef.setInput('filterOptions', filterOptions);
- fixture.detectChanges();
+ const chipLabel = fixture.nativeElement.querySelector('.p-chip-label') as HTMLSpanElement;
- const chips = component.chips();
- expect(chips[0].displayValue).toBe('psychology');
- });
+ expect(chipLabel.textContent?.trim()).toBe('Subject: Biology');
+ });
- it('should handle multiple options for single filter', () => {
- const filterOptions: Record = {
- subject: [
- { label: 'Psychology', value: 'psychology', cardSearchResultCount: 50 },
- { label: 'Biology', value: 'biology', cardSearchResultCount: 30 },
- ],
- };
-
- fixture.componentRef.setInput('filters', mockFilters);
- fixture.componentRef.setInput('filterOptions', filterOptions);
- fixture.detectChanges();
-
- const chips = component.chips();
- expect(chips.length).toBe(2);
- expect(chips[0].displayValue).toBe('Psychology');
- expect(chips[1].displayValue).toBe('Biology');
+ it('should render only label when displayValue is true string', () => {
+ fixture.componentRef.setInput('filters', mockFilters);
+ fixture.componentRef.setInput('filterOptions', {
+ hasData: [trueOption],
});
+ fixture.detectChanges();
- it('should return empty array when filterOptions is empty', () => {
- fixture.componentRef.setInput('filters', mockFilters);
- fixture.componentRef.setInput('filterOptions', {});
- fixture.detectChanges();
+ const chipLabel = fixture.nativeElement.querySelector('.p-chip-label') as HTMLSpanElement;
- const chips = component.chips();
- expect(chips).toEqual([]);
- });
+ expect(chipLabel.textContent?.trim()).toBe('Has Data');
});
- describe('removeFilter', () => {
- it('should emit selectedOptionRemoved with correct data', () => {
- const emitSpy = jest.fn();
- component.selectedOptionRemoved.subscribe(emitSpy);
-
- const mockOption: FilterOption = { label: 'Psychology', value: 'psychology', cardSearchResultCount: 50 };
-
- fixture.componentRef.setInput('filters', mockFilters);
- fixture.detectChanges();
-
- component.removeFilter('subject', mockOption);
-
- expect(emitSpy).toHaveBeenCalledWith({
- filterKey: 'subject',
- optionRemoved: mockOption,
- });
- });
-
- it('should emit with different filter keys', () => {
- const emitSpy = jest.fn();
- component.selectedOptionRemoved.subscribe(emitSpy);
-
- const mockOption1: FilterOption = { label: 'Psychology', value: 'psychology', cardSearchResultCount: 50 };
- const mockOption2: FilterOption = { label: 'Project', value: 'project', cardSearchResultCount: 40 };
+ it('should emit selectedOptionRemoved when removeFilter is called', () => {
+ fixture.componentRef.setInput('filters', mockFilters);
+ fixture.componentRef.setInput('filterOptions', {});
+ fixture.detectChanges();
- fixture.componentRef.setInput('filters', mockFilters);
- fixture.detectChanges();
+ const emitSpy = jest.spyOn(component.selectedOptionRemoved, 'emit');
- component.removeFilter('subject', mockOption1);
- component.removeFilter('resourceType', mockOption2);
+ component.removeFilter('subject', biologyOption);
- expect(emitSpy).toHaveBeenCalledTimes(2);
- expect(emitSpy).toHaveBeenNthCalledWith(1, {
- filterKey: 'subject',
- optionRemoved: mockOption1,
- });
- expect(emitSpy).toHaveBeenNthCalledWith(2, {
- filterKey: 'resourceType',
- optionRemoved: mockOption2,
- });
+ expect(emitSpy).toHaveBeenCalledWith({
+ filterKey: 'subject',
+ optionRemoved: biologyOption,
});
});
});
diff --git a/src/app/shared/components/filter-chips/filter-chips.component.ts b/src/app/shared/components/filter-chips/filter-chips.component.ts
index 4550c4d62..953bb7431 100644
--- a/src/app/shared/components/filter-chips/filter-chips.component.ts
+++ b/src/app/shared/components/filter-chips/filter-chips.component.ts
@@ -3,7 +3,7 @@ import { Chip } from 'primeng/chip';
import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';
-import { DiscoverableFilter, FilterOption } from '@osf/shared/models/search/discaverable-filter.model';
+import { DiscoverableFilter, FilterOption } from '@osf/shared/models/search/discoverable-filter.model';
@Component({
selector: 'osf-filter-chips',
@@ -17,14 +17,14 @@ export class FilterChipsComponent {
selectedOptionRemoved = output<{ filterKey: string; optionRemoved: FilterOption }>();
- filterLabels = computed(() => {
- return this.filters()
+ filterLabels = computed(() =>
+ this.filters()
.filter((filter) => filter.key && filter.label)
.map((filter) => ({
key: filter.key,
label: filter.label,
- }));
- });
+ }))
+ );
chips = computed(() => {
const options = this.filterOptions();
diff --git a/src/app/shared/components/generic-filter/generic-filter.component.spec.ts b/src/app/shared/components/generic-filter/generic-filter.component.spec.ts
index 1152ec047..684543927 100644
--- a/src/app/shared/components/generic-filter/generic-filter.component.spec.ts
+++ b/src/app/shared/components/generic-filter/generic-filter.component.spec.ts
@@ -4,7 +4,7 @@ import { ComponentRef } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
-import { FilterOperatorOption, FilterOption } from '@osf/shared/models/search/discaverable-filter.model';
+import { FilterOperatorOption, FilterOption } from '@osf/shared/models/search/discoverable-filter.model';
import { LoadingSpinnerComponent } from '../loading-spinner/loading-spinner.component';
diff --git a/src/app/shared/components/generic-filter/generic-filter.component.ts b/src/app/shared/components/generic-filter/generic-filter.component.ts
index 041160d70..0929b3c35 100644
--- a/src/app/shared/components/generic-filter/generic-filter.component.ts
+++ b/src/app/shared/components/generic-filter/generic-filter.component.ts
@@ -19,7 +19,7 @@ import {
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormsModule } from '@angular/forms';
-import { FilterOperatorOption, FilterOption } from '@osf/shared/models/search/discaverable-filter.model';
+import { FilterOperatorOption, FilterOption } from '@osf/shared/models/search/discoverable-filter.model';
import { LoadingSpinnerComponent } from '../loading-spinner/loading-spinner.component';
diff --git a/src/app/shared/components/global-search/global-search.component.spec.ts b/src/app/shared/components/global-search/global-search.component.spec.ts
index 6e4887249..2b11c8b67 100644
--- a/src/app/shared/components/global-search/global-search.component.spec.ts
+++ b/src/app/shared/components/global-search/global-search.component.spec.ts
@@ -5,12 +5,12 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormControl } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
-import { ResourceType } from '@shared/enums/resource-type.enum';
import {
DiscoverableFilter,
FilterOperatorOption,
FilterOption,
-} from '@shared/models/search/discaverable-filter.model';
+} from '@osf/shared/models/search/discoverable-filter.model';
+import { ResourceType } from '@shared/enums/resource-type.enum';
import { GlobalSearchSelectors } from '@shared/stores/global-search';
import { FilterChipsComponent } from '../filter-chips/filter-chips.component';
diff --git a/src/app/shared/components/global-search/global-search.component.ts b/src/app/shared/components/global-search/global-search.component.ts
index 3da3dc8bd..86015b0dd 100644
--- a/src/app/shared/components/global-search/global-search.component.ts
+++ b/src/app/shared/components/global-search/global-search.component.ts
@@ -22,9 +22,9 @@ import { ActivatedRoute, Router } from '@angular/router';
import { PreprintProviderDetails } from '@osf/features/preprints/models';
import { normalizeQuotes } from '@osf/shared/helpers/normalize-quotes';
+import { DiscoverableFilter, FilterOption } from '@osf/shared/models/search/discoverable-filter.model';
import { SearchFiltersComponent } from '@shared/components/search-filters/search-filters.component';
import { ResourceType } from '@shared/enums/resource-type.enum';
-import { DiscoverableFilter, FilterOption } from '@shared/models/search/discaverable-filter.model';
import { TabOption } from '@shared/models/tab-option.model';
import {
ClearFilterSearchResults,
diff --git a/src/app/shared/components/search-filters/search-filters.component.spec.ts b/src/app/shared/components/search-filters/search-filters.component.spec.ts
index 1177919c0..fc759ba41 100644
--- a/src/app/shared/components/search-filters/search-filters.component.spec.ts
+++ b/src/app/shared/components/search-filters/search-filters.component.spec.ts
@@ -6,7 +6,7 @@ import {
DiscoverableFilter,
FilterOperatorOption,
FilterOption,
-} from '@osf/shared/models/search/discaverable-filter.model';
+} from '@osf/shared/models/search/discoverable-filter.model';
import { FILTER_PLACEHOLDERS } from '@shared/constants/filter-placeholders';
import { GenericFilterComponent } from '../generic-filter/generic-filter.component';
diff --git a/src/app/shared/components/search-filters/search-filters.component.ts b/src/app/shared/components/search-filters/search-filters.component.ts
index f8999fcf1..c87370fc3 100644
--- a/src/app/shared/components/search-filters/search-filters.component.ts
+++ b/src/app/shared/components/search-filters/search-filters.component.ts
@@ -16,7 +16,7 @@ import {
DiscoverableFilter,
FilterOperatorOption,
FilterOption,
-} from '@shared/models/search/discaverable-filter.model';
+} from '@osf/shared/models/search/discoverable-filter.model';
import { GenericFilterComponent } from '../generic-filter/generic-filter.component';
import { LoadingSpinnerComponent } from '../loading-spinner/loading-spinner.component';
diff --git a/src/app/shared/components/search-results-container/search-results-container.component.ts b/src/app/shared/components/search-results-container/search-results-container.component.ts
index 8e751b6f0..a65ea03d6 100644
--- a/src/app/shared/components/search-results-container/search-results-container.component.ts
+++ b/src/app/shared/components/search-results-container/search-results-container.component.ts
@@ -19,7 +19,7 @@ import { FormsModule } from '@angular/forms';
import { PreprintProviderDetails } from '@osf/features/preprints/models';
import { searchSortingOptions } from '@osf/shared/constants/search-sort-options.const';
import { ResourceType } from '@osf/shared/enums/resource-type.enum';
-import { DiscoverableFilter, FilterOption } from '@shared/models/search/discaverable-filter.model';
+import { DiscoverableFilter, FilterOption } from '@osf/shared/models/search/discoverable-filter.model';
import { ResourceModel } from '@shared/models/search/resource.model';
import { TabOption } from '@shared/models/tab-option.model';
diff --git a/src/app/shared/mappers/filters/filter-option.mapper.ts b/src/app/shared/mappers/filters/filter-option.mapper.ts
index df77250b3..a408a1a66 100644
--- a/src/app/shared/mappers/filters/filter-option.mapper.ts
+++ b/src/app/shared/mappers/filters/filter-option.mapper.ts
@@ -1,4 +1,4 @@
-import { FilterOption } from '@osf/shared/models/search/discaverable-filter.model';
+import { FilterOption } from '@osf/shared/models/search/discoverable-filter.model';
import { FilterOptionItem } from '@osf/shared/models/search/filter-options-json-api.model';
import { SearchResultDataJsonApi } from '@osf/shared/models/search/index-card-search-json-api.model';
diff --git a/src/app/shared/mappers/filters/filters.mapper.ts b/src/app/shared/mappers/filters/filters.mapper.ts
index 6cee8c2d6..91086a975 100644
--- a/src/app/shared/mappers/filters/filters.mapper.ts
+++ b/src/app/shared/mappers/filters/filters.mapper.ts
@@ -1,4 +1,4 @@
-import { DiscoverableFilter, FilterOperatorOption } from '@osf/shared/models/search/discaverable-filter.model';
+import { DiscoverableFilter, FilterOperatorOption } from '@osf/shared/models/search/discoverable-filter.model';
import {
IndexCardSearchResponseJsonApi,
RelatedPropertyPathDataJsonApi,
diff --git a/src/app/shared/models/search/discaverable-filter.model.ts b/src/app/shared/models/search/discoverable-filter.model.ts
similarity index 100%
rename from src/app/shared/models/search/discaverable-filter.model.ts
rename to src/app/shared/models/search/discoverable-filter.model.ts
diff --git a/src/app/shared/models/search/resource.model.ts b/src/app/shared/models/search/resource.model.ts
index d5b9ba320..964a4aace 100644
--- a/src/app/shared/models/search/resource.model.ts
+++ b/src/app/shared/models/search/resource.model.ts
@@ -1,7 +1,7 @@
import { ResourceType } from '@osf/shared/enums/resource-type.enum';
import { StringOrNull } from '@osf/shared/helpers/types.helper';
-import { DiscoverableFilter } from './discaverable-filter.model';
+import { DiscoverableFilter } from './discoverable-filter.model';
export interface ResourceModel {
absoluteUrl: string;
diff --git a/src/app/shared/services/global-search.service.ts b/src/app/shared/services/global-search.service.ts
index 626609c6e..0b62d6178 100644
--- a/src/app/shared/services/global-search.service.ts
+++ b/src/app/shared/services/global-search.service.ts
@@ -8,7 +8,7 @@ import { parseSearchTotalCount } from '../helpers/search-total-count.helper';
import { mapFilterOptions } from '../mappers/filters/filter-option.mapper';
import { MapFilters } from '../mappers/filters/filters.mapper';
import { MapResources } from '../mappers/search';
-import { FilterOption } from '../models/search/discaverable-filter.model';
+import { FilterOption } from '../models/search/discoverable-filter.model';
import { FilterOptionItem, FilterOptionsResponseJsonApi } from '../models/search/filter-options-json-api.model';
import {
IndexCardSearchResponseJsonApi,
diff --git a/src/app/shared/stores/global-search/global-search.actions.ts b/src/app/shared/stores/global-search/global-search.actions.ts
index 00dfa8d38..597741cfd 100644
--- a/src/app/shared/stores/global-search/global-search.actions.ts
+++ b/src/app/shared/stores/global-search/global-search.actions.ts
@@ -1,6 +1,6 @@
import { StringOrNull } from '@osf/shared/helpers/types.helper';
+import { FilterOption } from '@osf/shared/models/search/discoverable-filter.model';
import { ResourceType } from '@shared/enums/resource-type.enum';
-import { FilterOption } from '@shared/models/search/discaverable-filter.model';
export class FetchResources {
static readonly type = '[GlobalSearch] Fetch Resources';
diff --git a/src/app/shared/stores/global-search/global-search.model.ts b/src/app/shared/stores/global-search/global-search.model.ts
index 2174a080c..65aeaa7d8 100644
--- a/src/app/shared/stores/global-search/global-search.model.ts
+++ b/src/app/shared/stores/global-search/global-search.model.ts
@@ -1,6 +1,6 @@
import { ResourceType } from '@osf/shared/enums/resource-type.enum';
import { StringOrNull } from '@osf/shared/helpers/types.helper';
-import { DiscoverableFilter, FilterOption } from '@osf/shared/models/search/discaverable-filter.model';
+import { DiscoverableFilter, FilterOption } from '@osf/shared/models/search/discoverable-filter.model';
import { ResourceModel } from '@osf/shared/models/search/resource.model';
import { AsyncStateModel } from '@osf/shared/models/store/async-state.model';
diff --git a/src/app/shared/stores/global-search/global-search.selectors.ts b/src/app/shared/stores/global-search/global-search.selectors.ts
index 01b5add12..c655d9f20 100644
--- a/src/app/shared/stores/global-search/global-search.selectors.ts
+++ b/src/app/shared/stores/global-search/global-search.selectors.ts
@@ -2,7 +2,7 @@ import { Selector } from '@ngxs/store';
import { ResourceType } from '@osf/shared/enums/resource-type.enum';
import { StringOrNull } from '@osf/shared/helpers/types.helper';
-import { DiscoverableFilter, FilterOption } from '@osf/shared/models/search/discaverable-filter.model';
+import { DiscoverableFilter, FilterOption } from '@osf/shared/models/search/discoverable-filter.model';
import { ResourceModel } from '@osf/shared/models/search/resource.model';
import { GlobalSearchStateModel } from './global-search.model';
diff --git a/src/app/shared/stores/global-search/global-search.state.ts b/src/app/shared/stores/global-search/global-search.state.ts
index 78e7c552b..bf15f8ca0 100644
--- a/src/app/shared/stores/global-search/global-search.state.ts
+++ b/src/app/shared/stores/global-search/global-search.state.ts
@@ -6,8 +6,8 @@ import { inject, Injectable } from '@angular/core';
import { ENVIRONMENT } from '@core/provider/environment.provider';
import { getResourceTypeStringFromEnum } from '@osf/shared/helpers/get-resource-types.helper';
+import { FilterOperatorOption } from '@osf/shared/models/search/discoverable-filter.model';
import { GlobalSearchService } from '@osf/shared/services/global-search.service';
-import { FilterOperatorOption } from '@shared/models/search/discaverable-filter.model';
import { ResourcesData } from '@shared/models/search/resource.model';
import {
@@ -192,6 +192,7 @@ export class GlobalSearchState {
loadFilterOptionsAndSetValues(ctx: StateContext, action: LoadFilterOptionsAndSetValues) {
const filterValues = action.filterValues;
const filterKeys = Object.keys(filterValues).filter((key) => filterValues[key]);
+
if (!filterKeys.length) return;
const loadingFilters = ctx