diff --git a/scripts/langindex.json b/scripts/langindex.json index 3bba525dc..332b659a6 100644 --- a/scripts/langindex.json +++ b/scripts/langindex.json @@ -36,6 +36,7 @@ "addon.block_calendarupcoming.pluginname": "block_calendar_upcoming", "addon.block_comments.pluginname": "block_comments", "addon.block_completionstatus.pluginname": "block_completionstatus", + "addon.block_globalsearch.pluginname": "block_globalsearch", "addon.block_glossaryrandom.pluginname": "block_glossary_random", "addon.block_learningplans.pluginname": "block_lp", "addon.block_myoverview.all": "block_myoverview", diff --git a/src/addons/block/block.module.ts b/src/addons/block/block.module.ts index f62aa4481..0989bedf9 100644 --- a/src/addons/block/block.module.ts +++ b/src/addons/block/block.module.ts @@ -41,6 +41,7 @@ import { AddonBlockSiteMainMenuModule } from './sitemainmenu/sitemainmenu.module import { AddonBlockStarredCoursesModule } from './starredcourses/starredcourses.module'; import { AddonBlockTagsModule } from './tags/tags.module'; import { AddonBlockTimelineModule } from './timeline/timeline.module'; +import { AddonBlockGlobalSearchModule } from '@addons/block/globalsearch/globalsearch.module'; @NgModule({ imports: [ @@ -55,6 +56,7 @@ import { AddonBlockTimelineModule } from './timeline/timeline.module'; AddonBlockCommentsModule, AddonBlockCompletionStatusModule, AddonBlockCourseListModule, + AddonBlockGlobalSearchModule, AddonBlockGlossaryRandomModule, AddonBlockHtmlModule, AddonBlockLearningPlansModule, diff --git a/src/addons/block/globalsearch/globalsearch.module.ts b/src/addons/block/globalsearch/globalsearch.module.ts new file mode 100644 index 000000000..3861622ec --- /dev/null +++ b/src/addons/block/globalsearch/globalsearch.module.ts @@ -0,0 +1,38 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { IonicModule } from '@ionic/angular'; +import { TranslateModule } from '@ngx-translate/core'; +import { CoreBlockDelegate } from '@features/block/services/block-delegate'; +import { AddonBlockGlobalSearchHandler } from './services/block-handler'; +import { CoreBlockComponentsModule } from '@features/block/components/components.module'; + +@NgModule({ + imports: [ + IonicModule, + CoreBlockComponentsModule, + TranslateModule.forChild(), + ], + providers: [ + { + provide: APP_INITIALIZER, + multi: true, + useValue: () => { + CoreBlockDelegate.registerHandler(AddonBlockGlobalSearchHandler.instance); + }, + }, + ], +}) +export class AddonBlockGlobalSearchModule {} diff --git a/src/addons/block/globalsearch/lang.json b/src/addons/block/globalsearch/lang.json new file mode 100644 index 000000000..abf5ca286 --- /dev/null +++ b/src/addons/block/globalsearch/lang.json @@ -0,0 +1,3 @@ +{ + "pluginname": "Global search" +} diff --git a/src/addons/block/globalsearch/services/block-handler.ts b/src/addons/block/globalsearch/services/block-handler.ts new file mode 100644 index 000000000..0fae9d28a --- /dev/null +++ b/src/addons/block/globalsearch/services/block-handler.ts @@ -0,0 +1,61 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Injectable } from '@angular/core'; +import { CoreBlockHandlerData } from '@features/block/services/block-delegate'; +import { CoreBlockOnlyTitleComponent } from '@features/block/components/only-title-block/only-title-block'; +import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler'; +import { makeSingleton } from '@singletons'; +import { CoreCourseBlock } from '@features/course/services/course'; +import { CoreSites } from '@services/sites'; +import { CORE_SEARCH_PAGE_NAME } from '@features/search/services/handlers/mainmenu'; + +/** + * Block handler. + */ +@Injectable({ providedIn: 'root' }) +export class AddonBlockGlobalSearchHandlerService extends CoreBlockBaseHandler { + + name = 'AddonBlockGlobalSearch'; + blockName = 'globalsearch'; + + /** + * @inheritdoc + */ + async isEnabled(): Promise { + const site = CoreSites.getRequiredCurrentSite(); + + return !site.isFeatureDisabled('CoreNoDelegate_GlobalSearch') + && site.wsAvailable('core_search_get_results') + && site.canUseAdvancedFeature('enableglobalsearch'); + } + + /** + * @inheritdoc + */ + getDisplayData(block: CoreCourseBlock, contextLevel: string, instanceId: number): CoreBlockHandlerData | undefined { + return { + title: 'addon.block_globalsearch.pluginname', + class: 'addon-block-globalsearch', + component: CoreBlockOnlyTitleComponent, + link: CORE_SEARCH_PAGE_NAME, + linkParams: contextLevel === 'course' + ? { courseId: instanceId } + : {}, + }; + } + +} + +export const AddonBlockGlobalSearchHandler = makeSingleton(AddonBlockGlobalSearchHandlerService); diff --git a/src/core/features/search/pages/global-search/global-search.ts b/src/core/features/search/pages/global-search/global-search.ts index 0adbafc40..136847c19 100644 --- a/src/core/features/search/pages/global-search/global-search.ts +++ b/src/core/features/search/pages/global-search/global-search.ts @@ -28,6 +28,7 @@ import { CORE_SEARCH_GLOBAL_SEARCH_FILTERS_UPDATED, CoreSearchGlobalSearch, } from '@features/search/services/global-search'; +import { CoreNavigator } from '@services/navigator'; @Component({ selector: 'page-core-search-global-search', @@ -46,11 +47,16 @@ export class CoreSearchGlobalSearchPage implements OnInit, OnDestroy { ngOnInit(): void { const site = CoreSites.getRequiredCurrentSite(); const searchBanner = site.config?.searchbanner?.trim() ?? ''; + const courseId = CoreNavigator.getRouteNumberParam('courseId'); if (CoreUtils.isTrueOrOne(site.config?.searchbannerenable) && searchBanner.length > 0) { this.searchBanner = searchBanner; } + if (courseId) { + this.resultsSource.setFilters({ courseIds: [courseId] }); + } + this.filtersObserver = CoreEvents.on( CORE_SEARCH_GLOBAL_SEARCH_FILTERS_UPDATED, filters => this.resultsSource.setFilters(filters), diff --git a/src/core/features/search/tests/behat/global-search.feature b/src/core/features/search/tests/behat/global-search.feature index d0bc85cef..381dda737 100644 --- a/src/core/features/search/tests/behat/global-search.feature +++ b/src/core/features/search/tests/behat/global-search.feature @@ -129,3 +129,19 @@ Feature: Test Global Search When I press the more menu button in the app And I press "Global search" in the app Then I should find "Search indexing is under maintentance!" in the app + + Scenario: Open from side block + Given global search expects the query "message" and will return: + | type | idnumber | + | activity | page01 | + And the following "blocks" exist: + | blockname | contextlevel | reference | + | globalsearch | Course | C1 | + And I entered the course "Course 1" as "student1" in the app + When I press "Open block drawer" in the app + And I press "Global search" in the app + Then I should find "What are you searching for?" in the app + + When I press "Filter" in the app + Then "C1" should be selected in the app + But "C2" should not be selected in the app