diff --git a/libs/openchallenges/challenge-search/src/lib/challenge-search-data.service.ts b/libs/openchallenges/challenge-search/src/lib/challenge-search-data.service.ts index ed9a59fe40..dbafc84db8 100644 --- a/libs/openchallenges/challenge-search/src/lib/challenge-search-data.service.ts +++ b/libs/openchallenges/challenge-search/src/lib/challenge-search-data.service.ts @@ -11,6 +11,8 @@ import { ChallengePlatformSearchQuery, ChallengePlatformService, ChallengePlatformSort, + EdamConceptSearchQuery, + EdamConceptService, Image, ImageAspectRatio, ImageHeight, @@ -28,44 +30,48 @@ import { Filter } from '@sagebionetworks/openchallenges/ui'; providedIn: 'root', }) export class ChallengeSearchDataService { - private platformSearchTerms: BehaviorSubject = - new BehaviorSubject(''); + private edamConceptSearchTerms: BehaviorSubject = + new BehaviorSubject({ searchTerms: '' }); private organizationSearchTerms: BehaviorSubject = new BehaviorSubject(''); + private platformSearchTerms: BehaviorSubject = + new BehaviorSubject(''); + constructor( + private edamConceptService: EdamConceptService, private challengePlatformService: ChallengePlatformService, private organizationService: OrganizationService, private imageService: ImageService ) {} - setPlatformSearchTerms(searchTerms: string) { - this.platformSearchTerms.next(searchTerms); + setEdamConceptSearchTerms(searchQuery: EdamConceptSearchQuery) { + this.edamConceptSearchTerms.next(searchQuery); } setOriganizationSearchTerms(searchTerms: string) { this.organizationSearchTerms.next(searchTerms); } - searchPlatforms(): Observable { - return this.platformSearchTerms.pipe( + setPlatformSearchTerms(searchTerms: string) { + this.platformSearchTerms.next(searchTerms); + } + + searchEdamConcepts(): Observable { + return this.edamConceptSearchTerms.pipe( debounceTime(400), distinctUntilChanged(), - switchMap((searchTerm: string) => { - const sortedBy: ChallengePlatformSort = 'name'; - const platformQuery: ChallengePlatformSearchQuery = { - searchTerms: searchTerm, - sort: sortedBy, - }; - return this.challengePlatformService.listChallengePlatforms( - platformQuery - ); + switchMap((searchQuery: EdamConceptSearchQuery) => { + // const sortedBy: EdamSort = 'name'; + const edamQuery: EdamConceptSearchQuery = searchQuery; + console.log(edamQuery); + return this.edamConceptService.listEdamConcepts(edamQuery); }), map((page) => - page.challengePlatforms.map((platform) => ({ - value: platform.slug, - label: platform.name, + page.edamConcepts.map((edamConcept) => ({ + value: edamConcept.classId, + label: edamConcept.preferredLabel, active: false, })) ) @@ -123,4 +129,28 @@ export class ChallengeSearchDataService { }) ); } + + searchPlatforms(): Observable { + return this.platformSearchTerms.pipe( + debounceTime(400), + distinctUntilChanged(), + switchMap((searchTerm: string) => { + const sortedBy: ChallengePlatformSort = 'name'; + const platformQuery: ChallengePlatformSearchQuery = { + searchTerms: searchTerm, + sort: sortedBy, + }; + return this.challengePlatformService.listChallengePlatforms( + platformQuery + ); + }), + map((page) => + page.challengePlatforms.map((platform) => ({ + value: platform.slug, + label: platform.name, + active: false, + })) + ) + ); + } } diff --git a/libs/openchallenges/challenge-search/src/lib/challenge-search-filter-panels.ts b/libs/openchallenges/challenge-search/src/lib/challenge-search-filter-panels.ts index bc0139893a..9fa42eb0c5 100644 --- a/libs/openchallenges/challenge-search/src/lib/challenge-search-filter-panels.ts +++ b/libs/openchallenges/challenge-search/src/lib/challenge-search-filter-panels.ts @@ -18,18 +18,10 @@ export const challengeStartYearRangeFilterPanel: FilterPanel = { collapsed: false, }; -// checkbox filters -export const challengeStatusFilterPanel: FilterPanel = { - query: 'status', - label: 'Status', - options: challengeStatusFilter, - collapsed: false, -}; - -export const challengeSubmissionTypesFilterPanel: FilterPanel = { - query: 'submissionTypes', - label: 'Submission Type', - options: challengeSubmissionTypesFilter, +export const challengeCategoriesFilterPanel: FilterPanel = { + query: 'categories', + label: 'Category', + options: challengeCategoriesFilter, collapsed: false, }; @@ -40,27 +32,11 @@ export const challengeIncentivesFilterPanel: FilterPanel = { collapsed: false, }; -export const challengePlatformsFilterPanel: FilterPanel = { - query: 'platforms', - label: 'Platform', - options: challengePlatformsFilter, - collapsed: false, -}; - -// dropdown filters export const challengeInputDataTypesFilterPanel: FilterPanel = { query: 'inputDataTypes', label: 'Input Data Type', options: challengeInputDataTypesFilter, collapsed: false, - showAvatar: false, -}; - -export const challengeCategoriesFilterPanel: FilterPanel = { - query: 'categories', - label: 'Category', - options: challengeCategoriesFilter, - collapsed: false, }; export const challengeOrganizationsFilterPanel: FilterPanel = { @@ -78,3 +54,24 @@ export const challengeOrganizatersFilterPanel: FilterPanel = { collapsed: false, showAvatar: true, }; + +export const challengePlatformsFilterPanel: FilterPanel = { + query: 'platforms', + label: 'Platform', + options: challengePlatformsFilter, + collapsed: false, +}; + +export const challengeStatusFilterPanel: FilterPanel = { + query: 'status', + label: 'Status', + options: challengeStatusFilter, + collapsed: false, +}; + +export const challengeSubmissionTypesFilterPanel: FilterPanel = { + query: 'submissionTypes', + label: 'Submission Type', + options: challengeSubmissionTypesFilter, + collapsed: false, +}; diff --git a/libs/openchallenges/challenge-search/src/lib/challenge-search.component.html b/libs/openchallenges/challenge-search/src/lib/challenge-search.component.html index 225a188b17..6e9588045b 100644 --- a/libs/openchallenges/challenge-search/src/lib/challenge-search.component.html +++ b/libs/openchallenges/challenge-search/src/lib/challenge-search.component.html @@ -89,6 +89,22 @@

Challenges

/> + + + + (); + @ViewChild('calendar') calendar?: Calendar; + @ViewChild('paginator', { static: false }) paginator!: PaginatorComponent; + challenges: Challenge[] = []; totalChallengesCount = 0; searchResultsCount!: number; - @ViewChild('calendar') calendar?: Calendar; customMonthRange!: Date[] | undefined; isCustomYear = false; refreshed = true; - selectedYear!: DateRange | string | undefined; - selectedMinStartDate!: string | undefined; - selectedMaxStartDate!: string | undefined; searchedTerms!: string; + selectedMaxStartDate!: string | undefined; + selectedMinStartDate!: string | undefined; selectedPageNumber!: number; selectedPageSize!: number; + selectedYear!: DateRange | string | undefined; sortedBy!: ChallengeSort; // set default values - defaultSelectedYear = undefined; - defaultSortedBy: ChallengeSort = 'relevance'; defaultPageNumber = 0; defaultPageSize = 24; - @ViewChild('paginator', { static: false }) paginator!: PaginatorComponent; + defaultSelectedYear = undefined; + defaultSortedBy: ChallengeSort = 'relevance'; // define filters sortFilters: Filter[] = challengeSortFilter; startYearRangeFilter: FilterPanel = challengeStartYearRangeFilterPanel; // checkbox filters + categoriesFilter = challengeCategoriesFilterPanel; + incentivesFilter = challengeIncentivesFilterPanel; statusFilter = challengeStatusFilterPanel; submissionTypesFilter = challengeSubmissionTypesFilterPanel; - incentivesFilter = challengeIncentivesFilterPanel; - categoriesFilter = challengeCategoriesFilterPanel; // dropdown filters - platformsFilter = challengePlatformsFilterPanel; + inputDataTypesFilter = challengeInputDataTypesFilterPanel; organizationsFilter = challengeOrganizationsFilterPanel; + platformsFilter = challengePlatformsFilterPanel; // define selected filter values - selectedStatus!: ChallengeStatus[]; - selectedSubmissionTypes!: ChallengeSubmissionType[]; - selectedIncentives!: ChallengeIncentive[]; + selectedCategories!: ChallengeCategory[]; - selectedPlatforms!: string[]; + selectedIncentives!: ChallengeIncentive[]; + // selectedInputDataTypes!: ChallengeInputDataType[]; + selectedInputDataTypes!: any[]; selectedOrgs!: number[]; + selectedPlatforms!: string[]; + selectedStatus!: ChallengeStatus[]; + selectedSubmissionTypes!: ChallengeSubmissionType[]; constructor( private activatedRoute: ActivatedRoute, @@ -194,32 +202,34 @@ export class ChallengeSearchComponent } // update selected filter values based on params in url - this.selectedStatus = this.splitParam(params['status']); - this.selectedSubmissionTypes = this.splitParam(params['submissionTypes']); - this.selectedIncentives = this.splitParam(params['incentives']); - this.selectedPlatforms = this.splitParam(params['platforms']); + this.searchedTerms = params['searchTerms']; this.selectedCategories = this.splitParam(params['categories']); + this.selectedIncentives = this.splitParam(params['incentives']); + this.selectedInputDataTypes = this.splitParam(params['inputDataTypes']); this.selectedOrgs = this.splitParam(params['organizations']).map( (idString) => +idString ); - this.searchedTerms = params['searchTerms']; this.selectedPageNumber = +params['pageNumber'] || this.defaultPageNumber; this.selectedPageSize = this.defaultPageSize; // no available pageSize options for users + this.selectedPlatforms = this.splitParam(params['platforms']); + this.selectedStatus = this.splitParam(params['status']); + this.selectedSubmissionTypes = this.splitParam(params['submissionTypes']); this.sortedBy = params['sort'] || this.defaultSortedBy; const defaultQuery: ChallengeSearchQuery = { + categories: this.selectedCategories, + incentives: this.selectedIncentives, + // inputDataTypes: this.selectedInputDataTypes, + maxStartDate: this.selectedMaxStartDate, + minStartDate: this.selectedMinStartDate, + organizations: this.selectedOrgs, pageNumber: this.selectedPageNumber, pageSize: this.selectedPageSize, - sort: this.sortedBy, + platforms: this.selectedPlatforms, searchTerms: this.searchedTerms, - minStartDate: this.selectedMinStartDate, - maxStartDate: this.selectedMaxStartDate, + sort: this.sortedBy, status: this.selectedStatus, submissionTypes: this.selectedSubmissionTypes, - platforms: this.selectedPlatforms, - incentives: this.selectedIncentives, - categories: this.selectedCategories, - organizations: this.selectedOrgs, }; this.query.next(defaultQuery); @@ -232,15 +242,17 @@ export class ChallengeSearchComponent this.totalChallengesCount = page.totalElements; }); - // update platform filter values this.challengeSearchDataService - .searchPlatforms() + .searchEdamConcepts() .pipe(takeUntil(this.destroy)) .subscribe((options) => { - const selectedPlatformValues = options.filter((option) => - this.selectedPlatforms.includes(option.value as string) + const selectedInputDataTypesValues = options.filter((option) => + this.selectedInputDataTypes.includes(option.value as string) + ); + this.inputDataTypesFilter.options = union( + options, + selectedInputDataTypesValues ); - this.platformsFilter.options = union(options, selectedPlatformValues); }); // update organization filter values @@ -253,6 +265,17 @@ export class ChallengeSearchComponent ); this.organizationsFilter.options = union(options, selectedOrgValues); }); + + // update platform filter values + this.challengeSearchDataService + .searchPlatforms() + .pipe(takeUntil(this.destroy)) + .subscribe((options) => { + const selectedPlatformValues = options.filter((option) => + this.selectedPlatforms.includes(option.value as string) + ); + this.platformsFilter.options = union(options, selectedPlatformValues); + }); } ngAfterContentInit(): void { @@ -358,19 +381,25 @@ export class ChallengeSearchComponent } onSearchChange( - searchType: 'challenges' | 'platforms' | 'organizations', + searchType: 'challenges' | 'inputDataTypes' | 'organizations' | 'platforms', searched: string ): void { switch (searchType) { case 'challenges': this.challengeSearchTerms.next(searched); break; - case 'platforms': - this.challengeSearchDataService.setPlatformSearchTerms(searched); + case 'inputDataTypes': + this.challengeSearchDataService.setEdamConceptSearchTerms({ + searchTerms: searched, + sections: [EdamSection.Data], + }); break; case 'organizations': this.challengeSearchDataService.setOriganizationSearchTerms(searched); break; + case 'platforms': + this.challengeSearchDataService.setPlatformSearchTerms(searched); + break; } }