forked from CIT/Vmeda.Online
		
	MOBILE-3210 myoverview: Add custom filters
This commit is contained in:
		
							parent
							
								
									b63b64bc67
								
							
						
					
					
						commit
						05fafe3e67
					
				| @ -1,8 +1,8 @@ | |||||||
| <ion-item-divider> | <ion-item-divider> | ||||||
|     <h2>{{ 'addon.block_myoverview.pluginname' | translate }}</h2> |     <h2>{{ 'addon.block_myoverview.pluginname' | translate }}</h2> | ||||||
|     <!-- Download all courses. --> |     <!-- Download all courses. --> | ||||||
|     <div *ngIf="downloadCoursesEnabled && downloadEnabled && courses[selectedFilter] && courses[selectedFilter].length > 1 && !showFilter" class="core-button-spinner" item-end> |     <div *ngIf="downloadCoursesEnabled && downloadEnabled && filteredCourses.length > 1 && !showFilter" class="core-button-spinner" item-end> | ||||||
|         <button *ngIf="prefetchCoursesData[selectedFilter].icon && prefetchCoursesData[selectedFilter].icon != 'spinner'" ion-button icon-only clear color="dark" (click)="prefetchCourses()"> |         <button *ngIf="prefetchCoursesData[selectedFilter] && prefetchCoursesData[selectedFilter].icon && prefetchCoursesData[selectedFilter].icon != 'spinner'" ion-button icon-only clear color="dark" (click)="prefetchCourses()"> | ||||||
|             <core-icon [name]="prefetchCoursesData[selectedFilter].icon"></core-icon> |             <core-icon [name]="prefetchCoursesData[selectedFilter].icon"></core-icon> | ||||||
|         </button> |         </button> | ||||||
|         <ion-badge class="core-course-download-courses-progress" *ngIf="prefetchCoursesData[selectedFilter].badge">{{prefetchCoursesData[selectedFilter].badge}}</ion-badge> |         <ion-badge class="core-course-download-courses-progress" *ngIf="prefetchCoursesData[selectedFilter].badge">{{prefetchCoursesData[selectedFilter].badge}}</ion-badge> | ||||||
| @ -23,11 +23,16 @@ | |||||||
|             <ion-option value="inprogress" *ngIf="showFilters.inprogress != 'hidden'" [disabled]="showFilters.inprogress == 'disabled'">{{ 'addon.block_myoverview.inprogress' | translate }}</ion-option> |             <ion-option value="inprogress" *ngIf="showFilters.inprogress != 'hidden'" [disabled]="showFilters.inprogress == 'disabled'">{{ 'addon.block_myoverview.inprogress' | translate }}</ion-option> | ||||||
|             <ion-option value="future" *ngIf="showFilters.future != 'hidden'" [disabled]="showFilters.future == 'disabled'">{{ 'addon.block_myoverview.future' | translate }}</ion-option> |             <ion-option value="future" *ngIf="showFilters.future != 'hidden'" [disabled]="showFilters.future == 'disabled'">{{ 'addon.block_myoverview.future' | translate }}</ion-option> | ||||||
|             <ion-option value="past" *ngIf="showFilters.past != 'hidden'" [disabled]="showFilters.past == 'disabled'">{{ 'addon.block_myoverview.past' | translate }}</ion-option> |             <ion-option value="past" *ngIf="showFilters.past != 'hidden'" [disabled]="showFilters.past == 'disabled'">{{ 'addon.block_myoverview.past' | translate }}</ion-option> | ||||||
|  |             <ng-container *ngIf="showFilters.custom != 'hidden'"> | ||||||
|  |                 <ng-container *ngFor="let customOption of customFilter; let index = index"> | ||||||
|  |                     <ion-option value="custom-{{index}}">{{ customOption.name }}</ion-option> | ||||||
|  |                 </ng-container> | ||||||
|  |             </ng-container> | ||||||
|             <ion-option value="favourite" *ngIf="showFilters.favourite != 'hidden'" [disabled]="showFilters.favourite == 'disabled'">{{ 'addon.block_myoverview.favourites' | translate }}</ion-option> |             <ion-option value="favourite" *ngIf="showFilters.favourite != 'hidden'" [disabled]="showFilters.favourite == 'disabled'">{{ 'addon.block_myoverview.favourites' | translate }}</ion-option> | ||||||
|             <ion-option value="hidden" *ngIf="showFilters.hidden != 'hidden'" [disabled]="showFilters.hidden == 'disabled'">{{ 'addon.block_myoverview.hiddencourses' | translate }}</ion-option> |             <ion-option value="hidden" *ngIf="showFilters.hidden != 'hidden'" [disabled]="showFilters.hidden == 'disabled'">{{ 'addon.block_myoverview.hiddencourses' | translate }}</ion-option> | ||||||
|         </ion-select> |         </ion-select> | ||||||
|     </div> |     </div> | ||||||
|     <core-empty-box *ngIf="courses[selectedFilter].length == 0" image="assets/img/icons/courses.svg" [message]="'addon.block_myoverview.nocourses' | translate"></core-empty-box> |     <core-empty-box *ngIf="filteredCourses.length == 0" image="assets/img/icons/courses.svg" [message]="'addon.block_myoverview.nocourses' | translate"></core-empty-box> | ||||||
| 
 | 
 | ||||||
|     <!-- Filter courses. --> |     <!-- Filter courses. --> | ||||||
|     <ion-searchbar #searchbar *ngIf="showFilter" [(ngModel)]="courses.filter" (ionInput)="filterChanged($event)" (ionCancel)="filterChanged()" [placeholder]="'core.courses.filtermycourses' | translate"> |     <ion-searchbar #searchbar *ngIf="showFilter" [(ngModel)]="courses.filter" (ionInput)="filterChanged($event)" (ionCancel)="filterChanged()" [placeholder]="'core.courses.filtermycourses' | translate"> | ||||||
|  | |||||||
| @ -43,12 +43,14 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
|         inprogress: [], |         inprogress: [], | ||||||
|         future: [], |         future: [], | ||||||
|         favourite: [], |         favourite: [], | ||||||
|         hidden: [] |         hidden: [], | ||||||
|  |         custom: [], // Leave it empty to avoid download all those courses.
 | ||||||
|     }; |     }; | ||||||
|  |     customFilter: any[] = []; | ||||||
|     selectedFilter = 'inprogress'; |     selectedFilter = 'inprogress'; | ||||||
|     sort = 'fullname'; |     sort = 'fullname'; | ||||||
|     currentSite: any; |     currentSite: any; | ||||||
|     filteredCourses: any[]; |     filteredCourses: any[] = []; | ||||||
|     prefetchCoursesData = { |     prefetchCoursesData = { | ||||||
|         all: {}, |         all: {}, | ||||||
|         allincludinghidden: {}, |         allincludinghidden: {}, | ||||||
| @ -56,7 +58,8 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
|         past: {}, |         past: {}, | ||||||
|         future: {}, |         future: {}, | ||||||
|         favourite: {}, |         favourite: {}, | ||||||
|         hidden: {} |         hidden: {}, | ||||||
|  |         custom: {}, // Leave it empty to avoid download all those courses.
 | ||||||
|     }; |     }; | ||||||
|     showFilters = { // Options are show, disabled, hidden.
 |     showFilters = { // Options are show, disabled, hidden.
 | ||||||
|         all: 'show', |         all: 'show', | ||||||
| @ -65,7 +68,8 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
|         inprogress: 'show', |         inprogress: 'show', | ||||||
|         future: 'show', |         future: 'show', | ||||||
|         favourite: 'show', |         favourite: 'show', | ||||||
|         hidden: 'show' |         hidden: 'show', | ||||||
|  |         custom: 'hidden', // True or false to show or hide.
 | ||||||
|     }; |     }; | ||||||
|     showFilter = false; |     showFilter = false; | ||||||
|     showSelectorFilter = false; |     showSelectorFilter = false; | ||||||
| @ -80,11 +84,15 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
|     protected courseIds = []; |     protected courseIds = []; | ||||||
|     protected fetchContentDefaultError = 'Error getting my overview data.'; |     protected fetchContentDefaultError = 'Error getting my overview data.'; | ||||||
| 
 | 
 | ||||||
|     constructor(injector: Injector, private coursesProvider: CoreCoursesProvider, |     constructor(injector: Injector, | ||||||
|             private courseCompletionProvider: AddonCourseCompletionProvider, private eventsProvider: CoreEventsProvider, |             protected coursesProvider: CoreCoursesProvider, | ||||||
|             private courseHelper: CoreCourseHelperProvider, |             protected courseCompletionProvider: AddonCourseCompletionProvider, | ||||||
|             private courseOptionsDelegate: CoreCourseOptionsDelegate, private coursesHelper: CoreCoursesHelperProvider, |             protected eventsProvider: CoreEventsProvider, | ||||||
|             private sitesProvider: CoreSitesProvider, private timeUtils: CoreTimeUtilsProvider) { |             protected courseHelper: CoreCourseHelperProvider, | ||||||
|  |             protected courseOptionsDelegate: CoreCourseOptionsDelegate, | ||||||
|  |             protected coursesHelper: CoreCoursesHelperProvider, | ||||||
|  |             protected sitesProvider: CoreSitesProvider, | ||||||
|  |             protected timeUtils: CoreTimeUtilsProvider) { | ||||||
| 
 | 
 | ||||||
|         super(injector, 'AddonBlockMyOverviewComponent'); |         super(injector, 'AddonBlockMyOverviewComponent'); | ||||||
|     } |     } | ||||||
| @ -115,7 +123,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
|             this.sort = value; |             this.sort = value; | ||||||
|         })); |         })); | ||||||
|         promises.push(this.currentSite.getLocalSiteConfig('AddonBlockMyOverviewFilter', this.selectedFilter).then((value) => { |         promises.push(this.currentSite.getLocalSiteConfig('AddonBlockMyOverviewFilter', this.selectedFilter).then((value) => { | ||||||
|             this.selectedFilter = typeof this.courses[value] == 'undefined' ? 'inprogress' : value; |             this.selectedFilter = value; | ||||||
|         })); |         })); | ||||||
| 
 | 
 | ||||||
|         Promise.all(promises).finally(() => { |         Promise.all(promises).finally(() => { | ||||||
| @ -213,6 +221,15 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
|                     (!config || config.displaygroupingstarred.value == '1'), |                     (!config || config.displaygroupingstarred.value == '1'), | ||||||
|                 this.courses.favourite.length === 0); |                 this.courses.favourite.length === 0); | ||||||
| 
 | 
 | ||||||
|  |             this.showFilters.custom = this.getShowFilterValue(this.showSelectorFilter && config && | ||||||
|  |                     config.displaygroupingcustomfield.value == '1' && config.customfieldsexport && config.customfieldsexport.value, | ||||||
|  |                     false); | ||||||
|  |             if (this.showFilters.custom == 'show') { | ||||||
|  |                 this.customFilter = this.textUtils.parseJSON(config.customfieldsexport.value); | ||||||
|  |             } else { | ||||||
|  |                 this.customFilter = []; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             if (this.showSelectorFilter) { |             if (this.showSelectorFilter) { | ||||||
|                 // Check if any selector is shown and not disabled.
 |                 // Check if any selector is shown and not disabled.
 | ||||||
|                 this.showSelectorFilter = Object.keys(this.showFilters).some((key) => { |                 this.showSelectorFilter = Object.keys(this.showFilters).some((key) => { | ||||||
| @ -224,7 +241,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
|                 // No selector, or the default option is disabled, show all.
 |                 // No selector, or the default option is disabled, show all.
 | ||||||
|                 this.selectedFilter = 'all'; |                 this.selectedFilter = 'all'; | ||||||
|             } |             } | ||||||
|             this.filteredCourses = this.courses[this.selectedFilter]; |             this.setCourseFilter(this.selectedFilter); | ||||||
| 
 | 
 | ||||||
|             this.initPrefetchCoursesIcons(); |             this.initPrefetchCoursesIcons(); | ||||||
|         }); |         }); | ||||||
| @ -248,17 +265,17 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
|      */ |      */ | ||||||
|     filterChanged(event: any): void { |     filterChanged(event: any): void { | ||||||
|         const newValue = event.target.value && event.target.value.trim().toLowerCase(); |         const newValue = event.target.value && event.target.value.trim().toLowerCase(); | ||||||
|         if (!newValue || !this.courses['all']) { |         if (!newValue || this.courses.allincludinghidden.length <= 0) { | ||||||
|             this.filteredCourses = this.courses['all']; |             this.filteredCourses = this.courses.allincludinghidden; | ||||||
|         } else { |         } else { | ||||||
|             // Use displayname if avalaible, or fullname if not.
 |             // Use displayname if avalaible, or fullname if not.
 | ||||||
|             if (this.courses['all'].length > 0 && |             if (this.courses.allincludinghidden.length > 0 && | ||||||
|                     typeof this.courses['all'][0].displayname != 'undefined') { |                     typeof this.courses.allincludinghidden[0].displayname != 'undefined') { | ||||||
|                 this.filteredCourses = this.courses['all'].filter((course) => { |                 this.filteredCourses = this.courses.allincludinghidden.filter((course) => { | ||||||
|                     return course.displayname.toLowerCase().indexOf(newValue) > -1; |                     return course.displayname.toLowerCase().indexOf(newValue) > -1; | ||||||
|                 }); |                 }); | ||||||
|             } else { |             } else { | ||||||
|                 this.filteredCourses = this.courses['all'].filter((course) => { |                 this.filteredCourses = this.courses.allincludinghidden.filter((course) => { | ||||||
|                     return course.fullname.toLowerCase().indexOf(newValue) > -1; |                     return course.fullname.toLowerCase().indexOf(newValue) > -1; | ||||||
|                 }); |                 }); | ||||||
|             } |             } | ||||||
| @ -304,8 +321,50 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
|      * The selected courses filter have changed. |      * The selected courses filter have changed. | ||||||
|      */ |      */ | ||||||
|     selectedChanged(): void { |     selectedChanged(): void { | ||||||
|         this.currentSite.setLocalSiteConfig('AddonBlockMyOverviewFilter', this.selectedFilter); |         this.setCourseFilter(this.selectedFilter); | ||||||
|         this.filteredCourses = this.courses[this.selectedFilter]; |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Set selected courses filter. | ||||||
|  |      * | ||||||
|  |      * @param {string} filter Filter name to set. | ||||||
|  |      */ | ||||||
|  |     protected setCourseFilter(filter: string): void { | ||||||
|  |         this.selectedFilter = filter; | ||||||
|  | 
 | ||||||
|  |         if (this.showFilters.custom == 'show' && filter.startsWith('custom-') && | ||||||
|  |                 typeof this.customFilter[filter.substr(7)] != 'undefined') { | ||||||
|  |             const filterName = this.block.configs.customfiltergrouping.value, | ||||||
|  |                 filterValue = this.customFilter[filter.substr(7)].value; | ||||||
|  | 
 | ||||||
|  |             this.loaded = false; | ||||||
|  | 
 | ||||||
|  |             this.coursesProvider.getEnrolledCoursesByCustomField(filterName, filterValue).then((courses) => { | ||||||
|  |                 // Get the courses information from allincludinghidden to get the max info about the course.
 | ||||||
|  |                 const courseIds = courses.map((course) => course.id); | ||||||
|  |                 this.filteredCourses = this.courses.allincludinghidden.filter((allCourse) => | ||||||
|  |                     courseIds.indexOf(allCourse.id) !== -1); | ||||||
|  |             }).catch((error) => { | ||||||
|  |                 this.domUtils.showErrorModalDefault(error, this.fetchContentDefaultError); | ||||||
|  |             }).finally(() => { | ||||||
|  |                 this.loaded = true; | ||||||
|  |             }); | ||||||
|  |         } else { | ||||||
|  |             // Only save the filter if not a custom one.
 | ||||||
|  |             this.currentSite.setLocalSiteConfig('AddonBlockMyOverviewFilter', filter); | ||||||
|  | 
 | ||||||
|  |             if (this.showFilters[filter] == 'show') { | ||||||
|  |                 this.filteredCourses = this.courses[filter]; | ||||||
|  |             } else { | ||||||
|  |                 const activeFilter = Object.keys(this.showFilters).find((name) => { | ||||||
|  |                     return this.showFilters[name] == 'show'; | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |                 if (activeFilter) { | ||||||
|  |                     this.setCourseFilter(activeFilter); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -314,6 +373,8 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
|      * @param courses Courses to filter. |      * @param courses Courses to filter. | ||||||
|      */ |      */ | ||||||
|     initCourseFilters(courses: any[]): void { |     initCourseFilters(courses: any[]): void { | ||||||
|  |         this.courses.allincludinghidden = courses; | ||||||
|  | 
 | ||||||
|         if (this.showSortFilter) { |         if (this.showSortFilter) { | ||||||
|                 if (this.sort == 'lastaccess') { |                 if (this.sort == 'lastaccess') { | ||||||
|                 courses.sort((a, b) => { |                 courses.sort((a, b) => { | ||||||
| @ -330,7 +391,6 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         this.courses.all = []; |         this.courses.all = []; | ||||||
|         this.courses.allincludinghidden = []; |  | ||||||
|         this.courses.past = []; |         this.courses.past = []; | ||||||
|         this.courses.inprogress = []; |         this.courses.inprogress = []; | ||||||
|         this.courses.future = []; |         this.courses.future = []; | ||||||
| @ -339,7 +399,6 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
| 
 | 
 | ||||||
|         const today = this.timeUtils.timestamp(); |         const today = this.timeUtils.timestamp(); | ||||||
|         courses.forEach((course) => { |         courses.forEach((course) => { | ||||||
|             this.courses.allincludinghidden.push(course); |  | ||||||
|             if (course.hidden) { |             if (course.hidden) { | ||||||
|                 this.courses.hidden.push(course); |                 this.courses.hidden.push(course); | ||||||
|             } else  { |             } else  { | ||||||
| @ -362,7 +421,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         this.filteredCourses = this.courses[this.selectedFilter]; |         this.setCourseFilter(this.selectedFilter); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -373,7 +432,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
|     switchSort(sort: string): void { |     switchSort(sort: string): void { | ||||||
|         this.sort = sort; |         this.sort = sort; | ||||||
|         this.currentSite.setLocalSiteConfig('AddonBlockMyOverviewSort', this.sort); |         this.currentSite.setLocalSiteConfig('AddonBlockMyOverviewSort', this.sort); | ||||||
|         this.initCourseFilters(this.courses.all.concat(this.courses.hidden)); |         this.initCourseFilters(this.courses.allincludinghidden); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -382,7 +441,12 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
|     switchFilter(): void { |     switchFilter(): void { | ||||||
|         this.showFilter = !this.showFilter; |         this.showFilter = !this.showFilter; | ||||||
|         this.courses.filter = ''; |         this.courses.filter = ''; | ||||||
|         this.filteredCourses = this.courses[this.showFilter ? 'all' : this.selectedFilter]; | 
 | ||||||
|  |         if (this.showFilter) { | ||||||
|  |             this.filteredCourses = this.courses.allincludinghidden; | ||||||
|  |         } else { | ||||||
|  |             this.setCourseFilter(this.selectedFilter); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -402,7 +466,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem | |||||||
|      * @return If switch button that enables the filter input is shown or not. |      * @return If switch button that enables the filter input is shown or not. | ||||||
|      */ |      */ | ||||||
|     showFilterSwitchButton(): boolean { |     showFilterSwitchButton(): boolean { | ||||||
|         return this.loaded && this.courses['all'] && this.courses['all'].length > 5; |         return this.loaded && this.courses.allincludinghidden && this.courses.allincludinghidden.length > 5; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -514,6 +514,36 @@ export class CoreCoursesProvider { | |||||||
|         return this.ROOT_CACHE_KEY + 'coursesbyfield:' + field + ':' + value; |         return this.ROOT_CACHE_KEY + 'coursesbyfield:' + field + ':' + value; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Get courses matching the given custom field. Only works in online. | ||||||
|  |      * | ||||||
|  |      * @param  customFieldName Custom field name. | ||||||
|  |      * @param  customFieldValue Custom field value. | ||||||
|  |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @return Promise resolved with the list of courses. | ||||||
|  |      * @since 3.8 | ||||||
|  |      */ | ||||||
|  |     getEnrolledCoursesByCustomField(customFieldName: string, customFieldValue: string, siteId?: string): Promise<any[]> { | ||||||
|  |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|  |             const data = { | ||||||
|  |                     classification: 'customfield', | ||||||
|  |                     customfieldname: customFieldName, | ||||||
|  |                     customfieldvalue: customFieldValue | ||||||
|  |                 }, | ||||||
|  |                 preSets = { | ||||||
|  |                     getFromCache: false | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|  |             return site.read('core_course_get_enrolled_courses_by_timeline_classification', data, preSets).then((courses) => { | ||||||
|  |                 if (courses.courses) { | ||||||
|  |                     return courses.courses; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 return Promise.reject(null); | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Check if get courses by field WS is available in a certain site. |      * Check if get courses by field WS is available in a certain site. | ||||||
|      * |      * | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user