+
+
+ {{ item.courseName }}
+ {{ 'core.category' | translate }}: {{ item.categoryName }}
+
+
\ No newline at end of file
diff --git a/src/core/features/course/components/tag-area/tag-area.ts b/src/core/features/course/components/tag-area/tag-area.ts
new file mode 100644
index 000000000..401ba9b64
--- /dev/null
+++ b/src/core/features/course/components/tag-area/tag-area.ts
@@ -0,0 +1,42 @@
+// (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, Input } from '@angular/core';
+
+import { CoreCourseHelper } from '@features/course/services/course-helper';
+import { CoreCouseTagItems } from '@features/course/services/handlers/course-tag-area';
+
+/**
+ * Component that renders the course tag area.
+ */
+@Component({
+ selector: 'core-course-tag-area',
+ templateUrl: 'core-course-tag-area.html',
+})
+export class CoreCourseTagAreaComponent {
+
+ @Input() items?: CoreCouseTagItems[]; // Area items to render.
+
+ /**
+ * Open a course.
+ *
+ * @param courseId The course to open.
+ */
+ openCourse(courseId: number): void {
+ // @todo If this component is inside a split view, use the master nav to open it.
+ // const navCtrl = this.splitviewCtrl ? this.splitviewCtrl.getMasterNav() : this.navCtrl;
+ CoreCourseHelper.instance.getAndOpenCourse(courseId);
+ }
+
+}
diff --git a/src/core/features/course/course.module.ts b/src/core/features/course/course.module.ts
index bd623076c..4d1563d58 100644
--- a/src/core/features/course/course.module.ts
+++ b/src/core/features/course/course.module.ts
@@ -28,6 +28,10 @@ import { CoreCourseModulePrefetchDelegate } from './services/module-prefetch-del
import { CoreCronDelegate } from '@services/cron';
import { CoreCourseLogCronHandler } from './services/handlers/log-cron';
import { CoreCourseSyncCronHandler } from './services/handlers/sync-cron';
+import { CoreTagAreaDelegate } from '@features/tag/services/tag-area-delegate';
+import { CoreCourseTagAreaHandler } from './services/handlers/course-tag-area';
+import { CoreCourseModulesTagAreaHandler } from './services/handlers/modules-tag-area';
+import { CoreCourse } from './services/course';
const routes: Routes = [
{
@@ -65,7 +69,10 @@ const courseIndexRoutes: Routes = [
useFactory: () => () => {
CoreCronDelegate.instance.register(CoreCourseSyncCronHandler.instance);
CoreCronDelegate.instance.register(CoreCourseLogCronHandler.instance);
+ CoreTagAreaDelegate.instance.registerHandler(CoreCourseTagAreaHandler.instance);
+ CoreTagAreaDelegate.instance.registerHandler(CoreCourseModulesTagAreaHandler.instance);
+ CoreCourse.instance.initialize();
CoreCourseModulePrefetchDelegate.instance.initialize();
},
},
diff --git a/src/core/features/course/services/course.ts b/src/core/features/course/services/course.ts
index 989682fe6..9982e3d00 100644
--- a/src/core/features/course/services/course.ts
+++ b/src/core/features/course/services/course.ts
@@ -23,7 +23,7 @@ import { CoreTimeUtils } from '@services/utils/time';
import { CoreUtils } from '@services/utils/utils';
import { CoreSiteWSPreSets, CoreSite } from '@classes/site';
import { CoreConstants } from '@/core/constants';
-import { makeSingleton, Translate } from '@singletons';
+import { makeSingleton, Platform, Translate } from '@singletons';
import { CoreStatusWithWarningsWSResponse, CoreWSExternalFile } from '@services/ws';
import { CoreCourseStatusDBRecord, COURSE_STATUS_TABLE } from './database/course';
@@ -39,6 +39,8 @@ import { CoreWSError } from '@classes/errors/wserror';
import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications';
import { CoreCourseHelper, CoreCourseModuleCompletionData } from './course-helper';
import { CoreCourseFormatDelegate } from './format-delegate';
+import { CoreCronDelegate } from '@services/cron';
+import { CoreCourseLogCronHandler } from './handlers/log-cron';
const ROOT_CACHE_KEY = 'mmCourse:';
@@ -77,6 +79,27 @@ export class CoreCourseProvider {
this.logger = CoreLogger.getInstance('CoreCourseProvider');
}
+ /**
+ * Initialize.
+ */
+ initialize(): void {
+ Platform.instance.resume.subscribe(() => {
+ // Run the handler the app is open to keep user in online status.
+ setTimeout(() => {
+ CoreCronDelegate.instance.forceCronHandlerExecution(CoreCourseLogCronHandler.instance.name);
+ }, 1000);
+ });
+
+ CoreEvents.on(CoreEvents.LOGIN, () => {
+ setTimeout(() => {
+ // Ignore errors here, since probably login is not complete: it happens on token invalid.
+ CoreUtils.instance.ignoreErrors(
+ CoreCronDelegate.instance.forceCronHandlerExecution(CoreCourseLogCronHandler.instance.name),
+ );
+ }, 1000);
+ });
+ }
+
/**
* Check if the get course blocks WS is available in current site.
*
diff --git a/src/core/features/course/services/handlers/course-tag-area.ts b/src/core/features/course/services/handlers/course-tag-area.ts
new file mode 100644
index 000000000..216bf0479
--- /dev/null
+++ b/src/core/features/course/services/handlers/course-tag-area.ts
@@ -0,0 +1,85 @@
+// (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 { Injectable, Type } from '@angular/core';
+
+import { CoreDomUtils } from '@services/utils/dom';
+import { CoreTagAreaHandler } from '@features/tag/services/tag-area-delegate';
+import { CoreCourseTagAreaComponent } from '../../components/tag-area/tag-area';
+import { makeSingleton } from '@singletons';
+
+/**
+ * Handler to support tags.
+ */
+@Injectable({ providedIn: 'root' })
+export class CoreCourseTagAreaHandlerService implements CoreTagAreaHandler {
+
+ name = 'CoreCourseTagAreaHandler';
+ type = 'core/course';
+
+ /**
+ * Whether or not the handler is enabled on a site level.
+ *
+ * @return Whether or not the handler is enabled on a site level.
+ */
+ async isEnabled(): Promise