Skip to content

Commit

Permalink
refactor to shorten the codes
Browse files Browse the repository at this point in the history
  • Loading branch information
rrchai committed May 13, 2024
1 parent 918ce06 commit bfd75b8
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ import {
import {
ChallengePlatformSearchQuery,
ChallengePlatformService,
ChallengePlatformSort,
EdamConceptSearchQuery,
EdamConceptService,
EdamConceptSort,
EdamSection,
Image,
ImageAspectRatio,
ImageHeight,
Expand All @@ -21,22 +24,30 @@ import {
Organization,
OrganizationSearchQuery,
OrganizationService,
OrganizationSort,
} from '@sagebionetworks/openchallenges/api-client-angular';
import { forkJoinConcurrent } from '@sagebionetworks/openchallenges/util';
import { Filter } from '@sagebionetworks/openchallenges/ui';
import { ChallengeSearchDropdown } from './challenge-search-dropdown';

@Injectable({
providedIn: 'root',
})
export class ChallengeSearchDataService {
private edamConceptSearchQuery: BehaviorSubject<EdamConceptSearchQuery> =
new BehaviorSubject<EdamConceptSearchQuery>({});
new BehaviorSubject<EdamConceptSearchQuery>({
sort: EdamConceptSort.PreferredLabel,
});

private organizationSearchQuery: BehaviorSubject<OrganizationSearchQuery> =
new BehaviorSubject<OrganizationSearchQuery>({});
new BehaviorSubject<OrganizationSearchQuery>({
sort: OrganizationSort.Name,
});

private platformSearchQuery: BehaviorSubject<ChallengePlatformSearchQuery> =
new BehaviorSubject<ChallengePlatformSearchQuery>({});
new BehaviorSubject<ChallengePlatformSearchQuery>({
sort: ChallengePlatformSort.Name,
});

constructor(
private challengePlatformService: ChallengePlatformService,
Expand All @@ -45,16 +56,19 @@ export class ChallengeSearchDataService {
private organizationService: OrganizationService
) {}

setEdamConceptSearch(searchQuery: EdamConceptSearchQuery) {
this.edamConceptSearchQuery.next({ ...searchQuery });
setEdamConceptSearchQuery(searchQuery: EdamConceptSearchQuery) {
const currentState = this.edamConceptSearchQuery.getValue();
this.edamConceptSearchQuery.next({ ...currentState, ...searchQuery });
}

setOriganizationSearch(searchQuery: OrganizationSearchQuery) {
this.organizationSearchQuery.next({ ...searchQuery });
setOriganizationSearchQuery(searchQuery: OrganizationSearchQuery) {
const currentState = this.organizationSearchQuery.getValue();
this.organizationSearchQuery.next({ ...currentState, ...searchQuery });
}

setPlatformSearch(searchQuery: ChallengePlatformSearchQuery) {
this.platformSearchQuery.next({ ...searchQuery });
setPlatformSearchQuery(searchQuery: ChallengePlatformSearchQuery) {
const currentState = this.platformSearchQuery.getValue();
this.platformSearchQuery.next({ ...currentState, ...searchQuery });
}

getEdamConcepts(newQuery: EdamConceptSearchQuery): Observable<Filter[]> {
Expand Down Expand Up @@ -150,4 +164,38 @@ export class ChallengeSearchDataService {
)
);
}

setSearchQuery(dropdown: ChallengeSearchDropdown, searchQuery = {}) {
const extraParams = {
inputDataTypes: {
sections: [EdamSection.Data],
},
operations: {
sections: [EdamSection.Operation],
sort: EdamConceptSort.PreferredLabel,
},
};

const setQueryMethods = {
inputDataTypes: () =>
this.setEdamConceptSearchQuery({
...extraParams.inputDataTypes,
...searchQuery,
}),
organizations: () => this.setOriganizationSearchQuery(searchQuery),
platforms: () => this.setPlatformSearchQuery(searchQuery),
};

return setQueryMethods[dropdown]();
}

fetchData(dropdown: ChallengeSearchDropdown) {
const fetchDataMethods = {
inputDataTypes: this.getEdamConcepts.bind(this),
organizations: this.getOriganizations.bind(this),
platforms: this.getPlatforms.bind(this),
};

return fetchDataMethods[dropdown];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@ <h2>Challenges</h2>
</p-panel>
<p-divider></p-divider>
<p-panel
header="{{ platformsFilter.label }}"
header="{{ dropdownFilters['platforms'].label }}"
[toggleable]="true"
[collapsed]="platformsFilter.collapsed"
[collapsed]="dropdownFilters['platforms'].collapsed"
>
<openchallenges-search-dropdown-filter
[options]="platformsFilter.options"
[options]="dropdownFilters['platforms'].options"
[selectedOptions]="selectedPlatforms"
placeholder="{{ platformsFilter.label.toLowerCase() + '(s)' }} "
[showAvatar]="platformsFilter.showAvatar"
placeholder="{{ dropdownFilters['platforms'].label.toLowerCase() + '(s)' }} "
[showAvatar]="dropdownFilters['platforms'].showAvatar"
[filterByApiClient]="true"
(selectionChange)="onParamChange({ platforms: $event })"
(searchChange)="onSearchChange('platforms', $event)"
Expand All @@ -91,15 +91,15 @@ <h2>Challenges</h2>
</p-panel>
<p-divider></p-divider>
<p-panel
header="{{ inputDataTypesFilter.label }}"
header="{{ dropdownFilters['inputDataTypes'].label }}"
[toggleable]="true"
[collapsed]="inputDataTypesFilter.collapsed"
[collapsed]="dropdownFilters['inputDataTypes'].collapsed"
>
<openchallenges-search-dropdown-filter
[options]="inputDataTypesFilter.options"
[options]="dropdownFilters['inputDataTypes'].options"
[selectedOptions]="selectedInputDataTypes"
placeholder="{{ inputDataTypesFilter.label.toLowerCase() + '(s)' }} "
[showAvatar]="inputDataTypesFilter.showAvatar"
placeholder="{{ dropdownFilters['inputDataTypes'].label.toLowerCase() + '(s)' }} "
[showAvatar]="dropdownFilters['inputDataTypes'].showAvatar"
[filterByApiClient]="true"
(selectionChange)="onParamChange({ inputDataTypes: $event })"
(searchChange)="onSearchChange('inputDataTypes', $event)"
Expand All @@ -108,15 +108,15 @@ <h2>Challenges</h2>
</p-panel>
<p-divider></p-divider>
<p-panel
header="{{ organizationsFilter.label }}"
header="{{ dropdownFilters['organizations'].label }}"
[toggleable]="true"
[collapsed]="organizationsFilter.collapsed"
[collapsed]="dropdownFilters['organizations'].collapsed"
>
<openchallenges-search-dropdown-filter
[options]="organizationsFilter.options"
[options]="dropdownFilters['organizations'].options"
[selectedOptions]="selectedOrgs"
placeholder="{{ organizationsFilter.label.toLowerCase() + '(s)' }} "
[showAvatar]="organizationsFilter.showAvatar"
placeholder="{{ dropdownFilters['organizations'].label.toLowerCase() + '(s)' }} "
[showAvatar]="dropdownFilters['organizations'].showAvatar"
[filterByApiClient]="true"
(selectionChange)="onParamChange({ organizations: $event })"
(searchChange)="onSearchChange('organizations', $event)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,11 @@ import {
Challenge,
ChallengeCategory,
ChallengeIncentive,
ChallengePlatformSort,
ChallengeSearchQuery,
ChallengeService,
ChallengeSort,
ChallengeStatus,
ChallengeSubmissionType,
EdamSection,
OrganizationSort,
} from '@sagebionetworks/openchallenges/api-client-angular';
import { ConfigService } from '@sagebionetworks/openchallenges/config';
import {
Expand Down Expand Up @@ -68,6 +65,7 @@ import { getSeoData } from './challenge-search-seo-data';
import { HttpParams } from '@angular/common/http';
import { ChallengeSearchDataService } from './challenge-search-data.service';
import { MultiSelectLazyLoadEvent } from 'primeng/multiselect';
import { ChallengeSearchDropdown } from './challenge-search-dropdown';

@Component({
selector: 'openchallenges-challenge-search',
Expand Down Expand Up @@ -148,9 +146,18 @@ export class ChallengeSearchComponent
submissionTypesFilter = challengeSubmissionTypesFilterPanel;

// dropdown filters
inputDataTypesFilter = challengeInputDataTypesFilterPanel;
organizationsFilter = challengeOrganizationsFilterPanel;
platformsFilter = challengePlatformsFilterPanel;
dropdownFilters: { [key: string]: FilterPanel } = {
inputDataTypes: challengeInputDataTypesFilterPanel,
organizations: challengeOrganizationsFilterPanel,
platforms: challengePlatformsFilterPanel,
};

// record loaded pages for dropdown filters
loadedPages: { [key: string]: Set<number> } = {
inputDataTypes: new Set(),
organizations: new Set(),
platforms: new Set(),
};

// define selected filter values
selectedCategories!: ChallengeCategory[];
Expand All @@ -161,11 +168,6 @@ export class ChallengeSearchComponent
selectedStatus!: ChallengeStatus[];
selectedSubmissionTypes!: ChallengeSubmissionType[];

// record loaded pages for dropdown filters
inputDataTypesLoadedPages: Set<number> = new Set();
organizationLoadedPages: Set<number> = new Set();
platformsLoadedPages: Set<number> = new Set();

constructor(
private activatedRoute: ActivatedRoute,
private challengeService: ChallengeService,
Expand Down Expand Up @@ -354,91 +356,45 @@ export class ChallengeSearchComponent
}

onSearchChange(
searchType: 'challenges' | 'inputDataTypes' | 'organizations' | 'platforms',
dropdown: 'challenges' | ChallengeSearchDropdown,
searched: string
): void {
this.inputDataTypesLoadedPages.clear();
this.organizationLoadedPages.clear();
this.platformsLoadedPages.clear();
this.inputDataTypesFilter.options = [];
this.organizationsFilter.options = [];
this.platformsFilter.options = [];
switch (searchType) {
case 'challenges':
this.challengeSearchTerms.next(searched);
break;
case 'inputDataTypes':
this.challengeSearchDataService.setEdamConceptSearch({
searchTerms: searched,
sections: [EdamSection.Data],
});
break;
case 'organizations':
this.challengeSearchDataService.setOriganizationSearch({
searchTerms: searched,
sort: OrganizationSort.Name,
});
break;
case 'platforms':
this.challengeSearchDataService.setPlatformSearch({
searchTerms: searched,
sort: ChallengePlatformSort.Name,
});
break;
this.loadedPages[dropdown].clear();
this.dropdownFilters[dropdown].options = [];

if (dropdown === 'challenges') {
this.challengeSearchTerms.next(searched);
} else {
this.challengeSearchDataService.setSearchQuery(dropdown, {
searchTerms: searched,
});
}
}

onLazyLoad(
type: 'inputDataTypes' | 'organizations' | 'platforms',
event: MultiSelectLazyLoadEvent
dropdown: ChallengeSearchDropdown,
event: MultiSelectLazyLoadEvent,
extraParams?: any
): void {
const configs = {
inputDataTypes: {
loadedPages: this.inputDataTypesLoadedPages,
dataServiceMethod: this.challengeSearchDataService.getEdamConcepts.bind(
this.challengeSearchDataService
),
optionsFilter: this.inputDataTypesFilter,
extraParams: { sections: [EdamSection.Data] },
},
organizations: {
loadedPages: this.organizationLoadedPages,
dataServiceMethod:
this.challengeSearchDataService.getOriganizations.bind(
this.challengeSearchDataService
),
optionsFilter: this.organizationsFilter,
extraParams: {},
},
platforms: {
loadedPages: this.platformsLoadedPages,
dataServiceMethod: this.challengeSearchDataService.getPlatforms.bind(
this.challengeSearchDataService
),
optionsFilter: this.platformsFilter,
extraParams: {},
},
};

const config = configs[type];
const size = this.defaultPageSize;
const startPage = Math.floor(event.first / size);
const endPage = Math.floor(event.last / size);

for (let page = startPage; page <= endPage; page++) {
if (!config.loadedPages.has(page)) {
config.loadedPages.add(page);
config
.dataServiceMethod({
if (!this.loadedPages[dropdown].has(page)) {
this.loadedPages[dropdown].add(page);

this.challengeSearchDataService
.fetchData(dropdown)({
pageNumber: page,
pageSize: size,
...config.extraParams,
...extraParams,
})
.pipe(takeUntil(this.destroy))
.subscribe((newOptions) => {
// combine old and new results by taking unique filter values
config.optionsFilter.options = unionWith(
config.optionsFilter.options,
this.dropdownFilters[dropdown].options = unionWith(
this.dropdownFilters[dropdown].options,
newOptions,
isEqual
);
Expand All @@ -448,9 +404,19 @@ export class ChallengeSearchComponent
}

private loadInitialDropdownData(): void {
this.onLazyLoad('platforms', { first: 0, last: this.defaultPageSize });
// this.onLazyLoad('platforms', { first: 0, last: this.defaultPageSize });
// this.onLazyLoad('platforms', { first: 0, last: this.defaultPageSize });
// define default how many items to load
const viewportRange = { first: 0, last: this.defaultPageSize };

// load initial data and reset the loaded pages
const dropdowns = [
'inputDataTypes',
'organizations',
'platforms',
] as ChallengeSearchDropdown[];
dropdowns.forEach((dropdown) => {
this.onLazyLoad(dropdown, viewportRange);
this.loadedPages[dropdown].clear();
});
}

dateToFormat(date: Date, format?: 'yyyy-MM-dd'): string | null {
Expand Down

0 comments on commit bfd75b8

Please sign in to comment.