diff --git a/src/addons/block/myoverview/components/myoverview/addon-block-myoverview.html b/src/addons/block/myoverview/components/myoverview/addon-block-myoverview.html index 884437ea6..422f1b3e7 100644 --- a/src/addons/block/myoverview/components/myoverview/addon-block-myoverview.html +++ b/src/addons/block/myoverview/components/myoverview/addon-block-myoverview.html @@ -4,20 +4,19 @@
-
- + - - - {{prefetchCoursesData[selectedFilter].badge}} + + {{prefetchCoursesData[timeSelectorFilter].badge}} - +
@@ -40,9 +39,9 @@
-
+
- + {{ 'addon.block_myoverview.allincludinghidden' | translate }} @@ -77,6 +76,16 @@
+
+ + + + {{ 'addon.block_myoverview.'+layout | translate }} + + + +
+ @@ -88,7 +97,7 @@
- + diff --git a/src/addons/block/myoverview/components/myoverview/myoverview.ts b/src/addons/block/myoverview/components/myoverview/myoverview.ts index 1d71653d0..0f3cf060f 100644 --- a/src/addons/block/myoverview/components/myoverview/myoverview.ts +++ b/src/addons/block/myoverview/components/myoverview/myoverview.ts @@ -59,54 +59,54 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem value: string; }[] = []; - selectedFilter = 'inprogress'; + timeSelectorFilter = 'inprogress'; sort = 'fullname'; currentSite?: CoreSite; filteredCourses: CoreEnrolledCourseDataWithOptions[] = []; - prefetchCoursesData = { - all: { + prefetchCoursesData: Record = { + all: { icon: '', statusTranslatable: 'core.loading', status: '', loading: true, }, - allincludinghidden: { + allincludinghidden: { icon: '', statusTranslatable: 'core.loading', status: '', loading: true, }, - inprogress: { + inprogress: { icon: '', statusTranslatable: 'core.loading', status: '', loading: true, }, - past: { + past: { icon: '', statusTranslatable: 'core.loading', status: '', loading: true, }, - future: { + future: { icon: '', statusTranslatable: 'core.loading', status: '', loading: true, }, - favourite: { + favourite: { icon: '', statusTranslatable: 'core.loading', status: '', loading: true, }, - hidden: { + hidden: { icon: '', statusTranslatable: 'core.loading', status: '', loading: true, }, - custom: { + custom: { icon: '', statusTranslatable: '', status: '', @@ -126,12 +126,15 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem }; showFilter = false; - showSelectorFilter = false; + showTimeSelectorFilter = false; showSortFilter = false; downloadCourseEnabled = false; downloadCoursesEnabled = false; showSortByShortName = false; + layouts: AddonBlockMyOverviewLayouts[] = []; + selectedLayout: AddonBlockMyOverviewLayouts = 'card'; + protected prefetchIconsInitialized = false; protected isDestroyed = false; protected coursesObserver?: CoreEventObserver; @@ -169,21 +172,31 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem CoreSites.getCurrentSiteId(), ); - this.currentSite = CoreSites.getCurrentSite(); + this.currentSite = CoreSites.getRequiredCurrentSite(); const promises: Promise[] = []; - if (this.currentSite) { - promises.push(this.currentSite.getLocalSiteConfig('AddonBlockMyOverviewSort', this.sort).then((value) => { - this.sort = value; + promises.push(this.currentSite.getLocalSiteConfig('AddonBlockMyOverviewSort', this.sort).then((value) => { + this.sort = value; - return; - })); - promises.push(this.currentSite.getLocalSiteConfig('AddonBlockMyOverviewFilter', this.selectedFilter).then((value) => { - this.selectedFilter = value; + return; + })); + promises.push(this.currentSite.getLocalSiteConfig( + 'AddonBlockMyOverviewFilter', + this.timeSelectorFilter, + ).then((value) => { + this.timeSelectorFilter = value; - return; - })); - } + return; + })); + + promises.push(this.currentSite.getLocalSiteConfig( + 'AddonBlockMyOverviewLayout', + this.selectedLayout, + ).then((value) => { + this.selectedLayout = value; + + return; + })); Promise.all(promises).finally(() => { super.ngOnInit(); @@ -229,6 +242,8 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem protected async fetchContent(refresh?: boolean): Promise { const config = this.block.configsRecord; + this.loadLayouts(config?.layouts?.value.split(',')); + const showCategories = config?.displaycategories?.value == '1'; const courses = await CoreCoursesHelper.getUserCoursesWithOptions(this.sort, undefined, undefined, showCategories, { @@ -280,23 +295,23 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem this.courses.future.length === 0, ); - this.showSelectorFilter = courses.length > 0 && (this.courses.past.length > 0 || this.courses.future.length > 0 || + this.showTimeSelectorFilter = courses.length > 0 && (this.courses.past.length > 0 || this.courses.future.length > 0 || typeof courses[0].enddate != 'undefined'); this.showFilters.hidden = this.getShowFilterValue( - this.showSelectorFilter && typeof courses[0].hidden != 'undefined' && + this.showTimeSelectorFilter && typeof courses[0].hidden != 'undefined' && (!config || config.displaygroupinghidden?.value == '1'), this.courses.hidden.length === 0, ); this.showFilters.favourite = this.getShowFilterValue( - this.showSelectorFilter && typeof courses[0].isfavourite != 'undefined' && + this.showTimeSelectorFilter && typeof courses[0].isfavourite != 'undefined' && (!config || config.displaygroupingstarred?.value == '1' || config.displaygroupingfavourites?.value == '1'), this.courses.favourite.length === 0, ); this.showFilters.custom = this.getShowFilterValue( - this.showSelectorFilter && config?.displaygroupingcustomfield?.value == '1' && !!config?.customfieldsexport?.value, + this.showTimeSelectorFilter && config?.displaygroupingcustomfield?.value == '1' && !!config?.customfieldsexport?.value, false, ); if (this.showFilters.custom == 'show') { @@ -305,25 +320,54 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem this.customFilter = []; } - if (this.showSelectorFilter) { + if (this.showTimeSelectorFilter) { // Check if any selector is shown and not disabled. - this.showSelectorFilter = Object.keys(this.showFilters).some((key) => this.showFilters[key] == 'show'); + this.showTimeSelectorFilter = Object.keys(this.showFilters).some((key) => this.showFilters[key] == 'show'); - if (!this.showSelectorFilter) { + if (!this.showTimeSelectorFilter) { // All filters disabled, display all the courses. this.showFilters.all = 'show'; } } - if (!this.showSelectorFilter) { + if (!this.showTimeSelectorFilter) { // No selector, display all the courses. - this.selectedFilter = 'all'; + this.timeSelectorFilter = 'all'; } - this.setCourseFilter(this.selectedFilter); + this.setCourseFilter(this.timeSelectorFilter); this.initPrefetchCoursesIcons(); } + /** + * Load block layouts. + * + * @param layouts Config available layouts. + */ + protected loadLayouts(layouts: string[] = []): void { + this.layouts = []; + + layouts.forEach((layout) => { + if (layout == '') { + return; + } + + const validLayout: AddonBlockMyOverviewLayouts = layout == 'summary' ? 'list' : layout as AddonBlockMyOverviewLayouts; + if (!this.layouts.includes(validLayout)) { + this.layouts.push(validLayout); + } + }); + + // If no layout is available use card. + if (this.layouts.length == 0) { + this.layouts = ['card']; + } + + if (!this.layouts.includes(this.selectedLayout)) { + this.selectedLayout = this.layouts[0]; + } + } + /** * Helper function to help with filter values. * @@ -417,7 +461,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem * @return Promise resolved when done. */ async prefetchCourses(): Promise { - const selected = this.selectedFilter; + const selected = this.timeSelectorFilter; const initialIcon = this.prefetchCoursesData[selected].icon; try { @@ -442,13 +486,14 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem } /** - * The selected courses filter have changed. + * The layout have changed. * - * @param filter New filter + * @param layout New layout. */ - selectedChanged(filter: string): void { - this.selectedFilter = filter; - this.setCourseFilter(this.selectedFilter); + layoutChanged(layout: AddonBlockMyOverviewLayouts): void { + this.selectedLayout = layout; + + this.currentSite?.setLocalSiteConfig('AddonBlockMyOverviewLayout', layout); } /** @@ -457,7 +502,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem * @param filter Filter name to set. */ protected async setCourseFilter(filter: string): Promise { - this.selectedFilter = filter; + this.timeSelectorFilter = filter; if (this.showFilters.custom == 'show' && filter.startsWith('custom-') && typeof this.customFilter[filter.substr(7)] != 'undefined') { @@ -497,6 +542,16 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem } } + /** + * The time selector courses filter have changed. + * + * @param filter New filter + */ + timeSelectorChanged(filter: string): void { + this.timeSelectorFilter = filter; + this.setCourseFilter(this.timeSelectorFilter); + } + /** * Init courses filters. * @@ -556,7 +611,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem } }); - this.setCourseFilter(this.selectedFilter); + this.setCourseFilter(this.timeSelectorFilter); } /** @@ -580,7 +635,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem if (this.showFilter) { this.filteredCourses = this.courses.allincludinghidden; } else { - this.setCourseFilter(this.selectedFilter); + this.setCourseFilter(this.timeSelectorFilter); } } @@ -614,3 +669,5 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem } } + +type AddonBlockMyOverviewLayouts = 'card'|'list'; diff --git a/src/addons/block/myoverview/lang.json b/src/addons/block/myoverview/lang.json index 7bca82636..19cbb6144 100644 --- a/src/addons/block/myoverview/lang.json +++ b/src/addons/block/myoverview/lang.json @@ -1,11 +1,13 @@ { "all": "All (except removed from view)", "allincludinghidden": "All", + "card": "Card", "favourites": "Starred", "future": "Future", "hiddencourses": "Removed from view", "inprogress": "In progress", "lastaccessed": "Last accessed", + "list": "List", "nocourses": "No courses", "past": "Past", "pluginname": "Course overview",