forked from EVOgeek/Vmeda.Online
		
	MOBILE-4207 forum: Implement search forums block
This commit is contained in:
		
							parent
							
								
									596365da9c
								
							
						
					
					
						commit
						cd85155953
					
				@ -66,6 +66,7 @@
 | 
				
			|||||||
  "addon.block_recentlyaccesseditems.noitems": "block_recentlyaccesseditems",
 | 
					  "addon.block_recentlyaccesseditems.noitems": "block_recentlyaccesseditems",
 | 
				
			||||||
  "addon.block_recentlyaccesseditems.pluginname": "block_recentlyaccesseditems",
 | 
					  "addon.block_recentlyaccesseditems.pluginname": "block_recentlyaccesseditems",
 | 
				
			||||||
  "addon.block_rssclient.pluginname": "block_rss_client",
 | 
					  "addon.block_rssclient.pluginname": "block_rss_client",
 | 
				
			||||||
 | 
					  "addon.block_searchforums.pluginname": "block_search_forums",
 | 
				
			||||||
  "addon.block_selfcompletion.pluginname": "block_selfcompletion",
 | 
					  "addon.block_selfcompletion.pluginname": "block_selfcompletion",
 | 
				
			||||||
  "addon.block_sitemainmenu.pluginname": "block_site_main_menu",
 | 
					  "addon.block_sitemainmenu.pluginname": "block_site_main_menu",
 | 
				
			||||||
  "addon.block_starredcourses.nocourses": "block_starredcourses",
 | 
					  "addon.block_starredcourses.nocourses": "block_starredcourses",
 | 
				
			||||||
@ -684,6 +685,7 @@
 | 
				
			|||||||
  "addon.mod_forum.removefromfavourites": "forum",
 | 
					  "addon.mod_forum.removefromfavourites": "forum",
 | 
				
			||||||
  "addon.mod_forum.reply": "forum",
 | 
					  "addon.mod_forum.reply": "forum",
 | 
				
			||||||
  "addon.mod_forum.replyplaceholder": "forum",
 | 
					  "addon.mod_forum.replyplaceholder": "forum",
 | 
				
			||||||
 | 
					  "addon.mod_forum.searchresults": "course",
 | 
				
			||||||
  "addon.mod_forum.subject": "forum",
 | 
					  "addon.mod_forum.subject": "forum",
 | 
				
			||||||
  "addon.mod_forum.tagarea_forum_posts": "forum",
 | 
					  "addon.mod_forum.tagarea_forum_posts": "forum",
 | 
				
			||||||
  "addon.mod_forum.thisforumhasduedate": "forum",
 | 
					  "addon.mod_forum.thisforumhasduedate": "forum",
 | 
				
			||||||
 | 
				
			|||||||
@ -42,6 +42,7 @@ import { AddonBlockStarredCoursesModule } from './starredcourses/starredcourses.
 | 
				
			|||||||
import { AddonBlockTagsModule } from './tags/tags.module';
 | 
					import { AddonBlockTagsModule } from './tags/tags.module';
 | 
				
			||||||
import { AddonBlockTimelineModule } from './timeline/timeline.module';
 | 
					import { AddonBlockTimelineModule } from './timeline/timeline.module';
 | 
				
			||||||
import { AddonBlockGlobalSearchModule } from '@addons/block/globalsearch/globalsearch.module';
 | 
					import { AddonBlockGlobalSearchModule } from '@addons/block/globalsearch/globalsearch.module';
 | 
				
			||||||
 | 
					import { AddonBlockSearchForumsModule } from '@addons/block/searchforums/searchforums.module';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@NgModule({
 | 
					@NgModule({
 | 
				
			||||||
    imports: [
 | 
					    imports: [
 | 
				
			||||||
@ -68,6 +69,7 @@ import { AddonBlockGlobalSearchModule } from '@addons/block/globalsearch/globals
 | 
				
			|||||||
        AddonBlockRecentlyAccessedCoursesModule,
 | 
					        AddonBlockRecentlyAccessedCoursesModule,
 | 
				
			||||||
        AddonBlockRecentlyAccessedItemsModule,
 | 
					        AddonBlockRecentlyAccessedItemsModule,
 | 
				
			||||||
        AddonBlockRssClientModule,
 | 
					        AddonBlockRssClientModule,
 | 
				
			||||||
 | 
					        AddonBlockSearchForumsModule,
 | 
				
			||||||
        AddonBlockSelfCompletionModule,
 | 
					        AddonBlockSelfCompletionModule,
 | 
				
			||||||
        AddonBlockSiteMainMenuModule,
 | 
					        AddonBlockSiteMainMenuModule,
 | 
				
			||||||
        AddonBlockStarredCoursesModule,
 | 
					        AddonBlockStarredCoursesModule,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										3
									
								
								src/addons/block/searchforums/lang.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/addons/block/searchforums/lang.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "pluginname": "Search forums"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								src/addons/block/searchforums/searchforums.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/addons/block/searchforums/searchforums.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -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 { AddonBlockSearchForumsHandler } 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(AddonBlockSearchForumsHandler.instance);
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class AddonBlockSearchForumsModule {}
 | 
				
			||||||
							
								
								
									
										68
									
								
								src/addons/block/searchforums/services/block-handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/addons/block/searchforums/services/block-handler.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					// (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 { FORUM_SEARCH_PAGE_NAME } from '@addons/mod/forum/forum.module';
 | 
				
			||||||
 | 
					import { CoreCourseBlock } from '@features/course/services/course';
 | 
				
			||||||
 | 
					import { CoreSearchGlobalSearch } from '@features/search/services/global-search';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Block handler.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Injectable({ providedIn: 'root' })
 | 
				
			||||||
 | 
					export class AddonBlockSearchForumsHandlerService extends CoreBlockBaseHandler {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    name = 'AddonBlockSearchForums';
 | 
				
			||||||
 | 
					    blockName = 'search_forums';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @inheritdoc
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    async isEnabled(): Promise<boolean> {
 | 
				
			||||||
 | 
					        const enabled = await CoreSearchGlobalSearch.isEnabled();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!enabled) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const forumSearchAreas = ['mod_forum-activity', 'mod_forum-post'];
 | 
				
			||||||
 | 
					        const searchAreas = await CoreSearchGlobalSearch.getSearchAreas();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return searchAreas.some(({ id }) => forumSearchAreas.includes(id));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @inheritdoc
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    getDisplayData(block: CoreCourseBlock, contextLevel: string, instanceId: number): CoreBlockHandlerData | undefined {
 | 
				
			||||||
 | 
					        if (contextLevel !== 'course') {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            title: 'addon.block_searchforums.pluginname',
 | 
				
			||||||
 | 
					            class: 'addon-block-search-forums',
 | 
				
			||||||
 | 
					            component: CoreBlockOnlyTitleComponent,
 | 
				
			||||||
 | 
					            link: FORUM_SEARCH_PAGE_NAME,
 | 
				
			||||||
 | 
					            linkParams: { courseId: instanceId },
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const AddonBlockSearchForumsHandler = makeSingleton(AddonBlockSearchForumsHandlerService);
 | 
				
			||||||
							
								
								
									
										38
									
								
								src/addons/mod/forum/forum-search-lazy.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/addons/mod/forum/forum-search-lazy.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -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 { CoreSharedModule } from '@/core/shared.module';
 | 
				
			||||||
 | 
					import { AddonModForumSearchPage } from '@addons/mod/forum/pages/search/search';
 | 
				
			||||||
 | 
					import { NgModule } from '@angular/core';
 | 
				
			||||||
 | 
					import { RouterModule, Routes } from '@angular/router';
 | 
				
			||||||
 | 
					import { CoreMainMenuComponentsModule } from '@features/mainmenu/components/components.module';
 | 
				
			||||||
 | 
					import { CoreSearchComponentsModule } from '@features/search/components/components.module';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const routes: Routes = [{
 | 
				
			||||||
 | 
					    path: '',
 | 
				
			||||||
 | 
					    component: AddonModForumSearchPage,
 | 
				
			||||||
 | 
					}];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@NgModule({
 | 
				
			||||||
 | 
					    imports: [
 | 
				
			||||||
 | 
					        RouterModule.forChild(routes),
 | 
				
			||||||
 | 
					        CoreSharedModule,
 | 
				
			||||||
 | 
					        CoreSearchComponentsModule,
 | 
				
			||||||
 | 
					        CoreMainMenuComponentsModule,
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    declarations: [
 | 
				
			||||||
 | 
					        AddonModForumSearchPage,
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class AddonModForumSearchLazyModule {}
 | 
				
			||||||
@ -52,7 +52,13 @@ export const ADDON_MOD_FORUM_SERVICES: Type<unknown>[] = [
 | 
				
			|||||||
    AddonModForumSyncProvider,
 | 
					    AddonModForumSyncProvider,
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const FORUM_SEARCH_PAGE_NAME = 'forum/search';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const mainMenuRoutes: Routes = [
 | 
					const mainMenuRoutes: Routes = [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        path: FORUM_SEARCH_PAGE_NAME,
 | 
				
			||||||
 | 
					        loadChildren: () => import('./forum-search-lazy.module').then(m => m.AddonModForumSearchLazyModule),
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        path: `${AddonModForumModuleHandlerService.PAGE_NAME}/discussion/:discussionId`,
 | 
					        path: `${AddonModForumModuleHandlerService.PAGE_NAME}/discussion/:discussionId`,
 | 
				
			||||||
        loadChildren: () => import('./forum-discussion-lazy.module').then(m => m.AddonModForumDiscussionLazyModule),
 | 
					        loadChildren: () => import('./forum-discussion-lazy.module').then(m => m.AddonModForumDiscussionLazyModule),
 | 
				
			||||||
 | 
				
			|||||||
@ -59,6 +59,7 @@
 | 
				
			|||||||
    "removefromfavourites": "Unstar this discussion",
 | 
					    "removefromfavourites": "Unstar this discussion",
 | 
				
			||||||
    "reply": "Reply",
 | 
					    "reply": "Reply",
 | 
				
			||||||
    "replyplaceholder": "Write your reply...",
 | 
					    "replyplaceholder": "Write your reply...",
 | 
				
			||||||
 | 
					    "searchresults": "Search results: {{$a}}",
 | 
				
			||||||
    "subject": "Subject",
 | 
					    "subject": "Subject",
 | 
				
			||||||
    "tagarea_forum_posts": "Forum posts",
 | 
					    "tagarea_forum_posts": "Forum posts",
 | 
				
			||||||
    "thisforumhasduedate": "The due date for posting to this forum is {{$a}}.",
 | 
					    "thisforumhasduedate": "The due date for posting to this forum is {{$a}}.",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										50
									
								
								src/addons/mod/forum/pages/search/search.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/addons/mod/forum/pages/search/search.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					<ion-header>
 | 
				
			||||||
 | 
					    <ion-toolbar>
 | 
				
			||||||
 | 
					        <ion-buttons slot="start">
 | 
				
			||||||
 | 
					            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
				
			||||||
 | 
					        </ion-buttons>
 | 
				
			||||||
 | 
					        <ion-title>
 | 
				
			||||||
 | 
					            <h1>{{ 'addon.block_searchforums.pluginname' | translate }}</h1>
 | 
				
			||||||
 | 
					        </ion-title>
 | 
				
			||||||
 | 
					        <ion-buttons slot="end">
 | 
				
			||||||
 | 
					            <core-user-menu-button></core-user-menu-button>
 | 
				
			||||||
 | 
					        </ion-buttons>
 | 
				
			||||||
 | 
					    </ion-toolbar>
 | 
				
			||||||
 | 
					</ion-header>
 | 
				
			||||||
 | 
					<ion-content class="limited-width">
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					        <ion-card class="core-danger-card" *ngIf="searchBanner">
 | 
				
			||||||
 | 
					            <ion-item>
 | 
				
			||||||
 | 
					                <ion-icon name="fas-triangle-exclamation" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
 | 
					                <ion-label>
 | 
				
			||||||
 | 
					                    <core-format-text [text]="searchBanner"></core-format-text>
 | 
				
			||||||
 | 
					                </ion-label>
 | 
				
			||||||
 | 
					            </ion-item>
 | 
				
			||||||
 | 
					        </ion-card>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <core-search-box (onSubmit)="search($event)" (onClear)="clearSearch()" [placeholder]="'core.search' | translate"
 | 
				
			||||||
 | 
					            [searchLabel]="'core.search' | translate" [autoFocus]="true" [searchArea]="searchAreaId"></core-search-box>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div *ngIf="!resultsSource.isEmpty()" class="results-count">
 | 
				
			||||||
 | 
					            {{ 'addon.mod_forum.searchresults' | translate: { $a: resultsSource.getTotalResults() } }}
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <ion-list *ngIf="resultsSource.isLoaded()">
 | 
				
			||||||
 | 
					            <core-search-global-search-result *ngFor="let result of resultsSource.getItems()" [result]="result" [showCourse]="false"
 | 
				
			||||||
 | 
					                (onClick)="visitResult(result)">
 | 
				
			||||||
 | 
					            </core-search-global-search-result>
 | 
				
			||||||
 | 
					        </ion-list>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <core-infinite-loading [enabled]="resultsSource.isLoaded() && !resultsSource.isCompleted()" (action)="loadMoreResults($event)"
 | 
				
			||||||
 | 
					            [error]="loadMoreError">
 | 
				
			||||||
 | 
					        </core-infinite-loading>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <core-empty-box *ngIf="resultsSource.isEmpty()" icon="fas-magnifying-glass" [dimmed]="!resultsSource.isLoaded()">
 | 
				
			||||||
 | 
					            <p *ngIf="!resultsSource.isLoaded()">{{ 'core.search.empty' | translate }}</p>
 | 
				
			||||||
 | 
					            <ng-container *ngIf="resultsSource.isLoaded()">
 | 
				
			||||||
 | 
					                <p><strong>{{ 'core.search.noresults' | translate: { $a: resultsSource.getQuery() } }}</strong></p>
 | 
				
			||||||
 | 
					                <p><small>{{ 'core.search.noresultshelp' | translate }}</small></p>
 | 
				
			||||||
 | 
					            </ng-container>
 | 
				
			||||||
 | 
					        </core-empty-box>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</ion-content>
 | 
				
			||||||
							
								
								
									
										15
									
								
								src/addons/mod/forum/pages/search/search.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/addons/mod/forum/pages/search/search.scss
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					:host {
 | 
				
			||||||
 | 
					    --results-count-text-color: var(--gray-700);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .results-count {
 | 
				
			||||||
 | 
					        color: var(--results-count-text-color);
 | 
				
			||||||
 | 
					        min-height: 0px;
 | 
				
			||||||
 | 
					        margin: 8px 16px;
 | 
				
			||||||
 | 
					        font-size: 14px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:host-context(html.dark) {
 | 
				
			||||||
 | 
					    --results-count-text-color: var(--gray-400);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										119
									
								
								src/addons/mod/forum/pages/search/search.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								src/addons/mod/forum/pages/search/search.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,119 @@
 | 
				
			|||||||
 | 
					// (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 { Component, OnInit } from '@angular/core';
 | 
				
			||||||
 | 
					import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper';
 | 
				
			||||||
 | 
					import { CoreSearchGlobalSearchResultsSource } from '@features/search/classes/global-search-results-source';
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					    CoreSearchGlobalSearch,
 | 
				
			||||||
 | 
					    CoreSearchGlobalSearchFilters,
 | 
				
			||||||
 | 
					    CoreSearchGlobalSearchResult,
 | 
				
			||||||
 | 
					} from '@features/search/services/global-search';
 | 
				
			||||||
 | 
					import { CoreNavigator } from '@services/navigator';
 | 
				
			||||||
 | 
					import { CoreSites } from '@services/sites';
 | 
				
			||||||
 | 
					import { CoreDomUtils } from '@services/utils/dom';
 | 
				
			||||||
 | 
					import { CoreUtils } from '@services/utils/utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					    selector: 'page-addon-mod-forum-search',
 | 
				
			||||||
 | 
					    templateUrl: 'search.html',
 | 
				
			||||||
 | 
					    styleUrls: ['search.scss'],
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class AddonModForumSearchPage implements OnInit {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    loadMoreError: string | null = null;
 | 
				
			||||||
 | 
					    searchBanner: string | null = null;
 | 
				
			||||||
 | 
					    resultsSource = new CoreSearchGlobalSearchResultsSource('', {});
 | 
				
			||||||
 | 
					    searchAreaId?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @inheritdoc
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnInit(): void {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            const site = CoreSites.getRequiredCurrentSite();
 | 
				
			||||||
 | 
					            const searchBanner = site.config?.searchbanner?.trim() ?? '';
 | 
				
			||||||
 | 
					            const courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
 | 
				
			||||||
 | 
					            const filters: CoreSearchGlobalSearchFilters = {
 | 
				
			||||||
 | 
					                courseIds: [courseId],
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (CoreUtils.isTrueOrOne(site.config?.searchbannerenable) && searchBanner.length > 0) {
 | 
				
			||||||
 | 
					                this.searchBanner = searchBanner;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            filters.searchAreaIds = ['mod_forum-activity', 'mod_forum-post'];
 | 
				
			||||||
 | 
					            this.searchAreaId = `AddonModForumSearch-${courseId}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.resultsSource.setFilters(filters);
 | 
				
			||||||
 | 
					        } catch (error) {
 | 
				
			||||||
 | 
					            CoreDomUtils.showErrorModal(error);
 | 
				
			||||||
 | 
					            CoreNavigator.back();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Perform a new search.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param query Search query.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    async search(query: string): Promise<void> {
 | 
				
			||||||
 | 
					        this.resultsSource.setQuery(query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (this.resultsSource.hasEmptyQuery()) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        await CoreDomUtils.showOperationModals('core.searching', true, async () => {
 | 
				
			||||||
 | 
					            await this.resultsSource.reload();
 | 
				
			||||||
 | 
					            await CoreUtils.ignoreErrors(
 | 
				
			||||||
 | 
					                CoreSearchGlobalSearch.logViewResults(this.resultsSource.getQuery(), this.resultsSource.getFilters()),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Clear search results.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    clearSearch(): void {
 | 
				
			||||||
 | 
					        this.loadMoreError = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Visit a result's origin.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param result Result to visit.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    async visitResult(result: CoreSearchGlobalSearchResult): Promise<void> {
 | 
				
			||||||
 | 
					        await CoreContentLinksHelper.handleLink(result.url);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Load more results.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param complete Notify completion.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    async loadMoreResults(complete: () => void ): Promise<void> {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            await this.resultsSource?.load();
 | 
				
			||||||
 | 
					        } catch (error) {
 | 
				
			||||||
 | 
					            this.loadMoreError = CoreDomUtils.getErrorMessage(error);
 | 
				
			||||||
 | 
					        } finally {
 | 
				
			||||||
 | 
					            complete();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										49
									
								
								src/addons/mod/forum/tests/behat/search.feature
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/addons/mod/forum/tests/behat/search.feature
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					@mod @mod_forum @app @javascript @lms_from4.3
 | 
				
			||||||
 | 
					Feature: Test Forum Search
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Background:
 | 
				
			||||||
 | 
					    Given solr is installed
 | 
				
			||||||
 | 
					    And the following config values are set as admin:
 | 
				
			||||||
 | 
					      | enableglobalsearch | 1 |
 | 
				
			||||||
 | 
					      | searchengine       | solr |
 | 
				
			||||||
 | 
					    And the following "courses" exist:
 | 
				
			||||||
 | 
					      | fullname | shortname |
 | 
				
			||||||
 | 
					      | Course 1 | C1        |
 | 
				
			||||||
 | 
					      | Course 2 | C2        |
 | 
				
			||||||
 | 
					    And the following "users" exist:
 | 
				
			||||||
 | 
					      | username |
 | 
				
			||||||
 | 
					      | student1 |
 | 
				
			||||||
 | 
					    And the following "course enrolments" exist:
 | 
				
			||||||
 | 
					      | user     | course | role    |
 | 
				
			||||||
 | 
					      | student1 | C1     | student |
 | 
				
			||||||
 | 
					      | student1 | C2     | student |
 | 
				
			||||||
 | 
					    And the following "activities" exist:
 | 
				
			||||||
 | 
					      | activity | name        | intro               | course | idnumber |
 | 
				
			||||||
 | 
					      | forum    | Test forum 1 | Test forum 1 intro | C1     | forum1   |
 | 
				
			||||||
 | 
					      | forum    | Test forum 2 | Test forum 2 intro | C1     | forum2   |
 | 
				
			||||||
 | 
					      | forum    | Test forum 3 | Test forum 3 intro | C2     | forum3   |
 | 
				
			||||||
 | 
					    And the following "mod_forum > discussions" exist:
 | 
				
			||||||
 | 
					      | forum   | name                 | subject              | message                      |
 | 
				
			||||||
 | 
					      | forum1  | Initial discussion 1 | Initial discussion 1 | Initial discussion message 1 |
 | 
				
			||||||
 | 
					      | forum2  | Initial discussion 2 | Initial discussion 2 | Initial discussion message 2 |
 | 
				
			||||||
 | 
					      | forum3  | Initial discussion 3 | Initial discussion 3 | Initial discussion message 3 |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Scenario: Search in side block
 | 
				
			||||||
 | 
					    Given global search expects the query "message" and will return:
 | 
				
			||||||
 | 
					      | type     | idnumber |
 | 
				
			||||||
 | 
					      | activity | forum1   |
 | 
				
			||||||
 | 
					      | activity | forum2   |
 | 
				
			||||||
 | 
					    And the following "blocks" exist:
 | 
				
			||||||
 | 
					      | blockname     | contextlevel | reference |
 | 
				
			||||||
 | 
					      | search_forums | 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 "Search forums" in the app
 | 
				
			||||||
 | 
					    Then I should find "What are you searching for?" in the app
 | 
				
			||||||
 | 
					    And I should find "Search forums" in the app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    When I set the field "Search" to "message" in the app
 | 
				
			||||||
 | 
					    And I press "Search" "button" in the app
 | 
				
			||||||
 | 
					    Then I should find "Search results: 2" in the app
 | 
				
			||||||
 | 
					    And I should find "Test forum 1" in the app
 | 
				
			||||||
 | 
					    And I should find "Test forum 2" in the app
 | 
				
			||||||
@ -28,6 +28,7 @@ export class CoreSearchGlobalSearchResultsSource extends CorePaginatedItemsManag
 | 
				
			|||||||
    private query: string;
 | 
					    private query: string;
 | 
				
			||||||
    private filters: CoreSearchGlobalSearchFilters;
 | 
					    private filters: CoreSearchGlobalSearchFilters;
 | 
				
			||||||
    private pagesLoaded = 0;
 | 
					    private pagesLoaded = 0;
 | 
				
			||||||
 | 
					    private totalResults?: number;
 | 
				
			||||||
    private topResultsIds?: number[];
 | 
					    private topResultsIds?: number[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(query: string, filters: CoreSearchGlobalSearchFilters) {
 | 
					    constructor(query: string, filters: CoreSearchGlobalSearchFilters) {
 | 
				
			||||||
@ -93,6 +94,15 @@ export class CoreSearchGlobalSearchResultsSource extends CorePaginatedItemsManag
 | 
				
			|||||||
        return this.pagesLoaded;
 | 
					        return this.pagesLoaded;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get total results with the given filter.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @returns Total results.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    getTotalResults(): number | null {
 | 
				
			||||||
 | 
					        return this.totalResults ?? null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @inheritdoc
 | 
					     * @inheritdoc
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
@ -107,6 +117,7 @@ export class CoreSearchGlobalSearchResultsSource extends CorePaginatedItemsManag
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    reset(): void {
 | 
					    reset(): void {
 | 
				
			||||||
        this.pagesLoaded = 0;
 | 
					        this.pagesLoaded = 0;
 | 
				
			||||||
 | 
					        delete this.totalResults;
 | 
				
			||||||
        delete this.topResultsIds;
 | 
					        delete this.topResultsIds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        super.reset();
 | 
					        super.reset();
 | 
				
			||||||
@ -130,6 +141,8 @@ export class CoreSearchGlobalSearchResultsSource extends CorePaginatedItemsManag
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        const pageResults = await CoreSearchGlobalSearch.getResults(this.query, this.filters, page);
 | 
					        const pageResults = await CoreSearchGlobalSearch.getResults(this.query, this.filters, page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.totalResults = pageResults.total;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        results.push(...pageResults.results.filter(result => !this.topResultsIds?.includes(result.id)));
 | 
					        results.push(...pageResults.results.filter(result => !this.topResultsIds?.includes(result.id)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return { items: results, hasMoreItems: pageResults.canLoadMore };
 | 
					        return { items: results, hasMoreItems: pageResults.canLoadMore };
 | 
				
			||||||
 | 
				
			|||||||
@ -16,16 +16,19 @@ import { NgModule } from '@angular/core';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { CoreSharedModule } from '@/core/shared.module';
 | 
					import { CoreSharedModule } from '@/core/shared.module';
 | 
				
			||||||
import { CoreSearchBoxComponent } from './search-box/search-box';
 | 
					import { CoreSearchBoxComponent } from './search-box/search-box';
 | 
				
			||||||
 | 
					import { CoreSearchGlobalSearchResultComponent } from '@features/search/components/global-search-result/global-search-result';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@NgModule({
 | 
					@NgModule({
 | 
				
			||||||
    declarations: [
 | 
					    declarations: [
 | 
				
			||||||
        CoreSearchBoxComponent,
 | 
					        CoreSearchBoxComponent,
 | 
				
			||||||
 | 
					        CoreSearchGlobalSearchResultComponent,
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    imports: [
 | 
					    imports: [
 | 
				
			||||||
        CoreSharedModule,
 | 
					        CoreSharedModule,
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    exports: [
 | 
					    exports: [
 | 
				
			||||||
        CoreSearchBoxComponent,
 | 
					        CoreSearchBoxComponent,
 | 
				
			||||||
 | 
					        CoreSearchGlobalSearchResultComponent,
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class CoreSearchComponentsModule {}
 | 
					export class CoreSearchComponentsModule {}
 | 
				
			||||||
 | 
				
			|||||||
@ -19,7 +19,6 @@ import { CoreSearchGlobalSearchPage } from './pages/global-search/global-search'
 | 
				
			|||||||
import { CoreSearchComponentsModule } from '@features/search/components/components.module';
 | 
					import { CoreSearchComponentsModule } from '@features/search/components/components.module';
 | 
				
			||||||
import { CoreMainMenuComponentsModule } from '@features/mainmenu/components/components.module';
 | 
					import { CoreMainMenuComponentsModule } from '@features/mainmenu/components/components.module';
 | 
				
			||||||
import { buildTabMainRoutes } from '@features/mainmenu/mainmenu-tab-routing.module';
 | 
					import { buildTabMainRoutes } from '@features/mainmenu/mainmenu-tab-routing.module';
 | 
				
			||||||
import { CoreSearchGlobalSearchResultComponent } from '@features/search/components/global-search-result/global-search-result';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Build module routes.
 | 
					 * Build module routes.
 | 
				
			||||||
@ -42,7 +41,6 @@ function buildRoutes(injector: Injector): Routes {
 | 
				
			|||||||
    exports: [RouterModule],
 | 
					    exports: [RouterModule],
 | 
				
			||||||
    declarations: [
 | 
					    declarations: [
 | 
				
			||||||
        CoreSearchGlobalSearchPage,
 | 
					        CoreSearchGlobalSearchPage,
 | 
				
			||||||
        CoreSearchGlobalSearchResultComponent,
 | 
					 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    providers: [
 | 
					    providers: [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
				
			|||||||
@ -78,6 +78,7 @@ export type CoreSearchGlobalSearchSearchArea = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export interface CoreSearchGlobalSearchFilters {
 | 
					export interface CoreSearchGlobalSearchFilters {
 | 
				
			||||||
    searchAreaCategoryIds?: string[];
 | 
					    searchAreaCategoryIds?: string[];
 | 
				
			||||||
 | 
					    searchAreaIds?: string[];
 | 
				
			||||||
    courseIds?: number[];
 | 
					    courseIds?: number[];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -116,10 +117,11 @@ export class CoreSearchGlobalSearchService {
 | 
				
			|||||||
        query: string,
 | 
					        query: string,
 | 
				
			||||||
        filters: CoreSearchGlobalSearchFilters,
 | 
					        filters: CoreSearchGlobalSearchFilters,
 | 
				
			||||||
        page: number,
 | 
					        page: number,
 | 
				
			||||||
    ): Promise<{ results: CoreSearchGlobalSearchResult[]; canLoadMore: boolean }> {
 | 
					    ): Promise<{ results: CoreSearchGlobalSearchResult[]; total: number; canLoadMore: boolean }> {
 | 
				
			||||||
        if (this.filtersYieldEmptyResults(filters)) {
 | 
					        if (this.filtersYieldEmptyResults(filters)) {
 | 
				
			||||||
            return {
 | 
					            return {
 | 
				
			||||||
                results: [],
 | 
					                results: [],
 | 
				
			||||||
 | 
					                total: 0,
 | 
				
			||||||
                canLoadMore: false,
 | 
					                canLoadMore: false,
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -136,6 +138,7 @@ export class CoreSearchGlobalSearchService {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            results: await Promise.all((results ?? []).map(result => this.formatWSResult(result))),
 | 
					            results: await Promise.all((results ?? []).map(result => this.formatWSResult(result))),
 | 
				
			||||||
 | 
					            total: totalcount,
 | 
				
			||||||
            canLoadMore: totalcount > (page + 1) * CORE_SEARCH_GLOBAL_SEARCH_PAGE_LENGTH,
 | 
					            canLoadMore: totalcount > (page + 1) * CORE_SEARCH_GLOBAL_SEARCH_PAGE_LENGTH,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -269,7 +272,9 @@ export class CoreSearchGlobalSearchService {
 | 
				
			|||||||
     * @returns Whether the given filters will return 0 results.
 | 
					     * @returns Whether the given filters will return 0 results.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    protected filtersYieldEmptyResults(filters: CoreSearchGlobalSearchFilters): boolean {
 | 
					    protected filtersYieldEmptyResults(filters: CoreSearchGlobalSearchFilters): boolean {
 | 
				
			||||||
        return filters.courseIds?.length === 0 || filters.searchAreaCategoryIds?.length === 0;
 | 
					        return filters.courseIds?.length === 0
 | 
				
			||||||
 | 
					            || filters.searchAreaIds?.length === 0
 | 
				
			||||||
 | 
					            || filters.searchAreaCategoryIds?.length === 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -285,11 +290,21 @@ export class CoreSearchGlobalSearchService {
 | 
				
			|||||||
            wsFilters.courseids = filters.courseIds;
 | 
					            wsFilters.courseids = filters.courseIds;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (filters.searchAreaIds) {
 | 
				
			||||||
 | 
					            wsFilters.areaids = filters.searchAreaIds;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (filters.searchAreaCategoryIds) {
 | 
					        if (filters.searchAreaCategoryIds) {
 | 
				
			||||||
            const searchAreas = await this.getSearchAreas();
 | 
					            const searchAreas = await this.getSearchAreas();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            wsFilters.areaids = searchAreas
 | 
					            wsFilters.areaids = searchAreas
 | 
				
			||||||
                .filter(({ category }) => filters.searchAreaCategoryIds?.includes(category.id))
 | 
					                .filter(({ id, category }) => {
 | 
				
			||||||
 | 
					                    if (filters.searchAreaIds && !filters.searchAreaIds.includes(id)) {
 | 
				
			||||||
 | 
					                        return false;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    return filters.searchAreaCategoryIds?.includes(category.id);
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
                .map(({ id }) => id);
 | 
					                .map(({ id }) => id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user