forked from EVOgeek/Vmeda.Online
		
	MOBILE-3565 searchbox: Searchbox component implementation
This commit is contained in:
		
							parent
							
								
									9daf5a3db7
								
							
						
					
					
						commit
						f3ae7e5e4a
					
				| @ -54,6 +54,7 @@ import { CoreUtilsProvider } from '@services/utils/utils'; | ||||
| import { initCoreFilepoolDB } from '@services/filepool.db'; | ||||
| import { initCoreSitesDB } from '@services/sites.db'; | ||||
| import { initCoreSyncDB } from '@services/sync.db'; | ||||
| import { initCoreSearchHistoryDB } from '@core/search/services/search.history.db'; | ||||
| 
 | ||||
| // Import core modules.
 | ||||
| import { CoreEmulatorModule } from '@core/emulator/emulator.module'; | ||||
| @ -170,6 +171,7 @@ export class AppModule { | ||||
|         initCoreFilepoolDB(); | ||||
|         initCoreSitesDB(); | ||||
|         initCoreSyncDB(); | ||||
|         initCoreSearchHistoryDB(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -38,6 +38,6 @@ | ||||
|     } | ||||
| 
 | ||||
|     &.core-loading-loaded { | ||||
|         position: relative; | ||||
|         position: unset; | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										43
									
								
								src/app/core/search/components/components.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/app/core/search/components/components.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| // (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 { NgModule } from '@angular/core'; | ||||
| import { CommonModule } from '@angular/common'; | ||||
| import { IonicModule } from '@ionic/angular'; | ||||
| import { FormsModule } from '@angular/forms'; | ||||
| import { TranslateModule } from '@ngx-translate/core'; | ||||
| 
 | ||||
| import { CoreDirectivesModule } from '@directives/directives.module'; | ||||
| import { CoreComponentsModule } from '@components/components.module'; | ||||
| 
 | ||||
| import { CoreSearchBoxComponent } from './search-box/search-box'; | ||||
| 
 | ||||
| 
 | ||||
| @NgModule({ | ||||
|     declarations: [ | ||||
|         CoreSearchBoxComponent, | ||||
|     ], | ||||
|     imports: [ | ||||
|         CommonModule, | ||||
|         IonicModule, | ||||
|         FormsModule, | ||||
|         TranslateModule.forChild(), | ||||
|         CoreDirectivesModule, | ||||
|         CoreComponentsModule, | ||||
|     ], | ||||
|     exports: [ | ||||
|         CoreSearchBoxComponent, | ||||
|     ], | ||||
| }) | ||||
| export class CoreSearchComponentsModule {} | ||||
| @ -0,0 +1,28 @@ | ||||
| <ion-card> | ||||
|     <form (ngSubmit)="submitForm($event)" role="search" #searchForm> | ||||
|         <ion-item> | ||||
|             <ion-label> | ||||
|                 <ion-input type="search" name="search" [(ngModel)]="searchText" [placeholder]="placeholder" | ||||
|                     [autocorrect]="autocorrect" [spellcheck]="spellcheck" [core-auto-focus]="autoFocus" | ||||
|                     [disabled]="disabled" role="searchbox" (ionFocus)="focus($event)"></ion-input> | ||||
|             </ion-label> | ||||
|             <ion-button slot="end" fill="clear" type="submit" size="small" [attr.aria-label]="searchLabel" | ||||
|                 [disabled]="disabled || !searchText || (searchText.length < lengthCheck)"> | ||||
|                 <ion-icon name="fas-search" slot="icon-only"></ion-icon> | ||||
|             </ion-button> | ||||
|             <ion-button *ngIf="showClear" slot="end" fill="clear" size="small" | ||||
|                 [attr.aria-label]="'core.clearsearch' | translate" [disabled]="searched == '' || disabled" | ||||
|                 (click)="clearForm()"> | ||||
|                 <ion-icon name="fas-backspace" slot="icon-only"></ion-icon> | ||||
|             </ion-button> | ||||
|         </ion-item> | ||||
|         <ion-list class="core-search-history" [hidden]="!historyShown"> | ||||
|             <ion-item class="ion-text-wrap" *ngFor="let item of history" | ||||
|                 (click)="historyClicked($event, item.searchedtext)" class="core-clickable" tabindex="1"> | ||||
|                 <ion-icon name="fa-history" slot="start"> | ||||
|                 </ion-icon> | ||||
|                 {{item.searchedtext}} | ||||
|             </ion-item> | ||||
|         </ion-list> | ||||
|     </form> | ||||
| </ion-card> | ||||
							
								
								
									
										27
									
								
								src/app/core/search/components/search-box/search-box.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/app/core/search/components/search-box/search-box.scss
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| :host { | ||||
|     height: 80px; | ||||
|     display: block; | ||||
|     position: relative; | ||||
| 
 | ||||
|     ion-card { | ||||
|         position: absolute; | ||||
|         left: 0; | ||||
|         right: 0; | ||||
|         z-index: 4; | ||||
|     } | ||||
| 
 | ||||
|     ion-button.button:last-child { | ||||
|         margin-left: unset; | ||||
|         margin-inline-start: 10px; | ||||
|     } | ||||
| 
 | ||||
|     .core-search-history { | ||||
|         max-height: calc(-120px + 80vh); | ||||
|         overflow-y: auto; | ||||
| 
 | ||||
|         .item:hover { | ||||
|             --background: var(--gray-lighter); | ||||
|             cursor: pointer; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										173
									
								
								src/app/core/search/components/search-box/search-box.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								src/app/core/search/components/search-box/search-box.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,173 @@ | ||||
| // (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, Input, Output, EventEmitter, OnInit } from '@angular/core'; | ||||
| 
 | ||||
| import { CoreSites } from '@services/sites'; | ||||
| import { CoreDomUtils } from '@services/utils/dom'; | ||||
| import { CoreUtils } from '@services/utils/utils'; | ||||
| import { CoreSearchHistory, CoreSearchHistoryItem } from '../../services/search-history'; | ||||
| import { Translate } from '@singletons/core.singletons'; | ||||
| 
 | ||||
| /** | ||||
|  * Component to display a "search box". | ||||
|  * | ||||
|  * @description | ||||
|  * This component will display a standalone search box with its search button in order to have a better UX. | ||||
|  * | ||||
|  * Example usage: | ||||
|  * <core-search-box (onSubmit)="search($event)" [placeholder]="'core.courses.search' | translate" | ||||
|  *     [searchLabel]="'core.courses.search' | translate" autoFocus="true"></core-search-box> | ||||
|  */ | ||||
| @Component({ | ||||
|     selector: 'core-search-box', | ||||
|     templateUrl: 'core-search-box.html', | ||||
|     styleUrls: ['search-box.scss'], | ||||
| }) | ||||
| export class CoreSearchBoxComponent implements OnInit { | ||||
| 
 | ||||
|     @Input() searchLabel?: string; // Label to be used on action button.
 | ||||
|     @Input() placeholder?: string; // Placeholder text for search text input.
 | ||||
|     @Input() autocorrect = 'on'; // Enables/disable Autocorrection on search text input.
 | ||||
|     @Input() spellcheck?: string | boolean = true; // Enables/disable Spellchecker on search text input.
 | ||||
|     @Input() autoFocus?: string | boolean; // Enables/disable Autofocus when entering view.
 | ||||
|     @Input() lengthCheck = 3; // Check value length before submit. If 0, any string will be submitted.
 | ||||
|     @Input() showClear = true; // Show/hide clear button.
 | ||||
|     @Input() disabled = false; // Disables the input text.
 | ||||
|     @Input() protected initialSearch = ''; // Initial search text.
 | ||||
| 
 | ||||
|     /* If provided. It will save and display a history of searches for this particular Id. | ||||
|      * To use different history lists, place different Id. | ||||
|      * I.e. AddonMessagesContacts or CoreUserParticipants-6 (using the course Id).*/ | ||||
|     @Input() protected searchArea  = ''; | ||||
| 
 | ||||
|     @Output() onSubmit: EventEmitter<string>; // Send data when submitting the search form.
 | ||||
|     @Output() onClear: EventEmitter<void>; // Send event when clearing the search form.
 | ||||
| 
 | ||||
|     formElement?: HTMLFormElement; | ||||
| 
 | ||||
|     searched = ''; // Last search emitted.
 | ||||
|     searchText = ''; | ||||
|     history: CoreSearchHistoryItem[] = []; | ||||
|     historyShown = false; | ||||
| 
 | ||||
|     constructor() { | ||||
|         this.onSubmit = new EventEmitter<string>(); | ||||
|         this.onClear = new EventEmitter<void>(); | ||||
|     } | ||||
| 
 | ||||
|     ngOnInit(): void { | ||||
|         this.searchLabel = this.searchLabel || Translate.instance.instant('core.search'); | ||||
|         this.placeholder = this.placeholder || Translate.instance.instant('core.search'); | ||||
|         this.spellcheck = CoreUtils.instance.isTrueOrOne(this.spellcheck); | ||||
|         this.showClear = CoreUtils.instance.isTrueOrOne(this.showClear); | ||||
|         this.searchText = this.initialSearch; | ||||
| 
 | ||||
|         if (this.searchArea) { | ||||
|             this.loadHistory(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Form submitted. | ||||
|      * | ||||
|      * @param e Event. | ||||
|      */ | ||||
|     submitForm(e?: Event): void { | ||||
|         e && e.preventDefault(); | ||||
|         e && e.stopPropagation(); | ||||
| 
 | ||||
|         if (this.searchText.length < this.lengthCheck) { | ||||
|             // The view should handle this case, but we check it here too just in case.
 | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (this.searchArea) { | ||||
|             this.saveSearchToHistory(this.searchText); | ||||
|         } | ||||
| 
 | ||||
|         CoreDomUtils.instance.triggerFormSubmittedEvent(this.formElement, false, CoreSites.instance.getCurrentSiteId()); | ||||
| 
 | ||||
|         this.historyShown = false; | ||||
|         this.searched = this.searchText; | ||||
|         this.onSubmit.emit(this.searchText); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Saves the search term onto the history. | ||||
|      * | ||||
|      * @param text Text to save. | ||||
|      * @return Promise resolved when done. | ||||
|      */ | ||||
|     protected async saveSearchToHistory(text: string): Promise<void> { | ||||
|         try { | ||||
|             await CoreSearchHistory.instance.insertOrUpdateSearchText(this.searchArea, text.toLowerCase()); | ||||
|         } finally { | ||||
|             this.loadHistory(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Loads search history. | ||||
|      * | ||||
|      * @return Promise resolved when done. | ||||
|      */ | ||||
|     protected async loadHistory(): Promise<void> { | ||||
|         this.history = await CoreSearchHistory.instance.getSearchHistory(this.searchArea); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Select an item and use it for search text. | ||||
|      * | ||||
|      * @param e Event. | ||||
|      * @param text Selected text. | ||||
|      */ | ||||
|     historyClicked(e: Event, text: string): void { | ||||
|         if (this.searched != text) { | ||||
|             this.searchText = text; | ||||
|             this.submitForm(e); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Form submitted. | ||||
|      */ | ||||
|     clearForm(): void { | ||||
|         this.searched = ''; | ||||
|         this.searchText = ''; | ||||
|         this.onClear.emit(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param event Focus event on input element. | ||||
|      */ | ||||
|     focus(event: CustomEvent): void { | ||||
|         this.historyShown = true; | ||||
| 
 | ||||
|         if (!this.formElement) { | ||||
|             this.formElement = event.detail.target.closest('form'); | ||||
| 
 | ||||
| 
 | ||||
|             this.formElement?.addEventListener('blur', () => { | ||||
|                 // Wait the new element to be focused.
 | ||||
|                 setTimeout(() => { | ||||
|                     if (document.activeElement?.closest('form') != this.formElement) { | ||||
|                         this.historyShown = false; | ||||
|                     } | ||||
|                 }); | ||||
|             }, true); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										28
									
								
								src/app/core/search/search.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/app/core/search/search.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| // (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 { NgModule } from '@angular/core'; | ||||
| import { CoreSearchComponentsModule } from './components/components.module'; | ||||
| 
 | ||||
| @NgModule({ | ||||
|     declarations: [ | ||||
|     ], | ||||
|     imports: [ | ||||
|         CoreSearchComponentsModule, | ||||
|     ], | ||||
|     providers: [ | ||||
|         CoreSearchComponentsModule, | ||||
|     ], | ||||
| }) | ||||
| export class CoreSearchModule {} | ||||
							
								
								
									
										133
									
								
								src/app/core/search/services/search-history.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								src/app/core/search/services/search-history.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,133 @@ | ||||
| // (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 { CoreSites } from '@services/sites'; | ||||
| import { SQLiteDB } from '@classes/sqlitedb'; | ||||
| import { CoreSearchHistoryDBRecord, SEARCH_HISTORY_TABLE_NAME } from './search.history.db'; | ||||
| import { makeSingleton } from '@/app/singletons/core.singletons'; | ||||
| 
 | ||||
| /** | ||||
|  * Service that enables adding a history to a search box. | ||||
|  */ | ||||
| @Injectable({ | ||||
|     providedIn: 'root', | ||||
| }) | ||||
| export class CoreSearchHistoryProvider { | ||||
| 
 | ||||
|     protected static readonly HISTORY_LIMIT = 10; | ||||
| 
 | ||||
|     /** | ||||
|      * Get a search area history sorted by use. | ||||
|      * | ||||
|      * @param searchArea Search Area Name. | ||||
|      * @param siteId Site ID. If not defined, current site. | ||||
|      * @return Promise resolved with the list of items when done. | ||||
|      */ | ||||
|     async getSearchHistory(searchArea: string, siteId?: string): Promise<CoreSearchHistoryDBRecord[]> { | ||||
|         const site = await CoreSites.instance.getSite(siteId); | ||||
|         const conditions = { | ||||
|             searcharea: searchArea, | ||||
|         }; | ||||
| 
 | ||||
|         const history: CoreSearchHistoryDBRecord[] = await site.getDb().getRecords(SEARCH_HISTORY_TABLE_NAME, conditions); | ||||
| 
 | ||||
|         // Sorting by last used DESC.
 | ||||
|         return history.sort((a, b) => (b.lastused || 0) - (a.lastused || 0)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Controls search limit and removes the last item if overflows. | ||||
|      * | ||||
|      * @param  searchArea Search area to control | ||||
|      * @param  db SQLite DB where to perform the search. | ||||
|      * @return Resolved when done. | ||||
|      */ | ||||
|     protected async controlSearchLimit(searchArea: string, db: SQLiteDB): Promise<void> { | ||||
|         const items = await this.getSearchHistory(searchArea); | ||||
|         if (items.length > CoreSearchHistoryProvider.HISTORY_LIMIT) { | ||||
|             // Over the limit. Remove the last.
 | ||||
|             const lastItem = items.pop(); | ||||
| 
 | ||||
|             const searchItem = { | ||||
|                 searcharea: lastItem!.searcharea, | ||||
|                 searchedtext: lastItem!.searchedtext, | ||||
|             }; | ||||
| 
 | ||||
|             await db.deleteRecords(SEARCH_HISTORY_TABLE_NAME, searchItem); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Updates the search history item if exists. | ||||
|      * | ||||
|      * @param  searchArea Area where the search has been performed. | ||||
|      * @param  text Text of the performed text. | ||||
|      * @param  db SQLite DB where to perform the search. | ||||
|      * @return True if exists, false otherwise. | ||||
|      */ | ||||
|     protected async updateExistingItem(searchArea: string, text: string, db: SQLiteDB): Promise<boolean> { | ||||
|         const searchItem = { | ||||
|             searcharea: searchArea, | ||||
|             searchedtext: text, | ||||
|         }; | ||||
| 
 | ||||
|         try { | ||||
|             const existingItem: CoreSearchHistoryDBRecord = await db.getRecord(SEARCH_HISTORY_TABLE_NAME, searchItem); | ||||
| 
 | ||||
|             // If item exist, update time and number of times searched.
 | ||||
|             existingItem.lastused = Date.now(); | ||||
|             existingItem.times++; | ||||
| 
 | ||||
|             await db.updateRecords(SEARCH_HISTORY_TABLE_NAME, existingItem, searchItem); | ||||
| 
 | ||||
|             return true; | ||||
|         } catch { | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Inserts a searched term on the history. | ||||
|      * | ||||
|      * @param  searchArea Area where the search has been performed. | ||||
|      * @param  text Text of the performed text. | ||||
|      * @param  siteId Site ID. If not defined, current site. | ||||
|      * @return Resolved when done. | ||||
|      */ | ||||
|     async insertOrUpdateSearchText(searchArea: string, text: string, siteId?: string): Promise<void> { | ||||
|         const site = await CoreSites.instance.getSite(siteId); | ||||
|         const db = site.getDb(); | ||||
| 
 | ||||
|         const exists = await this.updateExistingItem(searchArea, text, db); | ||||
| 
 | ||||
|         if (!exists) { | ||||
|             // If item is new, control the history does not goes over the limit.
 | ||||
|             const searchItem: CoreSearchHistoryDBRecord = { | ||||
|                 searcharea: searchArea, | ||||
|                 searchedtext: text, | ||||
|                 lastused: Date.now(), | ||||
|                 times: 1, | ||||
|             }; | ||||
| 
 | ||||
|             await db.insertRecord(SEARCH_HISTORY_TABLE_NAME, searchItem); | ||||
| 
 | ||||
|             await this.controlSearchLimit(searchArea, db); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| export class CoreSearchHistory extends makeSingleton(CoreSearchHistoryProvider) {} | ||||
							
								
								
									
										67
									
								
								src/app/core/search/services/search.history.db.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/app/core/search/services/search.history.db.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,67 @@ | ||||
| // (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 { CoreSiteSchema, registerSiteSchema } from '@services/sites'; | ||||
| 
 | ||||
| /** | ||||
|  * Database variables for CoreSearchHistory service. | ||||
|  */ | ||||
| export const SEARCH_HISTORY_TABLE_NAME = 'seach_history'; | ||||
| const SITE_SCHEMA: CoreSiteSchema = { | ||||
|     name: 'CoreSearchHistoryProvider', | ||||
|     version: 1, | ||||
|     tables: [ | ||||
|         { | ||||
|             name: SEARCH_HISTORY_TABLE_NAME, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'searcharea', | ||||
|                     type: 'TEXT', | ||||
|                     notNull: true, | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'lastused', | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true, | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'times', | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true, | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'searchedtext', | ||||
|                     type: 'TEXT', | ||||
|                     notNull: true, | ||||
|                 }, | ||||
|             ], | ||||
|             primaryKeys: ['searcharea', 'searchedtext'], | ||||
|         }, | ||||
|     ], | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Search history item definition. | ||||
|  */ | ||||
| export type CoreSearchHistoryDBRecord = { | ||||
|     searcharea: string; // Search area where the search has been performed.
 | ||||
|     lastused: number; // Timestamp of the last search.
 | ||||
|     searchedtext: string; // Text of the performed search.
 | ||||
|     times: number; // Times search has been performed (if previously in history).
 | ||||
| }; | ||||
| 
 | ||||
| export const initCoreSearchHistoryDB = (): void => { | ||||
|     registerSiteSchema(SITE_SCHEMA); | ||||
| }; | ||||
| 
 | ||||
| @ -20,6 +20,5 @@ import { CoreSettingsRoutingModule } from './settings-routing.module'; | ||||
|     imports: [ | ||||
|         CoreSettingsRoutingModule, | ||||
|     ], | ||||
|     declarations: [], | ||||
| }) | ||||
| export class CoreSettingsModule {} | ||||
|  | ||||
| @ -1725,14 +1725,14 @@ export class CoreDomUtilsProvider { | ||||
|      * @param online Whether the action was done in offline or not. | ||||
|      * @param siteId The site affected. If not provided, no site affected. | ||||
|      */ | ||||
|     triggerFormSubmittedEvent(formRef: ElementRef | undefined, online?: boolean, siteId?: string): void { | ||||
|     triggerFormSubmittedEvent(formRef: ElementRef | HTMLFormElement | undefined, online?: boolean, siteId?: string): void { | ||||
|         if (!formRef) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         CoreEvents.trigger(CoreEvents.FORM_ACTION, { | ||||
|             action: 'submit', | ||||
|             form: formRef.nativeElement, | ||||
|             form: formRef.nativeElement || formRef, | ||||
|             online: !!online, | ||||
|         }, siteId); | ||||
|     } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user