diff --git a/src/core/features/courses/courses.module.ts b/src/core/features/courses/courses.module.ts
index 925858cc0..f4f801622 100644
--- a/src/core/features/courses/courses.module.ts
+++ b/src/core/features/courses/courses.module.ts
@@ -60,7 +60,7 @@ const mainMenuHomeSiblingRoutes: Routes = [
const mainMenuTabRoutes: Routes = [
{
path: CoreCoursesMyCoursesMainMenuHandlerService.PAGE_NAME,
- loadChildren: () => import('./pages/list/list.module').then(m => m.CoreCoursesListPageModule),
+ loadChildren: () => import('./pages/my/my.module').then(m => m.CoreCoursesMyCoursesPageModule),
},
];
diff --git a/src/core/features/courses/pages/my/my.html b/src/core/features/courses/pages/my/my.html
new file mode 100644
index 000000000..cd7224b05
--- /dev/null
+++ b/src/core/features/courses/pages/my/my.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+ {{ 'core.courses.mycourses' | translate }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core/features/courses/pages/my/my.module.ts b/src/core/features/courses/pages/my/my.module.ts
new file mode 100644
index 000000000..a86c67dff
--- /dev/null
+++ b/src/core/features/courses/pages/my/my.module.ts
@@ -0,0 +1,63 @@
+// (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 { Injector, NgModule } from '@angular/core';
+import { RouterModule, ROUTES, Routes } from '@angular/router';
+
+import { CoreSharedModule } from '@/core/shared.module';
+import { CoreBlockComponentsModule } from '@features/block/components/components.module';
+
+import { CoreCoursesMyCoursesPage } from './my';
+import { CoreMainMenuComponentsModule } from '@features/mainmenu/components/components.module';
+import { buildTabMainRoutes } from '@features/mainmenu/mainmenu-tab-routing.module';
+
+function buildRoutes(injector: Injector): Routes {
+ return [
+ {
+ path: '',
+ component: CoreCoursesMyCoursesPage,
+ },
+ {
+ path: 'list',
+ loadChildren: () =>
+ import('../list/list.module')
+ .then(m => m.CoreCoursesListPageModule),
+ },
+ ...buildTabMainRoutes(injector, {
+ redirectTo: '',
+ pathMatch: 'full',
+ }),
+ ];
+}
+
+@NgModule({
+ imports: [
+ CoreSharedModule,
+ CoreBlockComponentsModule,
+ CoreMainMenuComponentsModule,
+ ],
+ providers: [
+ {
+ provide: ROUTES,
+ multi: true,
+ deps: [Injector],
+ useFactory: buildRoutes,
+ },
+ ],
+ declarations: [
+ CoreCoursesMyCoursesPage,
+ ],
+ exports: [RouterModule],
+})
+export class CoreCoursesMyCoursesPageModule { }
diff --git a/src/core/features/courses/pages/my/my.scss b/src/core/features/courses/pages/my/my.scss
new file mode 100644
index 000000000..05e886016
--- /dev/null
+++ b/src/core/features/courses/pages/my/my.scss
@@ -0,0 +1,3 @@
+:host ::ng-deep ion-item-divider {
+ display: none !important;
+}
diff --git a/src/core/features/courses/pages/my/my.ts b/src/core/features/courses/pages/my/my.ts
new file mode 100644
index 000000000..09c02acad
--- /dev/null
+++ b/src/core/features/courses/pages/my/my.ts
@@ -0,0 +1,117 @@
+// (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, OnDestroy, OnInit, ViewChild } from '@angular/core';
+import { CoreBlockComponent } from '@features/block/components/block/block';
+import { IonRefresher } from '@ionic/angular';
+import { CoreNavigator } from '@services/navigator';
+import { CoreSites } from '@services/sites';
+import { CoreUtils } from '@services/utils/utils';
+import { CoreEventObserver, CoreEvents } from '@singletons/events';
+import { CoreCourses, CoreCoursesProvider } from '../../services/courses';
+
+/**
+ * Page that shows a my courses.
+ */
+@Component({
+ selector: 'page-core-courses-my',
+ templateUrl: 'my.html',
+ styleUrls: ['my.scss'],
+})
+export class CoreCoursesMyCoursesPage implements OnInit, OnDestroy {
+
+ @ViewChild(CoreBlockComponent) block!: CoreBlockComponent;
+
+ searchEnabled = false;
+ downloadEnabled = false;
+ downloadCourseEnabled = false;
+ downloadCoursesEnabled = false;
+ userId: number;
+
+ protected updateSiteObserver: CoreEventObserver;
+ protected downloadEnabledObserver: CoreEventObserver;
+
+ constructor() {
+ // Refresh the enabled flags if site is updated.
+ this.updateSiteObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, () => {
+ this.searchEnabled = !CoreCourses.isSearchCoursesDisabledInSite();
+ this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite();
+ this.downloadCoursesEnabled = !CoreCourses.isDownloadCoursesDisabledInSite();
+
+ this.downloadEnabled = (this.downloadCourseEnabled || this.downloadCoursesEnabled) && this.downloadEnabled;
+ }, CoreSites.getCurrentSiteId());
+
+ this.downloadEnabledObserver = CoreEvents.on(CoreCoursesProvider.EVENT_DASHBOARD_DOWNLOAD_ENABLED_CHANGED, (data) => {
+ this.downloadEnabled = (this.downloadCourseEnabled || this.downloadCoursesEnabled) && data.enabled;
+ });
+
+ this.userId = CoreSites.getCurrentSiteUserId();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ ngOnInit(): void {
+ this.searchEnabled = !CoreCourses.isSearchCoursesDisabledInSite();
+ this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite();
+ this.downloadCoursesEnabled = !CoreCourses.isDownloadCoursesDisabledInSite();
+
+ this.downloadEnabled =
+ (this.downloadCourseEnabled || this.downloadCoursesEnabled) && CoreCourses.getCourseDownloadOptionsEnabled();
+
+ }
+
+ /**
+ * Switch download enabled.
+ */
+ switchDownload(): void {
+ CoreCourses.setCourseDownloadOptionsEnabled(this.downloadEnabled);
+ }
+
+ /**
+ * Open page to manage courses storage.
+ */
+ manageCoursesStorage(): void {
+ CoreNavigator.navigateToSitePath('/storage');
+ }
+
+ /**
+ * Go to search courses.
+ */
+ async openSearch(): Promise {
+ CoreNavigator.navigateToSitePath('/list', { params : { mode: 'search' } });
+ }
+
+ /**
+ * Refresh the data.
+ *
+ * @param refresher Refresher.
+ */
+ async refresh(refresher?: IonRefresher): Promise {
+ if (this.block) {
+ await CoreUtils.ignoreErrors(this.block.doRefresh());
+ }
+
+ refresher?.complete();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ ngOnDestroy(): void {
+ this.updateSiteObserver?.off();
+ this.downloadEnabledObserver?.off();
+ }
+
+}
diff --git a/src/core/features/courses/services/handlers/my-courses-mainmenu.ts b/src/core/features/courses/services/handlers/my-courses-mainmenu.ts
index 8c2c51878..4d27add17 100644
--- a/src/core/features/courses/services/handlers/my-courses-mainmenu.ts
+++ b/src/core/features/courses/services/handlers/my-courses-mainmenu.ts
@@ -26,7 +26,7 @@ import { CoreDashboardHomeHandler } from './dashboard-home';
@Injectable({ providedIn: 'root' })
export class CoreCoursesMyCoursesMainMenuHandlerService implements CoreMainMenuHandler {
- static readonly PAGE_NAME = 'courses';
+ static readonly PAGE_NAME = 'my';
name = 'CoreCoursesMyCourses';
priority = 900;
@@ -35,13 +35,20 @@ export class CoreCoursesMyCoursesMainMenuHandlerService implements CoreMainMenuH
* @inheritdoc
*/
async isEnabled(): Promise {
- const siteId = CoreSites.getCurrentSiteId();
+ const site = CoreSites.getRequiredCurrentSite();
+
+ const siteId = site.getId();
const disabled = await CoreCourses.isMyCoursesDisabled(siteId);
if (disabled) {
return false;
}
+ if (site.isVersionGreaterEqualThan('4.0')) {
+ return true;
+ }
+
+ // Dashboard cannot be disabled on 3.5 or 3.6 so it will never show this tab.
const dashboardEnabled = await CoreDashboardHomeHandler.isEnabledForSite(siteId);
const siteHomeEnabled = await CoreSiteHomeHomeHandler.isEnabledForSite(siteId);