MOBILE-2201 tag: Index page
This commit is contained in:
		
							parent
							
								
									353c6823db
								
							
						
					
					
						commit
						b2db3774e6
					
				| @ -1800,11 +1800,15 @@ | ||||
|   "core.submit": "moodle", | ||||
|   "core.success": "moodle", | ||||
|   "core.tablet": "local_moodlemobileapp", | ||||
|   "core.tag.errorareanotsupported": "local_moodlemobileapp", | ||||
|   "core.tag.itemstaggedwith": "moodle", | ||||
|   "core.tag.tag": "moodle", | ||||
|   "core.tag.tagarea_course": "moodle", | ||||
|   "core.tag.tagarea_course_modules": "moodle", | ||||
|   "core.tag.tagarea_post": "moodle", | ||||
|   "core.tag.tagarea_user": "moodle", | ||||
|   "core.tag.tags": "moodle", | ||||
|   "core.tag.warningareasnotsupported": "local_moodlemobileapp", | ||||
|   "core.teachers": "moodle", | ||||
|   "core.thereisdatatosync": "local_moodlemobileapp", | ||||
|   "core.thisdirection": "langconfig", | ||||
|  | ||||
| @ -1800,11 +1800,15 @@ | ||||
|     "core.submit": "Submit", | ||||
|     "core.success": "Success", | ||||
|     "core.tablet": "Tablet", | ||||
|     "core.tag.errorareanotsupported": "This tag area is not supported by the app.", | ||||
|     "core.tag.itemstaggedwith": "{{$a.tagarea}} tagged with \"{{$a.tag}}\"", | ||||
|     "core.tag.tag": "Tag", | ||||
|     "core.tag.tagarea_course": "Courses", | ||||
|     "core.tag.tagarea_course_modules": "Activities and resources", | ||||
|     "core.tag.tagarea_post": "Blog posts", | ||||
|     "core.tag.tagarea_user": "User interests", | ||||
|     "core.tag.tags": "Tags", | ||||
|     "core.tag.warningareasnotsupported": "Some of the tag areas are not displayed because they are not supported by the app.", | ||||
|     "core.teachers": "Teachers", | ||||
|     "core.thereisdatatosync": "There are offline {{$a}} to be synchronised.", | ||||
|     "core.thisdirection": "ltr", | ||||
|  | ||||
| @ -1,7 +1,11 @@ | ||||
| { | ||||
|     "errorareanotsupported": "This tag area is not supported by the app.", | ||||
|     "itemstaggedwith": "{{$a.tagarea}} tagged with \"{{$a.tag}}\"", | ||||
|     "tag": "Tag", | ||||
|     "tagarea_course": "Courses", | ||||
|     "tagarea_course_modules": "Activities and resources", | ||||
|     "tagarea_post": "Blog posts", | ||||
|     "tagarea_user": "User interests", | ||||
|     "tags": "Tags" | ||||
|     "tags": "Tags", | ||||
|     "warningareasnotsupported": "Some of the tag areas are not displayed because they are not supported by the app." | ||||
| } | ||||
|  | ||||
							
								
								
									
										16
									
								
								src/core/tag/pages/index-area/index-area.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/core/tag/pages/index-area/index-area.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| <ion-header> | ||||
|     <ion-navbar core-back-button> | ||||
|         <ion-title>{{ 'core.tag.itemstaggedwith' | translate: { $a: {tagarea: areaNameKey | translate, tag: tagName} } }}</ion-title> | ||||
|     </ion-navbar> | ||||
| </ion-header> | ||||
| <ion-content> | ||||
|     <ion-refresher [enabled]="loaded" (ionRefresh)="refreshData($event)"> | ||||
|         <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||
|     </ion-refresher> | ||||
|     <core-loading [hideUntil]="loaded"> | ||||
|         <ng-container *ngIf="loaded"> | ||||
|             <core-dynamic-component [component]="areaComponent" [data]="{items: items}"></core-dynamic-component> | ||||
|         </ng-container> | ||||
|         <core-infinite-loading [enabled]="canLoadMore" (action)="loadMore($event)" [error]="loadMoreError"></core-infinite-loading> | ||||
|     </core-loading> | ||||
| </ion-content> | ||||
							
								
								
									
										33
									
								
								src/core/tag/pages/index-area/index-area.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/core/tag/pages/index-area/index-area.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| // (C) Copyright 2015 Martin Dougiamas
 | ||||
| //
 | ||||
| // 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 { IonicPageModule } from 'ionic-angular'; | ||||
| import { TranslateModule } from '@ngx-translate/core'; | ||||
| import { CoreTagIndexAreaPage } from './index-area'; | ||||
| import { CoreComponentsModule } from '@components/components.module'; | ||||
| import { CoreDirectivesModule } from '@directives/directives.module'; | ||||
| 
 | ||||
| @NgModule({ | ||||
|     declarations: [ | ||||
|         CoreTagIndexAreaPage | ||||
|     ], | ||||
|     imports: [ | ||||
|         CoreComponentsModule, | ||||
|         CoreDirectivesModule, | ||||
|         IonicPageModule.forChild(CoreTagIndexAreaPage), | ||||
|         TranslateModule.forChild() | ||||
|     ], | ||||
| }) | ||||
| export class CoreTagIndexAreaPageModule {} | ||||
							
								
								
									
										150
									
								
								src/core/tag/pages/index-area/index-area.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								src/core/tag/pages/index-area/index-area.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,150 @@ | ||||
| // (C) Copyright 2015 Martin Dougiamas
 | ||||
| //
 | ||||
| // 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, Injector } from '@angular/core'; | ||||
| import { TranslateService } from '@ngx-translate/core'; | ||||
| import { IonicPage, NavParams } from 'ionic-angular'; | ||||
| import { CoreDomUtilsProvider } from '@providers/utils/dom'; | ||||
| import { CoreTagProvider } from '@core/tag/providers/tag'; | ||||
| import { CoreTagAreaDelegate } from '@core/tag/providers/area-delegate'; | ||||
| 
 | ||||
| /** | ||||
|  * Page that displays the tag index area. | ||||
|  */ | ||||
| @IonicPage({ segment: 'core-tag-index-area' }) | ||||
| @Component({ | ||||
|     selector: 'page-core-tag-index-area', | ||||
|     templateUrl: 'index-area.html', | ||||
| }) | ||||
| export class CoreTagIndexAreaPage { | ||||
|     tagId: number; | ||||
|     tagName: string; | ||||
|     collectionId: number; | ||||
|     areaId: number; | ||||
|     fromContextId: number; | ||||
|     contextId: number; | ||||
|     recursive: boolean; | ||||
|     areaNameKey: string; | ||||
|     loaded = false; | ||||
|     componentName: string; | ||||
|     itemType: string; | ||||
|     items = []; | ||||
|     nextPage = 0; | ||||
|     canLoadMore = false; | ||||
|     areaComponent: any; | ||||
|     loadMoreError = false; | ||||
| 
 | ||||
|     constructor(navParams: NavParams, private injector: Injector, private translate: TranslateService, | ||||
|             private tagProvider: CoreTagProvider, private domUtils: CoreDomUtilsProvider, | ||||
|             private tagAreaDelegate: CoreTagAreaDelegate) { | ||||
|         this.tagId = navParams.get('tagId'); | ||||
|         this.tagName = navParams.get('tagName'); | ||||
|         this.collectionId = navParams.get('collectionId'); | ||||
|         this.areaId = navParams.get('areaId'); | ||||
|         this.fromContextId = navParams.get('fromContextId'); | ||||
|         this.contextId = navParams.get('contextId'); | ||||
|         this.recursive = navParams.get('recursive'); | ||||
|         this.areaNameKey = navParams.get('areaNameKey'); | ||||
| 
 | ||||
|         // Pass the the following parameters to avoid fetching the first page.
 | ||||
|         this.componentName = navParams.get('componentName'); | ||||
|         this.itemType = navParams.get('itemType'); | ||||
|         this.items = navParams.get('items') || []; | ||||
|         this.nextPage = navParams.get('nextPage') || 0; | ||||
|         this.canLoadMore = !!navParams.get('canLoadMore'); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * View loaded. | ||||
|      */ | ||||
|     ionViewDidLoad(): void { | ||||
|         let promise: Promise<any>; | ||||
|         if (!this.componentName || !this.itemType || !this.items.length || this.nextPage == 0) { | ||||
|             promise = this.fetchData(true); | ||||
|         } else { | ||||
|             promise = Promise.resolve(); | ||||
|         } | ||||
| 
 | ||||
|         promise.then(() => { | ||||
|             return this.tagAreaDelegate.getComponent(this.componentName, this.itemType, this.injector).then((component) => { | ||||
|                 this.areaComponent = component; | ||||
|             }); | ||||
|         }).finally(() => { | ||||
|             this.loaded = true; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Fetch next page of the tag index area. | ||||
|      * | ||||
|      * @param {boolean} [refresh=false] Whether to refresh the data or fetch a new page. | ||||
|      * @return {Promise<any>} Resolved when done. | ||||
|      */ | ||||
|     fetchData(refresh: boolean = false): Promise<any> { | ||||
|         this.loadMoreError = false; | ||||
|         const page = refresh ? 0 : this.nextPage; | ||||
| 
 | ||||
|         return this.tagProvider.getTagIndexPerArea(this.tagId, this.tagName, this.collectionId, this.areaId, this.fromContextId, | ||||
|                 this.contextId, this.recursive, page).then((areas) => { | ||||
|             const area = areas[0]; | ||||
| 
 | ||||
|             return this.tagAreaDelegate.parseContent(area.component, area.itemtype, area.content).then((items) => { | ||||
|                 if (!items || !items.length) { | ||||
|                     // Tag area not supported.
 | ||||
|                     return Promise.reject(this.translate.instant('core.tag.errorareanotsupported')); | ||||
|                 } | ||||
| 
 | ||||
|                 if (page == 0) { | ||||
|                     this.items = items; | ||||
|                 } else { | ||||
|                     this.items.push(...items); | ||||
|                 } | ||||
|                 this.componentName = area.component; | ||||
|                 this.itemType = area.itemtype; | ||||
|                 this.areaNameKey = this.tagAreaDelegate.getDisplayNameKey(area.component, area.itemtype); | ||||
|                 this.canLoadMore = !!area.nextpageurl; | ||||
|                 this.nextPage = page + 1; | ||||
|             }); | ||||
|         }).catch((error) => { | ||||
|             this.loadMoreError = true; // Set to prevent infinite calls with infinite-loading.
 | ||||
|             this.domUtils.showErrorModalDefault(error, 'Error loading tag index'); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Load more items. | ||||
|      * | ||||
|      * @param {any} infiniteComplete Infinite scroll complete function. | ||||
|      * @return {Promise<any>} Resolved when done. | ||||
|      */ | ||||
|     loadMore(infiniteComplete: any): Promise<any> { | ||||
|         return this.fetchData().finally(() => { | ||||
|             infiniteComplete(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Refresh data. | ||||
|      * | ||||
|      * @param {any} refresher Refresher. | ||||
|      */ | ||||
|     refreshData(refresher: any): void { | ||||
|         this.tagProvider.invalidateTagIndexPerArea(this.tagId, this.tagName, this.collectionId, this.areaId, this.fromContextId, | ||||
|                 this.contextId, this.recursive).finally(() => { | ||||
|             this.fetchData(true).finally(() => { | ||||
|                 refresher.complete(); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										24
									
								
								src/core/tag/pages/index/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/core/tag/pages/index/index.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| <ion-header> | ||||
|     <ion-navbar core-back-button> | ||||
|         <ion-title>{{ 'core.tag.tag' | translate }}: {{ tagName }}</ion-title> | ||||
|     </ion-navbar> | ||||
| </ion-header> | ||||
| <core-split-view> | ||||
|     <ion-content> | ||||
|         <ion-refresher [enabled]="loaded" (ionRefresh)="refreshData($event)"> | ||||
|             <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||
|         </ion-refresher> | ||||
|         <core-loading [hideUntil]="loaded"> | ||||
|             <ion-list> | ||||
|                 <ion-item text-wrap *ngIf="hasUnsupportedAreas" class="core-warning-item"> | ||||
|                     <ion-icon item-start name="warning" color="warning"></ion-icon> | ||||
|                     {{ 'core.tag.warningareasnotsupported' | translate }} | ||||
|                 </ion-item> | ||||
|                 <a ion-item text-wrap *ngFor="let area of areas" [title]="area.nameKey | translate" (click)="openArea(area)" [class.core-split-item-selected]="area.id == selectedAreaId"> | ||||
|                     <h2>{{ area.nameKey | translate }}</h2> | ||||
|                     <ion-badge item-end *ngIf="area.badge">{{ area.badge }}</ion-badge> | ||||
|                 </a> | ||||
|             </ion-list> | ||||
|         </core-loading> | ||||
|     </ion-content> | ||||
| </core-split-view> | ||||
							
								
								
									
										33
									
								
								src/core/tag/pages/index/index.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/core/tag/pages/index/index.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| // (C) Copyright 2015 Martin Dougiamas
 | ||||
| //
 | ||||
| // 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 { IonicPageModule } from 'ionic-angular'; | ||||
| import { TranslateModule } from '@ngx-translate/core'; | ||||
| import { CoreTagIndexPage } from './index'; | ||||
| import { CoreComponentsModule } from '@components/components.module'; | ||||
| import { CoreDirectivesModule } from '@directives/directives.module'; | ||||
| 
 | ||||
| @NgModule({ | ||||
|     declarations: [ | ||||
|         CoreTagIndexPage | ||||
|     ], | ||||
|     imports: [ | ||||
|         CoreComponentsModule, | ||||
|         CoreDirectivesModule, | ||||
|         IonicPageModule.forChild(CoreTagIndexPage), | ||||
|         TranslateModule.forChild() | ||||
|     ], | ||||
| }) | ||||
| export class CoreTagIndexPageModule {} | ||||
							
								
								
									
										154
									
								
								src/core/tag/pages/index/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								src/core/tag/pages/index/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,154 @@ | ||||
| // (C) Copyright 2015 Martin Dougiamas
 | ||||
| //
 | ||||
| // 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, ViewChild } from '@angular/core'; | ||||
| import { IonicPage, NavParams } from 'ionic-angular'; | ||||
| import { CoreDomUtilsProvider } from '@providers/utils/dom'; | ||||
| import { CoreSplitViewComponent } from '@components/split-view/split-view'; | ||||
| import { CoreTagProvider } from '@core/tag/providers/tag'; | ||||
| import { CoreTagAreaDelegate } from '@core/tag/providers/area-delegate'; | ||||
| 
 | ||||
| /** | ||||
|  * Page that displays the tag index. | ||||
|  */ | ||||
| @IonicPage({ segment: 'core-tag-index' }) | ||||
| @Component({ | ||||
|     selector: 'page-core-tag-index', | ||||
|     templateUrl: 'index.html', | ||||
| }) | ||||
| export class CoreTagIndexPage { | ||||
|     @ViewChild(CoreSplitViewComponent) splitviewCtrl: CoreSplitViewComponent; | ||||
| 
 | ||||
|     tagId: number; | ||||
|     tagName: string; | ||||
|     collectionId: number; | ||||
|     areaId: number; | ||||
|     fromContextId: number; | ||||
|     contextId: number; | ||||
|     recursive: boolean; | ||||
|     loaded = false; | ||||
|     areas: Array<{ | ||||
|         id: number, | ||||
|         componentName: string, | ||||
|         itemType: string, | ||||
|         nameKey: string, | ||||
|         items: any[], | ||||
|         canLoadMore: boolean, | ||||
|         badge: string | ||||
|     }>; | ||||
|     selectedAreaId: number; | ||||
|     hasUnsupportedAreas = false; | ||||
| 
 | ||||
|     constructor(navParams: NavParams, private tagProvider: CoreTagProvider, private domUtils: CoreDomUtilsProvider, | ||||
|             private tagAreaDelegate: CoreTagAreaDelegate) { | ||||
|         this.tagId = navParams.get('tagId') || 0; | ||||
|         this.tagName = navParams.get('tagName') || ''; | ||||
|         this.collectionId = navParams.get('collectionId'); | ||||
|         this.areaId = navParams.get('areaId') || 0; | ||||
|         this.fromContextId = navParams.get('fromContextId') || 0; | ||||
|         this.contextId = navParams.get('contextId') || 0; | ||||
|         this.recursive = navParams.get('recursive') || true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * View loaded. | ||||
|      */ | ||||
|     ionViewDidLoad(): void { | ||||
|         this.fetchData().then(() => { | ||||
|             if (this.splitviewCtrl.isOn() && this.areas && this.areas.length > 0) { | ||||
|                 const area = this.areas.find((area) => area.id == this.areaId); | ||||
|                 this.openArea(area || this.areas[0]); | ||||
|             } | ||||
|         }).finally(() => { | ||||
|             this.loaded = true; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Fetch first page of tag index per area. | ||||
|      * | ||||
|      * @return {Promise<any>} Resolved when done. | ||||
|      */ | ||||
|     fetchData(): Promise<any> { | ||||
|         return this.tagProvider.getTagIndexPerArea(this.tagId, this.tagName, this.collectionId, this.areaId, this.fromContextId, | ||||
|                 this.contextId, this.recursive, 0).then((areas) => { | ||||
|             this.areas = []; | ||||
|             this.hasUnsupportedAreas = false; | ||||
| 
 | ||||
|             return Promise.all(areas.map((area) => { | ||||
|                 return this.tagAreaDelegate.parseContent(area.component, area.itemtype, area.content).then((items) => { | ||||
|                     if (!items || !items.length) { | ||||
|                         // Tag area not supported, skip.
 | ||||
|                         this.hasUnsupportedAreas = true; | ||||
| 
 | ||||
|                         return null; | ||||
|                     } | ||||
| 
 | ||||
|                     return { | ||||
|                         id: area.ta, | ||||
|                         componentName: area.component, | ||||
|                         itemType: area.itemtype, | ||||
|                         nameKey: this.tagAreaDelegate.getDisplayNameKey(area.component, area.itemtype), | ||||
|                         items, | ||||
|                         canLoadMore: !!area.nextpageurl, | ||||
|                         badge: items && items.length ? items.length + (area.nextpageurl ? '+' : '') : '', | ||||
|                     }; | ||||
|                 }); | ||||
|             })).then((areas) => { | ||||
|                 this.areas = areas.filter((area) => area != null); | ||||
|             }); | ||||
|         }).catch((error) => { | ||||
|             this.domUtils.showErrorModalDefault(error, 'Error loading tag index'); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Refresh data. | ||||
|      * | ||||
|      * @param {any} refresher Refresher. | ||||
|      */ | ||||
|     refreshData(refresher: any): void { | ||||
|         this.tagProvider.invalidateTagIndexPerArea(this.tagId, this.tagName, this.collectionId, this.areaId, this.fromContextId, | ||||
|                 this.contextId, this.recursive).finally(() => { | ||||
|             this.fetchData().finally(() => { | ||||
|                 refresher.complete(); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Navigate to an index area. | ||||
|      * | ||||
|      * @param {any} area Area. | ||||
|      */ | ||||
|     openArea(area: any): void { | ||||
|         this.selectedAreaId = area.id; | ||||
|         const params = { | ||||
|             tagId: this.tagId, | ||||
|             tagName: this.tagName, | ||||
|             collectionId: this.collectionId, | ||||
|             areaId: area.id, | ||||
|             fromContextId: this.fromContextId, | ||||
|             contextId: this.contextId, | ||||
|             recursive: this.recursive, | ||||
|             areaNameKey: area.nameKey, | ||||
|             componentName: area.component, | ||||
|             itemType: area.itemType, | ||||
|             items: area.items.slice(), | ||||
|             canLoadMore: area.canLoadMore, | ||||
|             nextPage: 1 | ||||
|         }; | ||||
|         this.splitviewCtrl.push('CoreTagIndexAreaPage', params); | ||||
|     } | ||||
| } | ||||
| @ -13,8 +13,27 @@ | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { TranslateService } from '@ngx-translate/core'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSite } from '@classes/site'; | ||||
| import { CoreSite, CoreSiteWSPreSets } from '@classes/site'; | ||||
| 
 | ||||
| /** | ||||
|  * Structure of a tag index returned by WS. | ||||
|  */ | ||||
| export interface CoreTagIndex { | ||||
|     tagid: number; | ||||
|     ta: number; | ||||
|     component: string; | ||||
|     itemtype: string; | ||||
|     nextpageurl: string; | ||||
|     prevpageurl: string; | ||||
|     exclusiveurl: string; | ||||
|     exclusivetext: string; | ||||
|     title: string; | ||||
|     content: string; | ||||
|     hascontent: number; | ||||
|     anchor: string; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Structure of a tag item returned by WS. | ||||
| @ -38,7 +57,9 @@ export interface CoreTagItem { | ||||
| @Injectable() | ||||
| export class CoreTagProvider { | ||||
| 
 | ||||
|     constructor(private sitesProvider: CoreSitesProvider) {} | ||||
|     protected ROOT_CACHE_KEY = 'CoreTag:'; | ||||
| 
 | ||||
|     constructor(private sitesProvider: CoreSitesProvider, private translate: TranslateService) {} | ||||
| 
 | ||||
|     /** | ||||
|      * Check whether tags are available in a certain site. | ||||
| @ -67,4 +88,96 @@ export class CoreTagProvider { | ||||
|                 site.wsAvailable('core_tag_get_tag_collections') && | ||||
|                 !site.isFeatureDisabled('NoDelegate_CoreTag'); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Fetch the tag index. | ||||
|      * | ||||
|      * @param {number} [id=0] Tag ID. | ||||
|      * @param {string} [name=''] Tag name. | ||||
|      * @param {number} [collectionId=0] Tag collection ID. | ||||
|      * @param {number} [areaId=0] Tag area ID. | ||||
|      * @param {number} [fromContextId=0] Context ID where the link was displayed. | ||||
|      * @param {number} [contextId=0] Context ID where to search for items. | ||||
|      * @param {boolean} [recursive=true] Search in the context and its children. | ||||
|      * @param {number} [page=0] Page number. | ||||
|      * @param {string} [siteId] Site ID. If not defined, current site. | ||||
|      * @return {Promise<CoreTagIndex[]>} Promise resolved with the tag index per area. | ||||
|      * @since 3.7 | ||||
|      */ | ||||
|     getTagIndexPerArea(id: number, name: string = '', collectionId: number = 0, areaId: number = 0, fromContextId: number = 0, | ||||
|             contextId: number = 0, recursive: boolean = true, page: number = 0, siteId?: string): Promise<CoreTagIndex[]> { | ||||
|         return this.sitesProvider.getSite(siteId).then((site) => { | ||||
|             const params = { | ||||
|                 tagindex: { | ||||
|                     id: id, | ||||
|                     tag: name, | ||||
|                     tc: collectionId, | ||||
|                     ta: areaId, | ||||
|                     excl: true, | ||||
|                     from: fromContextId, | ||||
|                     ctx: contextId, | ||||
|                     rec: recursive, | ||||
|                     page: page | ||||
|                 }, | ||||
|             }; | ||||
|             const preSets: CoreSiteWSPreSets = { | ||||
|                 updateFrequency: CoreSite.FREQUENCY_OFTEN, | ||||
|                 cacheKey: this.getTagIndexPerAreaKey(id, name, collectionId, areaId, fromContextId, contextId, recursive) | ||||
|             }; | ||||
| 
 | ||||
|             return site.read('core_tag_get_tagindex_per_area', params, preSets).catch((error) => { | ||||
|                 // Workaround for WS not passing parameter to error string.
 | ||||
|                 if (error && error.errorcode == 'notagsfound') { | ||||
|                     error.message = this.translate.instant('core.tag.notagsfound', {$a: name || id || ''}); | ||||
|                 } | ||||
| 
 | ||||
|                 return Promise.reject(error); | ||||
|             }).then((response) => { | ||||
|                 if (!response || !response.length) { | ||||
|                     return Promise.reject(null); | ||||
|                 } | ||||
| 
 | ||||
|                 return response; | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Invalidate tag index. | ||||
|      * | ||||
|      * @param {number} [id=0] Tag ID. | ||||
|      * @param {string} [name=''] Tag name. | ||||
|      * @param {number} [collectionId=0] Tag collection ID. | ||||
|      * @param {number} [areaId=0] Tag area ID. | ||||
|      * @param {number} [fromContextId=0] Context ID where the link was displayed. | ||||
|      * @param {number} [contextId=0] Context ID where to search for items. | ||||
|      * @param {boolean} [recursive=true] Search in the context and its children. | ||||
|      * @return {Promise<any>} Promise resolved when the data is invalidated. | ||||
|      */ | ||||
|     invalidateTagIndexPerArea(id: number, name: string = '', collectionId: number = 0, areaId: number = 0, | ||||
|             fromContextId: number = 0, contextId: number = 0, recursive: boolean = true, siteId?: string): Promise<any> { | ||||
|         return this.sitesProvider.getSite(siteId).then((site) => { | ||||
|             const key = this.getTagIndexPerAreaKey(id, name, collectionId, areaId, fromContextId, contextId, recursive); | ||||
| 
 | ||||
|             return site.invalidateWsCacheForKey(key); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get cache key for tag index. | ||||
|      * | ||||
|      * @param {number} id Tag ID. | ||||
|      * @param {string} name Tag name. | ||||
|      * @param {number} collectionId Tag collection ID. | ||||
|      * @param {number} areaId Tag area ID. | ||||
|      * @param {number} fromContextId Context ID where the link was displayed. | ||||
|      * @param {number} contextId Context ID where to search for items. | ||||
|      * @param {boolean} [recursive=true] Search in the context and its children. | ||||
|      * @return {string} Cache key. | ||||
|      */ | ||||
|     protected getTagIndexPerAreaKey(id: number, name: string, collectionId: number, areaId: number,  fromContextId: number, | ||||
|             contextId: number, recursive: boolean): string { | ||||
|         return this.ROOT_CACHE_KEY + 'index:' + id + ':' + name + ':' + collectionId + ':' + areaId + ':' + fromContextId + ':' | ||||
|             + contextId + ':' +  (recursive ? 1 : 0); | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user