@@ -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",