Merge pull request #2941 from crazyserver/MOBILE-3833
MOBILE-3833 mod: Create a base module to remove duplicated getData funcmain
commit
5edd98bc63
|
@ -52,7 +52,7 @@ export class AddonBadgesIssuedBadgePage implements OnInit {
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId') || this.courseId; // Use 0 for site badges.
|
this.courseId = CoreNavigator.getRouteNumberParam('courseId') || this.courseId; // Use 0 for site badges.
|
||||||
this.userId = CoreNavigator.getRouteNumberParam('userId') || CoreSites.getCurrentSite()!.getUserId();
|
this.userId = CoreNavigator.getRouteNumberParam('userId') || CoreSites.getRequiredCurrentSite().getUserId();
|
||||||
this.badgeHash = CoreNavigator.getRouteParam('badgeHash') || '';
|
this.badgeHash = CoreNavigator.getRouteParam('badgeHash') || '';
|
||||||
|
|
||||||
this.fetchIssuedBadge().finally(() => {
|
this.fetchIssuedBadge().finally(() => {
|
||||||
|
|
|
@ -69,12 +69,12 @@ export class AddonBlockTimelineComponent extends CoreBlockBaseComponent implemen
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.currentSite = CoreSites.getCurrentSite();
|
this.currentSite = CoreSites.getRequiredCurrentSite();
|
||||||
|
|
||||||
this.filter = await this.currentSite!.getLocalSiteConfig('AddonBlockTimelineFilter', this.filter);
|
this.filter = await this.currentSite.getLocalSiteConfig('AddonBlockTimelineFilter', this.filter);
|
||||||
this.switchFilter(this.filter);
|
this.switchFilter(this.filter);
|
||||||
|
|
||||||
this.sort = await this.currentSite!.getLocalSiteConfig('AddonBlockTimelineSort', this.sort);
|
this.sort = await this.currentSite.getLocalSiteConfig('AddonBlockTimelineSort', this.sort);
|
||||||
|
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,22 +13,11 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injector, NgModule } from '@angular/core';
|
import { Injector, NgModule } from '@angular/core';
|
||||||
import { Route, RouterModule, ROUTES, Routes } from '@angular/router';
|
import { RouterModule, ROUTES, Routes } from '@angular/router';
|
||||||
|
|
||||||
import { buildTabMainRoutes } from '@features/mainmenu/mainmenu-tab-routing.module';
|
import { buildTabMainRoutes } from '@features/mainmenu/mainmenu-tab-routing.module';
|
||||||
import { AddonCalendarMainMenuHandlerService } from './services/handlers/mainmenu';
|
import { AddonCalendarMainMenuHandlerService } from './services/handlers/mainmenu';
|
||||||
|
|
||||||
export const AddonCalendarEditRoute: Route = {
|
|
||||||
path: 'edit/:eventId',
|
|
||||||
loadChildren: () =>
|
|
||||||
import('@/addons/calendar/pages/edit-event/edit-event.module').then(m => m.AddonCalendarEditEventPageModule),
|
|
||||||
};
|
|
||||||
|
|
||||||
export const AddonCalendarEventRoute: Route ={
|
|
||||||
path: 'event/:id',
|
|
||||||
loadChildren: () => import('@/addons/calendar/pages/event/event.module').then(m => m.AddonCalendarEventPageModule),
|
|
||||||
};
|
|
||||||
|
|
||||||
function buildRoutes(injector: Injector): Routes {
|
function buildRoutes(injector: Injector): Routes {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
@ -48,8 +37,15 @@ function buildRoutes(injector: Injector): Routes {
|
||||||
loadChildren: () =>
|
loadChildren: () =>
|
||||||
import('@/addons/calendar/pages/day/day.module').then(m => m.AddonCalendarDayPageModule),
|
import('@/addons/calendar/pages/day/day.module').then(m => m.AddonCalendarDayPageModule),
|
||||||
},
|
},
|
||||||
AddonCalendarEventRoute,
|
{
|
||||||
AddonCalendarEditRoute,
|
path: 'event/:id',
|
||||||
|
loadChildren: () => import('@/addons/calendar/pages/event/event.module').then(m => m.AddonCalendarEventPageModule),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'edit/:eventId',
|
||||||
|
loadChildren: () =>
|
||||||
|
import('@/addons/calendar/pages/edit-event/edit-event.module').then(m => m.AddonCalendarEditEventPageModule),
|
||||||
|
},
|
||||||
...buildTabMainRoutes(injector, {
|
...buildTabMainRoutes(injector, {
|
||||||
redirectTo: 'index',
|
redirectTo: 'index',
|
||||||
pathMatch: 'full',
|
pathMatch: 'full',
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, OnInit, OnDestroy, ViewChild, ElementRef, Optional } from '@angular/core';
|
import { Component, OnInit, OnDestroy, ViewChild, ElementRef } from '@angular/core';
|
||||||
import { FormControl, FormGroup, FormBuilder, Validators } from '@angular/forms';
|
import { FormControl, FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||||
import { IonRefresher } from '@ionic/angular';
|
import { IonRefresher } from '@ionic/angular';
|
||||||
import { CoreEvents } from '@singletons/events';
|
import { CoreEvents } from '@singletons/events';
|
||||||
|
@ -23,7 +23,6 @@ import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreTimeUtils } from '@services/utils/time';
|
import { CoreTimeUtils } from '@services/utils/time';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { CoreCategoryData, CoreCourses, CoreCourseSearchedData, CoreEnrolledCourseData } from '@features/courses/services/courses';
|
import { CoreCategoryData, CoreCourses, CoreCourseSearchedData, CoreEnrolledCourseData } from '@features/courses/services/courses';
|
||||||
import { CoreSplitViewComponent } from '@components/split-view/split-view';
|
|
||||||
import { CoreEditorRichTextEditorComponent } from '@features/editor/components/rich-text-editor/rich-text-editor';
|
import { CoreEditorRichTextEditorComponent } from '@features/editor/components/rich-text-editor/rich-text-editor';
|
||||||
import {
|
import {
|
||||||
AddonCalendarProvider,
|
AddonCalendarProvider,
|
||||||
|
@ -94,9 +93,8 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected fb: FormBuilder,
|
protected fb: FormBuilder,
|
||||||
@Optional() protected svComponent: CoreSplitViewComponent,
|
|
||||||
) {
|
) {
|
||||||
this.currentSite = CoreSites.getCurrentSite()!;
|
this.currentSite = CoreSites.getRequiredCurrentSite();
|
||||||
this.errors = {
|
this.errors = {
|
||||||
required: Translate.instant('core.required'),
|
required: Translate.instant('core.required'),
|
||||||
};
|
};
|
||||||
|
@ -572,15 +570,8 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.svComponent?.outletActivated) {
|
this.originalData = undefined; // Avoid asking for confirmation.
|
||||||
// Empty form.
|
CoreNavigator.back();
|
||||||
this.hasOffline = false;
|
|
||||||
this.form.reset(this.originalData);
|
|
||||||
this.originalData = CoreUtils.clone(this.form.value);
|
|
||||||
} else {
|
|
||||||
this.originalData = undefined; // Avoid asking for confirmation.
|
|
||||||
CoreNavigator.back();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,26 +15,23 @@
|
||||||
[contextInstanceId]="event.contextInstanceId"></core-format-text>
|
[contextInstanceId]="event.contextInstanceId"></core-format-text>
|
||||||
</h1>
|
</h1>
|
||||||
<ion-buttons slot="end">
|
<ion-buttons slot="end">
|
||||||
<!-- The context menu will be added in here. -->
|
<core-context-menu>
|
||||||
|
<core-context-menu-item [hidden]="!eventLoaded || (!hasOffline && event && !event.deleted) || !isOnline"
|
||||||
|
[priority]="400" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event, true)"
|
||||||
|
[iconAction]="syncIcon" [closeOnClick]="false">
|
||||||
|
</core-context-menu-item>
|
||||||
|
<core-context-menu-item [hidden]="!canEdit || !event || !event.canedit || event.deleted" [priority]="300"
|
||||||
|
[content]="'core.edit' | translate" (action)="openEdit()" iconAction="fas-edit">
|
||||||
|
</core-context-menu-item>
|
||||||
|
<core-context-menu-item [hidden]="!event || !event.candelete || event.deleted" [priority]="200"
|
||||||
|
[content]="'core.delete' | translate" (action)="deleteEvent()"
|
||||||
|
iconAction="fas-trash"></core-context-menu-item>
|
||||||
|
<core-context-menu-item [hidden]="!event || !event.deleted" [priority]="200" [content]="'core.restore' | translate"
|
||||||
|
(action)="undoDelete()" iconAction="fas-undo-alt"></core-context-menu-item>
|
||||||
|
</core-context-menu>
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
<core-navbar-buttons slot="end">
|
|
||||||
<core-context-menu>
|
|
||||||
<core-context-menu-item [hidden]="isSplitViewOn || !eventLoaded || (!hasOffline && event && !event.deleted) || !isOnline"
|
|
||||||
[priority]="400" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event, true)"
|
|
||||||
[iconAction]="syncIcon" [closeOnClick]="false">
|
|
||||||
</core-context-menu-item>
|
|
||||||
<core-context-menu-item [hidden]="!canEdit || !event || !event.canedit || event.deleted" [priority]="300"
|
|
||||||
[content]="'core.edit' | translate" (action)="openEdit()" iconAction="fas-edit">
|
|
||||||
</core-context-menu-item>
|
|
||||||
<core-context-menu-item [hidden]="!event || !event.candelete || event.deleted" [priority]="200"
|
|
||||||
[content]="'core.delete' | translate" (action)="deleteEvent()"
|
|
||||||
iconAction="fas-trash"></core-context-menu-item>
|
|
||||||
<core-context-menu-item [hidden]="!event || !event.deleted" [priority]="200" [content]="'core.restore' | translate"
|
|
||||||
(action)="undoDelete()" iconAction="fas-undo-alt"></core-context-menu-item>
|
|
||||||
</core-context-menu>
|
|
||||||
</core-navbar-buttons>
|
|
||||||
<ion-content>
|
<ion-content>
|
||||||
<ion-refresher slot="fixed" [disabled]="!eventLoaded" (ionRefresh)="doRefresh($event.target)">
|
<ion-refresher slot="fixed" [disabled]="!eventLoaded" (ionRefresh)="doRefresh($event.target)">
|
||||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||||
|
@ -50,33 +47,13 @@
|
||||||
|
|
||||||
<ion-card>
|
<ion-card>
|
||||||
<ion-card-content *ngIf="event">
|
<ion-card-content *ngIf="event">
|
||||||
<ion-item class="ion-text-wrap" *ngIf="isSplitViewOn">
|
|
||||||
<img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" alt="" role="presentation"
|
|
||||||
class="core-module-icon">
|
|
||||||
<ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start" aria-hidden="true">
|
|
||||||
</ion-icon>
|
|
||||||
<ion-label>
|
|
||||||
<span class="sr-only">
|
|
||||||
{{ 'addon.calendar.type' + event.formattedType | translate }}
|
|
||||||
<span class="sr-only" *ngIf="event.moduleIcon && event.iconTitle">{{ event.iconTitle }}</span>
|
|
||||||
</span>
|
|
||||||
<h2>{{ 'addon.calendar.eventname' | translate }}</h2>
|
|
||||||
<p>
|
|
||||||
<core-format-text [text]="event.name" [contextLevel]="event.contextLevel"
|
|
||||||
[contextInstanceId]="event.contextInstanceId"></core-format-text>
|
|
||||||
</p>
|
|
||||||
</ion-label>
|
|
||||||
<ion-note slot="end" *ngIf="event.deleted">
|
|
||||||
<ion-icon name="fas-trash" aria-hidden="true"></ion-icon> {{ 'core.deletedoffline' | translate }}
|
|
||||||
</ion-note>
|
|
||||||
</ion-item>
|
|
||||||
<ion-item>
|
<ion-item>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>{{ 'addon.calendar.when' | translate }}</h2>
|
<h2>{{ 'addon.calendar.when' | translate }}</h2>
|
||||||
<core-format-text [text]="event.formattedtime" [contextLevel]="event.contextLevel"
|
<core-format-text [text]="event.formattedtime" [contextLevel]="event.contextLevel"
|
||||||
[contextInstanceId]="event.contextInstanceId"></core-format-text>
|
[contextInstanceId]="event.contextInstanceId"></core-format-text>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
<ion-note slot="end" *ngIf="!isSplitViewOn && event.deleted">
|
<ion-note slot="end" *ngIf="event.deleted">
|
||||||
<ion-icon name="fas-trash" aria-hidden="true"></ion-icon> {{ 'core.deletedoffline' | translate }}
|
<ion-icon name="fas-trash" aria-hidden="true"></ion-icon> {{ 'core.deletedoffline' | translate }}
|
||||||
</ion-note>
|
</ion-note>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, OnDestroy, OnInit, Optional } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { IonRefresher } from '@ionic/angular';
|
import { IonRefresher } from '@ionic/angular';
|
||||||
import { AlertOptions } from '@ionic/core';
|
import { AlertOptions } from '@ionic/core';
|
||||||
import {
|
import {
|
||||||
|
@ -32,14 +32,12 @@ import { CoreLocalNotifications } from '@services/local-notifications';
|
||||||
import { CoreCourse } from '@features/course/services/course';
|
import { CoreCourse } from '@features/course/services/course';
|
||||||
import { CoreTimeUtils } from '@services/utils/time';
|
import { CoreTimeUtils } from '@services/utils/time';
|
||||||
import { CoreGroups } from '@services/groups';
|
import { CoreGroups } from '@services/groups';
|
||||||
import { CoreSplitViewComponent } from '@components/split-view/split-view';
|
|
||||||
import { Network, NgZone, Translate } from '@singletons';
|
import { Network, NgZone, Translate } from '@singletons';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { CoreNavigator } from '@services/navigator';
|
import { CoreNavigator } from '@services/navigator';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { AddonCalendarReminderDBRecord } from '../../services/database/calendar';
|
import { AddonCalendarReminderDBRecord } from '../../services/database/calendar';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { CoreScreen } from '@services/screen';
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { CoreLang } from '@services/lang';
|
import { CoreLang } from '@services/lang';
|
||||||
|
|
||||||
|
@ -81,18 +79,15 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
|
||||||
hasOffline = false;
|
hasOffline = false;
|
||||||
isOnline = false;
|
isOnline = false;
|
||||||
syncIcon = CoreConstants.ICON_LOADING; // Sync icon.
|
syncIcon = CoreConstants.ICON_LOADING; // Sync icon.
|
||||||
isSplitViewOn = false;
|
|
||||||
monthNames?: string[];
|
monthNames?: string[];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Optional() protected svComponent: CoreSplitViewComponent,
|
|
||||||
protected route: ActivatedRoute,
|
protected route: ActivatedRoute,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
this.notificationsEnabled = CoreLocalNotifications.isAvailable();
|
this.notificationsEnabled = CoreLocalNotifications.isAvailable();
|
||||||
this.siteHomeId = CoreSites.getCurrentSiteHomeId();
|
this.siteHomeId = CoreSites.getCurrentSiteHomeId();
|
||||||
this.currentSiteId = CoreSites.getCurrentSiteId();
|
this.currentSiteId = CoreSites.getCurrentSiteId();
|
||||||
this.isSplitViewOn = this.svComponent?.outletActivated;
|
|
||||||
|
|
||||||
// Check if site supports editing. No need to check allowed types, event.canedit already does it.
|
// Check if site supports editing. No need to check allowed types, event.canedit already does it.
|
||||||
this.canEdit = AddonCalendar.canEditEventsInSite();
|
this.canEdit = AddonCalendar.canEditEventsInSite();
|
||||||
|
@ -147,7 +142,16 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
|
||||||
* View loaded.
|
* View loaded.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.eventId = CoreNavigator.getRouteNumberParam('id')!;
|
try {
|
||||||
|
this.eventId = CoreNavigator.getRequiredRouteNumberParam('id');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.syncIcon = CoreConstants.ICON_LOADING;
|
this.syncIcon = CoreConstants.ICON_LOADING;
|
||||||
|
|
||||||
this.fetchEvent();
|
this.fetchEvent();
|
||||||
|
@ -471,9 +475,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
|
||||||
CoreDomUtils.showToast('addon.calendar.eventcalendareventdeleted', true, 3000);
|
CoreDomUtils.showToast('addon.calendar.eventcalendareventdeleted', true, 3000);
|
||||||
|
|
||||||
// Event deleted, close the view.
|
// Event deleted, close the view.
|
||||||
if (CoreScreen.isMobile) {
|
CoreNavigator.back();
|
||||||
CoreNavigator.back();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Event deleted in offline, just mark it as deleted.
|
// Event deleted in offline, just mark it as deleted.
|
||||||
this.event.deleted = true;
|
this.event.deleted = true;
|
||||||
|
@ -528,9 +530,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
|
||||||
CoreDomUtils.showToast('addon.calendar.eventcalendareventdeleted', true, 3000);
|
CoreDomUtils.showToast('addon.calendar.eventcalendareventdeleted', true, 3000);
|
||||||
|
|
||||||
// Event was deleted, close the view.
|
// Event was deleted, close the view.
|
||||||
if (CoreScreen.isMobile) {
|
CoreNavigator.back();
|
||||||
CoreNavigator.back();
|
|
||||||
}
|
|
||||||
} else if (data.events && (!isManual || data.source != 'event')) {
|
} else if (data.events && (!isManual || data.source != 'event')) {
|
||||||
const event = data.events.find((ev) => ev.id == this.eventId);
|
const event = data.events.find((ev) => ev.id == this.eventId);
|
||||||
|
|
||||||
|
|
|
@ -60,11 +60,19 @@ export class AddonCompetencyCompetencyPage implements OnInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.competencyId = CoreNavigator.getRouteNumberParam('competencyId')!;
|
try {
|
||||||
this.planId = CoreNavigator.getRouteNumberParam('planId');
|
this.competencyId = CoreNavigator.getRequiredRouteNumberParam('competencyId');
|
||||||
if (!this.planId) {
|
this.planId = CoreNavigator.getRouteNumberParam('planId');
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
if (!this.planId) {
|
||||||
this.userId = CoreNavigator.getRouteNumberParam('userId');
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
this.userId = CoreNavigator.getRouteNumberParam('userId');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -40,9 +40,17 @@ export class AddonCompetencyCompetencySummaryPage implements OnInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.competencyId = CoreNavigator.getRouteNumberParam('competencyId')!;
|
try {
|
||||||
this.contextLevel = CoreNavigator.getRouteParam<ContextLevel>('contextLevel');
|
this.competencyId = CoreNavigator.getRequiredRouteNumberParam('competencyId');
|
||||||
this.contextInstanceId = CoreNavigator.getRouteNumberParam('contextInstanceId');
|
this.contextLevel = CoreNavigator.getRouteParam<ContextLevel>('contextLevel');
|
||||||
|
this.contextInstanceId = CoreNavigator.getRouteNumberParam('contextInstanceId');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.fetchCompetency();
|
await this.fetchCompetency();
|
||||||
|
|
|
@ -42,8 +42,16 @@ export class AddonCompetencyCourseCompetenciesPage implements OnInit {
|
||||||
* View loaded.
|
* View loaded.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
try {
|
||||||
this.userId = CoreNavigator.getRouteNumberParam('userId')!;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
this.userId = CoreNavigator.getRequiredRouteNumberParam('userId');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.fetchCourseCompetencies().finally(() => {
|
this.fetchCourseCompetencies().finally(() => {
|
||||||
this.competenciesLoaded = true;
|
this.competenciesLoaded = true;
|
||||||
|
|
|
@ -39,7 +39,15 @@ export class AddonCompetencyPlanPage implements OnInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.planId = CoreNavigator.getRouteNumberParam('planId')!;
|
try {
|
||||||
|
this.planId = CoreNavigator.getRequiredRouteNumberParam('planId');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.fetchLearningPlan().finally(() => {
|
this.fetchLearningPlan().finally(() => {
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
|
|
|
@ -44,11 +44,15 @@ export class AddonCourseCompletionReportPage implements OnInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
try {
|
||||||
this.userId = CoreNavigator.getRouteNumberParam('userId') || CoreSites.getCurrentSiteUserId();
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
this.userId = CoreNavigator.getRouteNumberParam('userId') || CoreSites.getCurrentSiteUserId();
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
if (!this.userId) {
|
CoreNavigator.back();
|
||||||
this.userId = CoreSites.getCurrentSiteUserId();
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.fetchCompletion().finally(() => {
|
this.fetchCompletion().finally(() => {
|
||||||
|
|
|
@ -54,7 +54,7 @@ export class AddonMessagesSendMessageUserHandlerService implements CoreUserProfi
|
||||||
* @return Promise resolved with true if enabled, resolved with false otherwise.
|
* @return Promise resolved with true if enabled, resolved with false otherwise.
|
||||||
*/
|
*/
|
||||||
async isEnabledForUser(user: CoreUserProfile): Promise<boolean> {
|
async isEnabledForUser(user: CoreUserProfile): Promise<boolean> {
|
||||||
const currentSite = CoreSites.getCurrentSite()!;
|
const currentSite = CoreSites.getRequiredCurrentSite();
|
||||||
|
|
||||||
// From 3.7 you can send messages to yourself.
|
// From 3.7 you can send messages to yourself.
|
||||||
return user.id != CoreSites.getCurrentSiteUserId() || currentSite.isVersionGreaterEqualThan('3.7');
|
return user.id != CoreSites.getCurrentSiteUserId() || currentSite.isVersionGreaterEqualThan('3.7');
|
||||||
|
|
|
@ -78,9 +78,17 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy, CanLeave {
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.moduleId = CoreNavigator.getRouteNumberParam('cmId')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.moduleId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.isBlind = !!CoreNavigator.getRouteNumberParam('blindId');
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
this.isBlind = !!CoreNavigator.getRouteNumberParam('blindId');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.fetchAssignment().finally(() => {
|
this.fetchAssignment().finally(() => {
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
|
|
|
@ -120,10 +120,18 @@ export class AddonModAssignSubmissionListPage implements AfterViewInit, OnDestro
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
ngAfterViewInit(): void {
|
ngAfterViewInit(): void {
|
||||||
this.moduleId = CoreNavigator.getRouteNumberParam('cmId')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.moduleId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.groupId = CoreNavigator.getRouteNumberParam('groupId') || 0;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.selectedStatus = CoreNavigator.getRouteParam('status');
|
this.groupId = CoreNavigator.getRouteNumberParam('groupId') || 0;
|
||||||
|
this.selectedStatus = CoreNavigator.getRouteParam('status');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.selectedStatus) {
|
if (this.selectedStatus) {
|
||||||
if (this.selectedStatus == AddonModAssignProvider.NEED_GRADING) {
|
if (this.selectedStatus == AddonModAssignProvider.NEED_GRADING) {
|
||||||
|
|
|
@ -55,10 +55,18 @@ export class AddonModAssignSubmissionReviewPage implements OnInit, CanLeave {
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.route.queryParams.subscribe((params) => {
|
this.route.queryParams.subscribe((params) => {
|
||||||
this.moduleId = CoreNavigator.getRouteNumberParam('cmId')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.moduleId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.submitId = CoreNavigator.getRouteNumberParam('submitId') || 0;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.blindId = CoreNavigator.getRouteNumberParam('blindId', { params });
|
this.submitId = CoreNavigator.getRouteNumberParam('submitId') || 0;
|
||||||
|
this.blindId = CoreNavigator.getRouteNumberParam('blindId', { params });
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.fetchSubmission().finally(() => {
|
this.fetchSubmission().finally(() => {
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
|
|
|
@ -14,23 +14,22 @@
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { AddonModAssignIndexComponent } from '../../components/index';
|
import { AddonModAssignIndexComponent } from '../../components/index';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to support assign modules.
|
* Handler to support assign modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModAssignModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModAssignModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_assign';
|
static readonly PAGE_NAME = 'mod_assign';
|
||||||
|
|
||||||
name = 'AddonModAssign';
|
name = 'AddonModAssign';
|
||||||
modName = 'assign';
|
modName = 'assign';
|
||||||
|
protected pageName = AddonModAssignModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: true,
|
[CoreConstants.FEATURE_GROUPS]: true,
|
||||||
|
@ -48,42 +47,7 @@ export class AddonModAssignModuleHandlerService implements CoreCourseModuleHandl
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the handler is enabled on a site level.
|
* @inheritdoc
|
||||||
*
|
|
||||||
* @return Whether or not the handler is enabled on a site level.
|
|
||||||
*/
|
|
||||||
async isEnabled(): Promise<boolean> {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the data required to display the module in the course contents view.
|
|
||||||
*
|
|
||||||
* @param module The module object.
|
|
||||||
* @return Data to render the module.
|
|
||||||
*/
|
|
||||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_assign-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModAssignModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
|
||||||
* The component returned must implement CoreCourseModuleMainComponent.
|
|
||||||
*
|
|
||||||
* @return The component to use, undefined if not found.
|
|
||||||
*/
|
*/
|
||||||
async getMainComponent(): Promise<Type<unknown> | undefined> {
|
async getMainComponent(): Promise<Type<unknown> | undefined> {
|
||||||
return AddonModAssignIndexComponent;
|
return AddonModAssignIndexComponent;
|
||||||
|
|
|
@ -134,7 +134,7 @@ export class AddonModBookProvider {
|
||||||
|
|
||||||
if (!CoreFile.isAvailable()) {
|
if (!CoreFile.isAvailable()) {
|
||||||
// We return the live URL.
|
// We return the live URL.
|
||||||
return CoreSites.getCurrentSite()!.checkAndFixPluginfileURL(indexUrl);
|
return CoreSites.getRequiredCurrentSite().checkAndFixPluginfileURL(indexUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
const siteId = CoreSites.getCurrentSiteId();
|
const siteId = CoreSites.getCurrentSiteId();
|
||||||
|
|
|
@ -15,23 +15,22 @@
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { AddonModBookIndexComponent } from '../../components/index';
|
import { AddonModBookIndexComponent } from '../../components/index';
|
||||||
import { AddonModBook } from '../book';
|
import { AddonModBook } from '../book';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to support book modules.
|
* Handler to support book modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModBookModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModBookModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_book';
|
static readonly PAGE_NAME = 'mod_book';
|
||||||
|
|
||||||
name = 'AddonModBook';
|
name = 'AddonModBook';
|
||||||
modName = 'book';
|
modName = 'book';
|
||||||
|
protected pageName = AddonModBookModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
|
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
|
||||||
|
@ -46,45 +45,14 @@ export class AddonModBookModuleHandlerService implements CoreCourseModuleHandler
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the handler is enabled on a site level.
|
* @inheritdoc
|
||||||
*
|
|
||||||
* @return Whether or not the handler is enabled on a site level.
|
|
||||||
*/
|
*/
|
||||||
isEnabled(): Promise<boolean> {
|
isEnabled(): Promise<boolean> {
|
||||||
return AddonModBook.isPluginEnabled();
|
return AddonModBook.isPluginEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the data required to display the module in the course contents view.
|
* @inheritdoc
|
||||||
*
|
|
||||||
* @param module The module object.
|
|
||||||
* @param courseId The course ID.
|
|
||||||
* @param sectionId The section ID.
|
|
||||||
* @return Data to render the module.
|
|
||||||
*/
|
|
||||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_book-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModBookModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
|
||||||
* The component returned must implement CoreCourseModuleMainComponent.
|
|
||||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
|
||||||
*
|
|
||||||
* @return The component (or promise resolved with component) to use, undefined if not found.
|
|
||||||
*/
|
*/
|
||||||
async getMainComponent(): Promise<Type<unknown> | undefined> {
|
async getMainComponent(): Promise<Type<unknown> | undefined> {
|
||||||
return AddonModBookIndexComponent;
|
return AddonModBookIndexComponent;
|
||||||
|
|
|
@ -78,12 +78,12 @@ export class AddonModChatChatPage implements OnInit, OnDestroy, CanLeave {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
|
||||||
this.chatId = CoreNavigator.getRouteNumberParam('chatId')!;
|
|
||||||
this.title = CoreNavigator.getRouteParam('title') || '';
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
|
this.chatId = CoreNavigator.getRequiredRouteNumberParam('chatId');
|
||||||
|
this.title = CoreNavigator.getRouteParam('title') || '';
|
||||||
|
|
||||||
await this.loginUser();
|
await this.loginUser();
|
||||||
|
|
||||||
await this.fetchMessages();
|
await this.fetchMessages();
|
||||||
|
|
|
@ -47,12 +47,20 @@ export class AddonModChatSessionMessagesPage implements OnInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
try {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.sessionStart = CoreNavigator.getRouteNumberParam('sessionStart')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.sessionEnd = CoreNavigator.getRouteNumberParam('sessionEnd')!;
|
this.sessionStart = CoreNavigator.getRequiredRouteNumberParam('sessionStart');
|
||||||
this.chatId = CoreNavigator.getRouteNumberParam('chatId')!;
|
this.sessionEnd = CoreNavigator.getRequiredRouteNumberParam('sessionEnd');
|
||||||
this.groupId = CoreNavigator.getRouteNumberParam('groupId') || 0;
|
this.chatId = CoreNavigator.getRequiredRouteNumberParam('chatId');
|
||||||
|
this.groupId = CoreNavigator.getRouteNumberParam('groupId') || 0;
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.currentUserId = CoreSites.getCurrentSiteUserId();
|
this.currentUserId = CoreSites.getCurrentSiteUserId();
|
||||||
|
|
||||||
|
|
|
@ -53,10 +53,18 @@ export class AddonModChatSessionsPage implements AfterViewInit, OnDestroy {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngAfterViewInit(): Promise<void> {
|
async ngAfterViewInit(): Promise<void> {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
try {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.chatId = CoreNavigator.getRouteNumberParam('chatId')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.sessions.setChatId(this.chatId);
|
this.chatId = CoreNavigator.getRequiredRouteNumberParam('chatId');
|
||||||
|
this.sessions.setChatId(this.chatId);
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await this.fetchSessions();
|
await this.fetchSessions();
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,8 @@
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { AddonModChatIndexComponent } from '../../components/index';
|
import { AddonModChatIndexComponent } from '../../components/index';
|
||||||
|
|
||||||
|
@ -25,12 +23,13 @@ import { AddonModChatIndexComponent } from '../../components/index';
|
||||||
* Handler to support chat modules.
|
* Handler to support chat modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModChatModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModChatModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_chat';
|
static readonly PAGE_NAME = 'mod_chat';
|
||||||
|
|
||||||
name = 'AddonModChat';
|
name = 'AddonModChat';
|
||||||
modName = 'chat';
|
modName = 'chat';
|
||||||
|
protected pageName = AddonModChatModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: true,
|
[CoreConstants.FEATURE_GROUPS]: true,
|
||||||
|
@ -43,35 +42,6 @@ export class AddonModChatModuleHandlerService implements CoreCourseModuleHandler
|
||||||
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
async isEnabled(): Promise<boolean> {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
|
||||||
const data: CoreCourseModuleHandlerData = {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_chat-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModChatModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,10 +14,8 @@
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { AddonModChoiceIndexComponent } from '../../components/index';
|
import { AddonModChoiceIndexComponent } from '../../components/index';
|
||||||
|
|
||||||
|
@ -25,12 +23,13 @@ import { AddonModChoiceIndexComponent } from '../../components/index';
|
||||||
* Handler to support choice modules.
|
* Handler to support choice modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModChoiceModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModChoiceModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_choice';
|
static readonly PAGE_NAME = 'mod_choice';
|
||||||
|
|
||||||
name = 'AddonModChoice';
|
name = 'AddonModChoice';
|
||||||
modName = 'choice';
|
modName = 'choice';
|
||||||
|
protected pageName = AddonModChoiceModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: true,
|
[CoreConstants.FEATURE_GROUPS]: true,
|
||||||
|
@ -44,33 +43,6 @@ export class AddonModChoiceModuleHandlerService implements CoreCourseModuleHandl
|
||||||
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
async isEnabled(): Promise<boolean> {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_choice-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModChoiceModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -53,7 +53,7 @@ export class AddonModDataFieldPluginComponent implements OnInit, OnChanges {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try{
|
try {
|
||||||
// Check if the plugin has defined its own component to render itself.
|
// Check if the plugin has defined its own component to render itself.
|
||||||
this.fieldComponent = await AddonModDataFieldsDelegate.getComponentForField(this.field);
|
this.fieldComponent = await AddonModDataFieldsDelegate.getComponentForField(this.field);
|
||||||
|
|
||||||
|
|
|
@ -96,10 +96,18 @@ export class AddonModDataEditPage implements OnInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.module = CoreNavigator.getRouteParam<CoreCourseModule>('module')!;
|
try {
|
||||||
this.entryId = CoreNavigator.getRouteNumberParam('entryId') || undefined;
|
this.module = CoreNavigator.getRequiredRouteParam<CoreCourseModule>('module');
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.entryId = CoreNavigator.getRouteNumberParam('entryId') || undefined;
|
||||||
this.selectedGroup = CoreNavigator.getRouteNumberParam('group') || 0;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
this.selectedGroup = CoreNavigator.getRouteNumberParam('group') || 0;
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If entryId is lower than 0 or null, it is a new entry or an offline entry.
|
// If entryId is lower than 0 or null, it is a new entry or an offline entry.
|
||||||
this.isEditing = typeof this.entryId != 'undefined' && this.entryId > 0;
|
this.isEditing = typeof this.entryId != 'undefined' && this.entryId > 0;
|
||||||
|
|
|
@ -132,11 +132,20 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.module = CoreNavigator.getRouteParam<CoreCourseModule>('module')!;
|
try {
|
||||||
this.entryId = CoreNavigator.getRouteNumberParam('entryId') || undefined;
|
this.module = CoreNavigator.getRequiredRouteParam<CoreCourseModule>('module');
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.entryId = CoreNavigator.getRouteNumberParam('entryId') || undefined;
|
||||||
this.selectedGroup = CoreNavigator.getRouteNumberParam('group') || 0;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.offset = CoreNavigator.getRouteNumberParam('offset');
|
this.selectedGroup = CoreNavigator.getRouteNumberParam('group') || 0;
|
||||||
|
this.offset = CoreNavigator.getRouteNumberParam('offset');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.title = this.module.name;
|
this.title = this.module.name;
|
||||||
|
|
||||||
this.commentsEnabled = !CoreComments.areCommentsDisabledInSite();
|
this.commentsEnabled = !CoreComments.areCommentsDisabledInSite();
|
||||||
|
|
|
@ -225,7 +225,7 @@ export class AddonModDataHelperProvider {
|
||||||
let render = '';
|
let render = '';
|
||||||
if (action == AddonModDataAction.MOREURL) {
|
if (action == AddonModDataAction.MOREURL) {
|
||||||
// Render more url directly because it can be part of an HTML attribute.
|
// Render more url directly because it can be part of an HTML attribute.
|
||||||
render = CoreSites.getCurrentSite()!.getURL() + '/mod/data/view.php?d={{database.id}}&rid=' + entry.id;
|
render = CoreSites.getRequiredCurrentSite().getURL() + '/mod/data/view.php?d={{database.id}}&rid=' + entry.id;
|
||||||
} else if (action == 'approvalstatus') {
|
} else if (action == 'approvalstatus') {
|
||||||
render = Translate.instant('addon.mod_data.' + (entry.approved ? 'approved' : 'notapproved'));
|
render = Translate.instant('addon.mod_data.' + (entry.approved ? 'approved' : 'notapproved'));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -14,10 +14,8 @@
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { AddonModDataIndexComponent } from '../../components/index';
|
import { AddonModDataIndexComponent } from '../../components/index';
|
||||||
|
|
||||||
|
@ -25,12 +23,13 @@ import { AddonModDataIndexComponent } from '../../components/index';
|
||||||
* Handler to support data modules.
|
* Handler to support data modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModDataModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModDataModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_data';
|
static readonly PAGE_NAME = 'mod_data';
|
||||||
|
|
||||||
name = 'AddonModData';
|
name = 'AddonModData';
|
||||||
modName = 'data';
|
modName = 'data';
|
||||||
|
protected pageName = AddonModDataModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: true,
|
[CoreConstants.FEATURE_GROUPS]: true,
|
||||||
|
@ -46,33 +45,6 @@ export class AddonModDataModuleHandlerService implements CoreCourseModuleHandler
|
||||||
[CoreConstants.FEATURE_COMMENT]: true,
|
[CoreConstants.FEATURE_COMMENT]: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
async isEnabled(): Promise<boolean> {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_data-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModDataModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -49,9 +49,17 @@ export class AddonModFeedbackAttemptPage implements OnInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.attemptId = CoreNavigator.getRouteNumberParam('attemptId')!;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
this.attemptId = CoreNavigator.getRequiredRouteNumberParam('attemptId');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.fetchData();
|
this.fetchData();
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
|
||||||
completedOffline = false;
|
completedOffline = false;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.currentSite = CoreSites.getCurrentSite()!;
|
this.currentSite = CoreSites.getRequiredCurrentSite();
|
||||||
|
|
||||||
// Refresh online status when changes.
|
// Refresh online status when changes.
|
||||||
this.onlineObserver = Network.onChange().subscribe(() => {
|
this.onlineObserver = Network.onChange().subscribe(() => {
|
||||||
|
@ -92,12 +92,20 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.currentPage = CoreNavigator.getRouteNumberParam('page');
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.title = CoreNavigator.getRouteParam('title');
|
this.currentPage = CoreNavigator.getRouteNumberParam('page');
|
||||||
this.preview = !!CoreNavigator.getRouteBooleanParam('preview');
|
this.title = CoreNavigator.getRouteParam('title');
|
||||||
this.fromIndex = !!CoreNavigator.getRouteBooleanParam('fromIndex');
|
this.preview = !!CoreNavigator.getRouteBooleanParam('preview');
|
||||||
|
this.fromIndex = !!CoreNavigator.getRouteBooleanParam('fromIndex');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await this.fetchData();
|
await this.fetchData();
|
||||||
|
|
||||||
|
|
|
@ -47,9 +47,17 @@ export class AddonModFeedbackNonRespondentsPage implements OnInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.selectedGroup = CoreNavigator.getRouteNumberParam('group') || 0;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
this.selectedGroup = CoreNavigator.getRouteNumberParam('group') || 0;
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.fetchData();
|
this.fetchData();
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,9 +63,17 @@ export class AddonModFeedbackRespondentsPage implements AfterViewInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngAfterViewInit(): Promise<void> {
|
async ngAfterViewInit(): Promise<void> {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.selectedGroup = CoreNavigator.getRouteNumberParam('group') || 0;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
this.selectedGroup = CoreNavigator.getRouteNumberParam('group') || 0;
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await this.fetchData();
|
await this.fetchData();
|
||||||
|
|
||||||
|
|
|
@ -14,23 +14,22 @@
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { AddonModFeedbackIndexComponent } from '../../components/index';
|
import { AddonModFeedbackIndexComponent } from '../../components/index';
|
||||||
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to support feedback modules.
|
* Handler to support feedback modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModFeedbackModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModFeedbackModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_feedback';
|
static readonly PAGE_NAME = 'mod_feedback';
|
||||||
|
|
||||||
name = 'AddonModFeedback';
|
name = 'AddonModFeedback';
|
||||||
modName = 'feedback';
|
modName = 'feedback';
|
||||||
|
protected pageName = AddonModFeedbackModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: true,
|
[CoreConstants.FEATURE_GROUPS]: true,
|
||||||
|
@ -44,33 +43,6 @@ export class AddonModFeedbackModuleHandlerService implements CoreCourseModuleHan
|
||||||
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
async isEnabled(): Promise<boolean> {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_feedback-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModFeedbackModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,10 +14,8 @@
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { AddonModFolderIndexComponent } from '../../components/index';
|
import { AddonModFolderIndexComponent } from '../../components/index';
|
||||||
|
|
||||||
|
@ -25,12 +23,13 @@ import { AddonModFolderIndexComponent } from '../../components/index';
|
||||||
* Handler to support folder modules.
|
* Handler to support folder modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModFolderModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModFolderModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_folder';
|
static readonly PAGE_NAME = 'mod_folder';
|
||||||
|
|
||||||
name = 'AddonModFolder';
|
name = 'AddonModFolder';
|
||||||
modName = 'folder';
|
modName = 'folder';
|
||||||
|
protected pageName = AddonModFolderModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
|
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
|
||||||
|
@ -44,33 +43,6 @@ export class AddonModFolderModuleHandlerService implements CoreCourseModuleHandl
|
||||||
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
async isEnabled(): Promise<boolean> {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_folder-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModFolderModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -58,7 +58,7 @@ export class AddonModForumPostOptionsMenuComponent implements OnInit, OnDestroy
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.post.id > 0) {
|
if (this.post.id > 0) {
|
||||||
const site = CoreSites.getCurrentSite()!;
|
const site = CoreSites.getRequiredCurrentSite();
|
||||||
this.url = site.createSiteUrl('/mod/forum/discuss.php', { d: this.post.discussionid.toString() }, 'p' + this.post.id);
|
this.url = site.createSiteUrl('/mod/forum/discuss.php', { d: this.post.discussionid.toString() }, 'p' + this.post.id);
|
||||||
this.offlinePost = false;
|
this.offlinePost = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -65,7 +65,7 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
discussionId!: number;
|
discussionId!: number;
|
||||||
forum: Partial<AddonModForumData> = {};
|
forum: Partial<AddonModForumData> = {};
|
||||||
accessInfo: AddonModForumAccessInformation = {};
|
accessInfo: AddonModForumAccessInformation = {};
|
||||||
discussion!: AddonModForumDiscussion;
|
discussion?: AddonModForumDiscussion;
|
||||||
startingPost?: Post;
|
startingPost?: Post;
|
||||||
posts!: Post[];
|
posts!: Post[];
|
||||||
discussionLoaded = false;
|
discussionLoaded = false;
|
||||||
|
@ -100,8 +100,8 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
leavingPage = false;
|
leavingPage = false;
|
||||||
|
|
||||||
protected forumId!: number;
|
protected forumId!: number;
|
||||||
protected postId!: number;
|
protected postId?: number;
|
||||||
protected parent!: number;
|
protected parent?: number;
|
||||||
protected onlineObserver?: Subscription;
|
protected onlineObserver?: Subscription;
|
||||||
protected syncObserver?: CoreEventObserver;
|
protected syncObserver?: CoreEventObserver;
|
||||||
protected syncManualObserver?: CoreEventObserver;
|
protected syncManualObserver?: CoreEventObserver;
|
||||||
|
@ -122,16 +122,25 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
try {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.forumId = CoreNavigator.getRouteNumberParam('forumId')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.discussion = CoreNavigator.getRouteParam<AddonModForumDiscussion>('discussion')!;
|
this.forumId = CoreNavigator.getRequiredRouteNumberParam('forumId');
|
||||||
this.discussionId = this.discussion
|
this.discussion = CoreNavigator.getRouteParam<AddonModForumDiscussion>('discussion');
|
||||||
? this.discussion.discussion
|
this.discussionId = this.discussion
|
||||||
: CoreNavigator.getRouteNumberParam('discussionId')!;
|
? this.discussion.discussion
|
||||||
this.trackPosts = CoreNavigator.getRouteBooleanParam('trackPosts')!;
|
: CoreNavigator.getRequiredRouteNumberParam('discussionId');
|
||||||
this.postId = CoreNavigator.getRouteNumberParam('postId')!;
|
this.trackPosts = CoreNavigator.getRouteBooleanParam('trackPosts') || false;
|
||||||
this.parent = CoreNavigator.getRouteNumberParam('parent')!;
|
this.postId = CoreNavigator.getRouteNumberParam('postId');
|
||||||
|
this.parent = CoreNavigator.getRouteNumberParam('parent');
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
this.goBack();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.isOnline = CoreApp.isOnline();
|
this.isOnline = CoreApp.isOnline();
|
||||||
this.onlineObserver = Network.onChange().subscribe(() => {
|
this.onlineObserver = Network.onChange().subscribe(() => {
|
||||||
|
@ -148,11 +157,9 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
* View loaded.
|
* View loaded.
|
||||||
*/
|
*/
|
||||||
async ngAfterViewInit(): Promise<void> {
|
async ngAfterViewInit(): Promise<void> {
|
||||||
if (this.parent) {
|
this.sort = this.parent
|
||||||
this.sort = 'nested'; // Force nested order.
|
? 'nested' // Force nested order.
|
||||||
} else {
|
: await this.getUserSort();
|
||||||
this.sort = await this.getUserSort();
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.fetchPosts(true, false, true);
|
await this.fetchPosts(true, false, true);
|
||||||
|
|
||||||
|
@ -183,6 +190,16 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
await this.loadDiscussion(this.forumId, this.cmId, this.discussionId);
|
await this.loadDiscussion(this.forumId, this.cmId, this.discussionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.discussion) {
|
||||||
|
CoreDomUtils.showErrorModal('Cannot get the discussion');
|
||||||
|
|
||||||
|
this.goBack();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const discussion = this.discussion;
|
||||||
|
|
||||||
// Refresh data if this discussion is synchronized automatically.
|
// Refresh data if this discussion is synchronized automatically.
|
||||||
this.syncObserver = CoreEvents.on(AddonModForumSyncProvider.AUTO_SYNCED, data => {
|
this.syncObserver = CoreEvents.on(AddonModForumSyncProvider.AUTO_SYNCED, data => {
|
||||||
if (data.forumId == this.forumId && this.discussionId == data.discussionId
|
if (data.forumId == this.forumId && this.discussionId == data.discussionId
|
||||||
|
@ -204,7 +221,7 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
}, CoreSites.getCurrentSiteId());
|
}, CoreSites.getCurrentSiteId());
|
||||||
|
|
||||||
// Invalidate discussion list if it was not read.
|
// Invalidate discussion list if it was not read.
|
||||||
if (this.discussion.numunread > 0) {
|
if (discussion.numunread > 0) {
|
||||||
AddonModForum.invalidateDiscussionsList(this.forumId);
|
AddonModForum.invalidateDiscussionsList(this.forumId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,22 +244,18 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
if ((this.forumId && this.forumId === data.forumId) || data.cmId === this.cmId) {
|
if ((this.forumId && this.forumId === data.forumId) || data.cmId === this.cmId) {
|
||||||
AddonModForum.invalidateDiscussionsList(this.forumId).finally(() => {
|
AddonModForum.invalidateDiscussionsList(this.forumId).finally(() => {
|
||||||
if (typeof data.locked != 'undefined') {
|
if (typeof data.locked != 'undefined') {
|
||||||
this.discussion.locked = data.locked;
|
discussion.locked = data.locked;
|
||||||
}
|
}
|
||||||
if (typeof data.pinned != 'undefined') {
|
if (typeof data.pinned != 'undefined') {
|
||||||
this.discussion.pinned = data.pinned;
|
discussion.pinned = data.pinned;
|
||||||
}
|
}
|
||||||
if (typeof data.starred != 'undefined') {
|
if (typeof data.starred != 'undefined') {
|
||||||
this.discussion.starred = data.starred;
|
discussion.starred = data.starred;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof data.deleted != 'undefined' && data.deleted) {
|
if (typeof data.deleted != 'undefined' && data.deleted) {
|
||||||
if (!data.post?.parentid) {
|
if (!data.post?.parentid) {
|
||||||
if (this.splitView?.outletActivated) {
|
this.goBack();
|
||||||
CoreNavigator.navigate('../');
|
|
||||||
} else {
|
|
||||||
CoreNavigator.back();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.discussionLoaded = false;
|
this.discussionLoaded = false;
|
||||||
this.refreshPosts();
|
this.refreshPosts();
|
||||||
|
@ -272,6 +285,17 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to go back.
|
||||||
|
*/
|
||||||
|
protected goBack(): void {
|
||||||
|
if (this.splitView?.outletActivated) {
|
||||||
|
CoreNavigator.navigate('../');
|
||||||
|
} else {
|
||||||
|
CoreNavigator.back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs when the page is about to leave and no longer be the active page.
|
* Runs when the page is about to leave and no longer be the active page.
|
||||||
*/
|
*/
|
||||||
|
@ -298,7 +322,7 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
*/
|
*/
|
||||||
protected async getUserSort(): Promise<SortType> {
|
protected async getUserSort(): Promise<SortType> {
|
||||||
try {
|
try {
|
||||||
const value = await CoreSites.getCurrentSite()!.getLocalSiteConfig<SortType>('AddonModForumDiscussionSort');
|
const value = await CoreSites.getRequiredCurrentSite().getLocalSiteConfig<SortType>('AddonModForumDiscussionSort');
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -515,7 +539,7 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
this.syncIcon = CoreConstants.ICON_SYNC;
|
this.syncIcon = CoreConstants.ICON_SYNC;
|
||||||
|
|
||||||
if (forceMarkAsRead || (hasUnreadPosts && this.trackPosts)) {
|
if (forceMarkAsRead || (hasUnreadPosts && this.trackPosts)) {
|
||||||
// // Add log in Moodle and mark unread posts as readed.
|
// Add log in Moodle and mark unread posts as readed.
|
||||||
AddonModForum.logDiscussionView(this.discussionId, this.forumId || -1, this.forum.name).catch(() => {
|
AddonModForum.logDiscussionView(this.discussionId, this.forumId || -1, this.forum.name).catch(() => {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
|
@ -543,14 +567,8 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
this.discussion = await AddonModForumHelper.getDiscussionById(forumId, cmId, discussionId);
|
||||||
const discussion = await AddonModForumHelper.getDiscussionById(forumId, cmId, discussionId);
|
this.discussionId = this.discussion.discussion;
|
||||||
|
|
||||||
this.discussion = discussion;
|
|
||||||
this.discussionId = this.discussion.discussion;
|
|
||||||
} catch (error) {
|
|
||||||
// Ignore errors.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -630,7 +648,7 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
* @param showErrors Whether to show errors in a modal.
|
* @param showErrors Whether to show errors in a modal.
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
refreshPosts(sync?: boolean, showErrors?: boolean): Promise<void> {
|
async refreshPosts(sync?: boolean, showErrors?: boolean): Promise<void> {
|
||||||
this.content.scrollToTop();
|
this.content.scrollToTop();
|
||||||
this.refreshIcon = CoreConstants.ICON_LOADING;
|
this.refreshIcon = CoreConstants.ICON_LOADING;
|
||||||
this.syncIcon = CoreConstants.ICON_LOADING;
|
this.syncIcon = CoreConstants.ICON_LOADING;
|
||||||
|
@ -642,9 +660,9 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
AddonModForum.invalidateCanAddDiscussion(this.forumId),
|
AddonModForum.invalidateCanAddDiscussion(this.forumId),
|
||||||
];
|
];
|
||||||
|
|
||||||
return CoreUtils.allPromises(promises).catch(() => {
|
await CoreUtils.ignoreErrors(CoreUtils.allPromises(promises));
|
||||||
// Ignore errors.
|
|
||||||
}).then(() => this.fetchPosts(sync, showErrors));
|
await this.fetchPosts(sync, showErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -656,7 +674,7 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
changeSort(type: SortType): Promise<void> {
|
changeSort(type: SortType): Promise<void> {
|
||||||
this.discussionLoaded = false;
|
this.discussionLoaded = false;
|
||||||
this.sort = type;
|
this.sort = type;
|
||||||
CoreSites.getCurrentSite()!.setLocalSiteConfig('AddonModForumDiscussionSort', this.sort);
|
CoreSites.getRequiredCurrentSite().setLocalSiteConfig('AddonModForumDiscussionSort', this.sort);
|
||||||
this.content.scrollToTop();
|
this.content.scrollToTop();
|
||||||
|
|
||||||
return this.fetchPosts();
|
return this.fetchPosts();
|
||||||
|
@ -668,6 +686,10 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
* @param locked True to lock the discussion, false to unlock.
|
* @param locked True to lock the discussion, false to unlock.
|
||||||
*/
|
*/
|
||||||
async setLockState(locked: boolean): Promise<void> {
|
async setLockState(locked: boolean): Promise<void> {
|
||||||
|
if (!this.discussion) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const modal = await CoreDomUtils.showModalLoading('core.sending', true);
|
const modal = await CoreDomUtils.showModalLoading('core.sending', true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -696,6 +718,10 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
* @param pinned True to pin the discussion, false to unpin it.
|
* @param pinned True to pin the discussion, false to unpin it.
|
||||||
*/
|
*/
|
||||||
async setPinState(pinned: boolean): Promise<void> {
|
async setPinState(pinned: boolean): Promise<void> {
|
||||||
|
if (!this.discussion) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const modal = await CoreDomUtils.showModalLoading('core.sending', true);
|
const modal = await CoreDomUtils.showModalLoading('core.sending', true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -725,6 +751,10 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
* @param starred True to star the discussion, false to unstar it.
|
* @param starred True to star the discussion, false to unstar it.
|
||||||
*/
|
*/
|
||||||
async toggleFavouriteState(starred: boolean): Promise<void> {
|
async toggleFavouriteState(starred: boolean): Promise<void> {
|
||||||
|
if (!this.discussion) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const modal = await CoreDomUtils.showModalLoading('core.sending', true);
|
const modal = await CoreDomUtils.showModalLoading('core.sending', true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -103,10 +103,18 @@ export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy, CanLea
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
try {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.forumId = CoreNavigator.getRouteNumberParam('forumId')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.timeCreated = CoreNavigator.getRouteNumberParam('timeCreated')!;
|
this.forumId = CoreNavigator.getRequiredRouteNumberParam('forumId');
|
||||||
|
this.timeCreated = CoreNavigator.getRequiredRouteNumberParam('timeCreated');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
this.goBack();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.fetchDiscussionData().finally(() => {
|
this.fetchDiscussionData().finally(() => {
|
||||||
this.groupsLoaded = true;
|
this.groupsLoaded = true;
|
||||||
|
@ -595,6 +603,17 @@ export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy, CanLea
|
||||||
delete this.syncObserver;
|
delete this.syncObserver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to go back.
|
||||||
|
*/
|
||||||
|
protected goBack(): void {
|
||||||
|
if (this.splitView?.outletActivated) {
|
||||||
|
CoreNavigator.navigate('../../');
|
||||||
|
} else {
|
||||||
|
CoreNavigator.back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page destroyed.
|
* Page destroyed.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,9 +14,7 @@
|
||||||
|
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { AddonModForum, AddonModForumProvider } from '../forum';
|
import { AddonModForum, AddonModForumProvider } from '../forum';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreCourseAnyModuleData } from '@features/course/services/course';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { makeSingleton, Translate } from '@singletons';
|
import { makeSingleton, Translate } from '@singletons';
|
||||||
import { CoreEvents } from '@singletons/events';
|
import { CoreEvents } from '@singletons/events';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
|
@ -24,17 +22,19 @@ import { CoreUtils } from '@services/utils/utils';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { AddonModForumIndexComponent } from '../../components/index';
|
import { AddonModForumIndexComponent } from '../../components/index';
|
||||||
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to support forum modules.
|
* Handler to support forum modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModForumModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModForumModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_forum';
|
static readonly PAGE_NAME = 'mod_forum';
|
||||||
|
|
||||||
name = 'AddonModForum';
|
name = 'AddonModForum';
|
||||||
modName = 'forum';
|
modName = 'forum';
|
||||||
|
protected pageName = AddonModForumModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: true,
|
[CoreConstants.FEATURE_GROUPS]: true,
|
||||||
|
@ -51,39 +51,10 @@ export class AddonModForumModuleHandlerService implements CoreCourseModuleHandle
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the handler is enabled on a site level.
|
* @inheritdoc
|
||||||
*
|
|
||||||
* @return Whether or not the handler is enabled on a site level.
|
|
||||||
*/
|
|
||||||
isEnabled(): Promise<boolean> {
|
|
||||||
return Promise.resolve(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the data required to display the module in the course contents view.
|
|
||||||
*
|
|
||||||
* @param module The module object.
|
|
||||||
* @param courseId The course ID.
|
|
||||||
* @param sectionId The section ID.
|
|
||||||
* @return Data to render the module.
|
|
||||||
*/
|
*/
|
||||||
getData(module: CoreCourseAnyModuleData, courseId: number): CoreCourseModuleHandlerData {
|
getData(module: CoreCourseAnyModuleData, courseId: number): CoreCourseModuleHandlerData {
|
||||||
const data: CoreCourseModuleHandlerData = {
|
const data = super.getData(module, courseId);
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_forum-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(
|
|
||||||
`${AddonModForumModuleHandlerService.PAGE_NAME}/${courseId}/${module.id}`,
|
|
||||||
options,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if ('afterlink' in module && !!module.afterlink) {
|
if ('afterlink' in module && !!module.afterlink) {
|
||||||
data.extraBadgeColor = '';
|
data.extraBadgeColor = '';
|
||||||
|
@ -111,20 +82,14 @@ export class AddonModForumModuleHandlerService implements CoreCourseModuleHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
* @inheritdoc
|
||||||
* The component returned must implement CoreCourseModuleMainComponent.
|
|
||||||
*
|
|
||||||
* @return The component to use, undefined if not found.
|
|
||||||
*/
|
*/
|
||||||
async getMainComponent(): Promise<Type<unknown> | undefined> {
|
async getMainComponent(): Promise<Type<unknown> | undefined> {
|
||||||
return AddonModForumIndexComponent;
|
return AddonModForumIndexComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to display the course refresher in single activity course format. If it returns false, a refresher must be
|
* @inheritdoc
|
||||||
* included in the template that calls the doRefresh method of the component. Defaults to true.
|
|
||||||
*
|
|
||||||
* @return Whether the refresher should be displayed.
|
|
||||||
*/
|
*/
|
||||||
displayRefresherInSingleActivity(): boolean {
|
displayRefresherInSingleActivity(): boolean {
|
||||||
return false;
|
return false;
|
||||||
|
@ -161,7 +126,7 @@ export class AddonModForumModuleHandlerService implements CoreCourseModuleHandle
|
||||||
{ $a : forum.unreadpostscount },
|
{ $a : forum.unreadpostscount },
|
||||||
)
|
)
|
||||||
: '';
|
: '';
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
data.extraBadgeColor = '';
|
data.extraBadgeColor = '';
|
||||||
data.extraBadge = '';
|
data.extraBadge = '';
|
||||||
|
|
|
@ -73,7 +73,7 @@ export class AddonModGlossaryEditPage implements OnInit, CanLeave {
|
||||||
};
|
};
|
||||||
|
|
||||||
protected timecreated!: number;
|
protected timecreated!: number;
|
||||||
protected concept?: string;
|
protected concept = '';
|
||||||
protected syncId?: string;
|
protected syncId?: string;
|
||||||
protected syncObserver?: CoreEventObserver;
|
protected syncObserver?: CoreEventObserver;
|
||||||
protected isDestroyed = false;
|
protected isDestroyed = false;
|
||||||
|
@ -86,11 +86,19 @@ export class AddonModGlossaryEditPage implements OnInit, CanLeave {
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.timecreated = CoreNavigator.getRouteNumberParam('timecreated')!;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.concept = CoreNavigator.getRouteParam<string>('concept')!;
|
this.timecreated = CoreNavigator.getRequiredRouteNumberParam('timecreated');
|
||||||
this.editorExtraParams.timecreated = this.timecreated;
|
this.concept = CoreNavigator.getRouteParam<string>('concept') || '';
|
||||||
|
this.editorExtraParams.timecreated = this.timecreated;
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
this.goBack();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.fetchData();
|
this.fetchData();
|
||||||
}
|
}
|
||||||
|
@ -116,7 +124,7 @@ export class AddonModGlossaryEditPage implements OnInit, CanLeave {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
CoreDomUtils.showErrorModalDefault(error, 'addon.mod_glossary.errorloadingglossary', true);
|
CoreDomUtils.showErrorModalDefault(error, 'addon.mod_glossary.errorloadingglossary', true);
|
||||||
|
|
||||||
CoreNavigator.back();
|
this.goBack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +134,7 @@ export class AddonModGlossaryEditPage implements OnInit, CanLeave {
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected async loadOfflineData(): Promise<void> {
|
protected async loadOfflineData(): Promise<void> {
|
||||||
const entry = await AddonModGlossaryOffline.getNewEntry(this.glossary!.id, this.concept || '', this.timecreated);
|
const entry = await AddonModGlossaryOffline.getNewEntry(this.glossary!.id, this.concept, this.timecreated);
|
||||||
|
|
||||||
this.entry.concept = entry.concept || '';
|
this.entry.concept = entry.concept || '';
|
||||||
this.entry.definition = entry.definition || '';
|
this.entry.definition = entry.definition || '';
|
||||||
|
@ -367,4 +375,15 @@ export class AddonModGlossaryEditPage implements OnInit, CanLeave {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to go back.
|
||||||
|
*/
|
||||||
|
protected goBack(): void {
|
||||||
|
if (this.splitView?.outletActivated) {
|
||||||
|
CoreNavigator.navigate('../../');
|
||||||
|
} else {
|
||||||
|
CoreNavigator.back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,10 +57,18 @@ export class AddonModGlossaryEntryPage implements OnInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
try {
|
||||||
this.entryId = CoreNavigator.getRouteNumberParam('entryId')!;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.tagsEnabled = CoreTag.areTagsAvailableInSite();
|
this.entryId = CoreNavigator.getRequiredRouteNumberParam('entryId');
|
||||||
this.commentsEnabled = !CoreComments.areCommentsDisabledInSite();
|
this.tagsEnabled = CoreTag.areTagsAvailableInSite();
|
||||||
|
this.commentsEnabled = !CoreComments.areCommentsDisabledInSite();
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.fetchEntry();
|
await this.fetchEntry();
|
||||||
|
|
|
@ -14,10 +14,8 @@
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { AddonModGlossaryIndexComponent } from '../../components/index/index';
|
import { AddonModGlossaryIndexComponent } from '../../components/index/index';
|
||||||
|
|
||||||
|
@ -25,12 +23,13 @@ import { AddonModGlossaryIndexComponent } from '../../components/index/index';
|
||||||
* Handler to support glossary modules.
|
* Handler to support glossary modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModGlossaryModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModGlossaryModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_glossary';
|
static readonly PAGE_NAME = 'mod_glossary';
|
||||||
|
|
||||||
name = 'AddonModGlossary';
|
name = 'AddonModGlossary';
|
||||||
modName = 'glossary';
|
modName = 'glossary';
|
||||||
|
protected pageName = AddonModGlossaryModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: false,
|
[CoreConstants.FEATURE_GROUPS]: false,
|
||||||
|
@ -46,33 +45,6 @@ export class AddonModGlossaryModuleHandlerService implements CoreCourseModuleHan
|
||||||
[CoreConstants.FEATURE_PLAGIARISM]: true,
|
[CoreConstants.FEATURE_PLAGIARISM]: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
async isEnabled(): Promise<boolean> {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_glossary-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action: (event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) => {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModGlossaryModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -96,7 +96,7 @@ export class AddonModH5PActivityIndexComponent extends CoreCourseModuleMainActiv
|
||||||
) {
|
) {
|
||||||
super('AddonModH5PActivityIndexComponent', content, courseContentsPage);
|
super('AddonModH5PActivityIndexComponent', content, courseContentsPage);
|
||||||
|
|
||||||
this.site = CoreSites.getCurrentSite()!;
|
this.site = CoreSites.getRequiredCurrentSite();
|
||||||
this.siteCanDownload = this.site.canDownloadFiles() && !CoreH5P.isOfflineDisabledInSite();
|
this.siteCanDownload = this.site.canDownloadFiles() && !CoreH5P.isOfflineDisabledInSite();
|
||||||
|
|
||||||
// Listen for messages from the iframe.
|
// Listen for messages from the iframe.
|
||||||
|
|
|
@ -50,9 +50,17 @@ export class AddonModH5PActivityAttemptResultsPage implements OnInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
try {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.attemptId = CoreNavigator.getRouteNumberParam('attemptId')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
|
this.attemptId = CoreNavigator.getRequiredRouteNumberParam('attemptId');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.fetchData();
|
await this.fetchData();
|
||||||
|
|
|
@ -51,9 +51,18 @@ export class AddonModH5PActivityUserAttemptsPage implements OnInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
try {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.userId = CoreNavigator.getRouteNumberParam('userId') || CoreSites.getCurrentSiteUserId();
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
|
this.userId = CoreNavigator.getRouteNumberParam('userId') || CoreSites.getCurrentSiteUserId();
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.isCurrentUser = this.userId == CoreSites.getCurrentSiteUserId();
|
this.isCurrentUser = this.userId == CoreSites.getCurrentSiteUserId();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -49,8 +49,16 @@ export class AddonModH5PActivityUsersAttemptsPage implements OnInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
try {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.fetchData();
|
await this.fetchData();
|
||||||
|
|
|
@ -14,10 +14,8 @@
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { AddonModH5PActivityIndexComponent } from '../../components/index';
|
import { AddonModH5PActivityIndexComponent } from '../../components/index';
|
||||||
import { AddonModH5PActivity } from '../h5pactivity';
|
import { AddonModH5PActivity } from '../h5pactivity';
|
||||||
|
@ -26,12 +24,13 @@ import { AddonModH5PActivity } from '../h5pactivity';
|
||||||
* Handler to support H5P activities.
|
* Handler to support H5P activities.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModH5PActivityModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModH5PActivityModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_h5pactivity';
|
static readonly PAGE_NAME = 'mod_h5pactivity';
|
||||||
|
|
||||||
name = 'AddonModH5PActivity';
|
name = 'AddonModH5PActivity';
|
||||||
modName = 'h5pactivity';
|
modName = 'h5pactivity';
|
||||||
|
protected pageName = AddonModH5PActivityModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: true,
|
[CoreConstants.FEATURE_GROUPS]: true,
|
||||||
|
@ -52,27 +51,6 @@ export class AddonModH5PActivityModuleHandlerService implements CoreCourseModule
|
||||||
return AddonModH5PActivity.isPluginEnabled();
|
return AddonModH5PActivity.isPluginEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
|
||||||
|
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_h5pactivity-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModH5PActivityModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,10 +14,8 @@
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { AddonModImscpIndexComponent } from '../../components/index';
|
import { AddonModImscpIndexComponent } from '../../components/index';
|
||||||
import { AddonModImscp } from '../imscp';
|
import { AddonModImscp } from '../imscp';
|
||||||
|
@ -26,12 +24,13 @@ import { AddonModImscp } from '../imscp';
|
||||||
* Handler to support IMSCP modules.
|
* Handler to support IMSCP modules.
|
||||||
*/
|
*/
|
||||||
@Injectable( { providedIn: 'root' })
|
@Injectable( { providedIn: 'root' })
|
||||||
export class AddonModImscpModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModImscpModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_imscp';
|
static readonly PAGE_NAME = 'mod_imscp';
|
||||||
|
|
||||||
name = 'AddonModImscp';
|
name = 'AddonModImscp';
|
||||||
modName = 'imscp';
|
modName = 'imscp';
|
||||||
|
protected pageName = AddonModImscpModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
|
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
|
||||||
|
@ -55,27 +54,7 @@ export class AddonModImscpModuleHandlerService implements CoreCourseModuleHandle
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
async getMainComponent(): Promise<Type<unknown>> {
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_imscp-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModImscpModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
async getMainComponent(): Promise<Type<unknown> | undefined> {
|
|
||||||
return AddonModImscpIndexComponent;
|
return AddonModImscpIndexComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourseWSModule } from '@features/course/services/course';
|
import { CoreCourseWSModule } from '@features/course/services/course';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
|
@ -22,7 +23,7 @@ import { makeSingleton } from '@singletons';
|
||||||
* Handler to support label modules.
|
* Handler to support label modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModLabelModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModLabelModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
name = 'AddonModLabel';
|
name = 'AddonModLabel';
|
||||||
modName = 'label';
|
modName = 'label';
|
||||||
|
@ -40,13 +41,6 @@ export class AddonModLabelModuleHandlerService implements CoreCourseModuleHandle
|
||||||
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
async isEnabled(): Promise<boolean> {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
@ -57,7 +51,7 @@ export class AddonModLabelModuleHandlerService implements CoreCourseModuleHandle
|
||||||
|
|
||||||
return {
|
return {
|
||||||
icon: '',
|
icon: '',
|
||||||
title: title,
|
title,
|
||||||
a11yTitle: '',
|
a11yTitle: '',
|
||||||
class: 'addon-mod-label-handler',
|
class: 'addon-mod-label-handler',
|
||||||
};
|
};
|
||||||
|
|
|
@ -119,12 +119,20 @@ export class AddonModLessonPlayerPage implements OnInit, OnDestroy, CanLeave {
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.password = CoreNavigator.getRouteParam('password');
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.review = !!CoreNavigator.getRouteBooleanParam('review');
|
this.password = CoreNavigator.getRouteParam('password');
|
||||||
this.currentPage = CoreNavigator.getRouteNumberParam('pageId');
|
this.review = !!CoreNavigator.getRouteBooleanParam('review');
|
||||||
this.retakeToReview = CoreNavigator.getRouteNumberParam('retake');
|
this.currentPage = CoreNavigator.getRouteNumberParam('pageId');
|
||||||
|
this.retakeToReview = CoreNavigator.getRouteNumberParam('retake');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Fetch the Lesson data.
|
// Fetch the Lesson data.
|
||||||
|
|
|
@ -64,10 +64,18 @@ export class AddonModLessonUserRetakePage implements OnInit {
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.userId = CoreNavigator.getRouteNumberParam('userId') || CoreSites.getCurrentSiteUserId();
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.retakeNumber = CoreNavigator.getRouteNumberParam('retake');
|
this.userId = CoreNavigator.getRouteNumberParam('userId') || CoreSites.getCurrentSiteUserId();
|
||||||
|
this.retakeNumber = CoreNavigator.getRouteNumberParam('retake');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch the data.
|
// Fetch the data.
|
||||||
this.fetchData().finally(() => {
|
this.fetchData().finally(() => {
|
||||||
|
|
|
@ -15,24 +15,22 @@
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData, CoreCourseWSModule } from '@features/course/services/course';
|
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
|
||||||
import { AddonModLessonIndexComponent } from '../../components/index';
|
import { AddonModLessonIndexComponent } from '../../components/index';
|
||||||
import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to support quiz modules.
|
* Handler to support lesson modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModLessonModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModLessonModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_lesson';
|
static readonly PAGE_NAME = 'mod_lesson';
|
||||||
|
|
||||||
name = 'AddonModLesson';
|
name = 'AddonModLesson';
|
||||||
modName = 'lesson';
|
modName = 'lesson';
|
||||||
|
protected pageName = AddonModLessonModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: true,
|
[CoreConstants.FEATURE_GROUPS]: true,
|
||||||
|
@ -47,55 +45,9 @@ export class AddonModLessonModuleHandlerService implements CoreCourseModuleHandl
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the handler is enabled on a site level.
|
* @inheritdoc
|
||||||
*
|
|
||||||
* @return Promise resolved with boolean: whether or not the handler is enabled on a site level.
|
|
||||||
*/
|
*/
|
||||||
async isEnabled(): Promise<boolean> {
|
async getMainComponent(): Promise<Type<unknown>> {
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the data required to display the module in the course contents view.
|
|
||||||
*
|
|
||||||
* @param module The module object.
|
|
||||||
* @param courseId The course ID.
|
|
||||||
* @param sectionId The section ID.
|
|
||||||
* @param forCoursePage Whether the data will be used to render the course page.
|
|
||||||
* @return Data to render the module.
|
|
||||||
*/
|
|
||||||
getData(
|
|
||||||
module: CoreCourseAnyModuleData,
|
|
||||||
courseId: number, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
||||||
sectionId: number, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
||||||
forCoursePage?: boolean, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
||||||
): CoreCourseModuleHandlerData {
|
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_lesson-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action: (event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) => {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModLessonModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
|
||||||
* The component returned must implement CoreCourseModuleMainComponent.
|
|
||||||
*
|
|
||||||
* @param course The course object.
|
|
||||||
* @param module The module object.
|
|
||||||
* @return The component to use, undefined if not found.
|
|
||||||
*/
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
async getMainComponent(course: CoreCourseAnyCourseData, module: CoreCourseWSModule): Promise<Type<unknown> | undefined> {
|
|
||||||
return AddonModLessonIndexComponent;
|
return AddonModLessonIndexComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,28 +16,29 @@ import { Injectable, Type } from '@angular/core';
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreCourseAnyModuleData } from '@features/course/services/course';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
import { CoreCourseModule } from '@features/course/services/course-helper';
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreApp } from '@services/app';
|
||||||
import { CoreFilepool } from '@services/filepool';
|
import { CoreFilepool } from '@services/filepool';
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { DomSanitizer, makeSingleton } from '@singletons';
|
import { DomSanitizer, makeSingleton } from '@singletons';
|
||||||
import { AddonModLtiHelper } from '../lti-helper';
|
import { AddonModLtiHelper } from '../lti-helper';
|
||||||
import { AddonModLti, AddonModLtiProvider } from '../lti';
|
import { AddonModLti, AddonModLtiProvider } from '../lti';
|
||||||
import { AddonModLtiIndexComponent } from '../../components/index';
|
import { AddonModLtiIndexComponent } from '../../components/index';
|
||||||
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to support LTI modules.
|
* Handler to support LTI modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModLtiModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModLtiModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_lti';
|
static readonly PAGE_NAME = 'mod_lti';
|
||||||
|
|
||||||
name = 'AddonModLti';
|
name = 'AddonModLti';
|
||||||
modName = 'lti';
|
modName = 'lti';
|
||||||
|
protected pageName = AddonModLtiModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: false,
|
[CoreConstants.FEATURE_GROUPS]: false,
|
||||||
|
@ -50,42 +51,26 @@ export class AddonModLtiModuleHandlerService implements CoreCourseModuleHandler
|
||||||
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
async isEnabled(): Promise<boolean> {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
getData(
|
getData(
|
||||||
module: CoreCourseAnyModuleData,
|
module: CoreCourseAnyModuleData,
|
||||||
courseId: number,
|
courseId: number,
|
||||||
|
sectionId?: number,
|
||||||
|
forCoursePage?: boolean,
|
||||||
): CoreCourseModuleHandlerData {
|
): CoreCourseModuleHandlerData {
|
||||||
|
const data = super.getData(module, courseId, sectionId, forCoursePage);
|
||||||
|
data.showDownloadButton = false;
|
||||||
|
|
||||||
const data: CoreCourseModuleHandlerData = {
|
data.buttons = [{
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
icon: 'fas-external-link-alt',
|
||||||
title: module.name,
|
label: 'addon.mod_lti.launchactivity',
|
||||||
class: 'addon-mod_lti-handler',
|
action: (event: Event, module: CoreCourseModule, courseId: number): void => {
|
||||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
|
// Launch the LTI.
|
||||||
options = options || {};
|
AddonModLtiHelper.getDataAndLaunch(courseId, module);
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModLtiModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
},
|
||||||
buttons: [{
|
}];
|
||||||
icon: 'fas-external-link-alt',
|
|
||||||
label: 'addon.mod_lti.launchactivity',
|
|
||||||
action: (event: Event, module: CoreCourseModule, courseId: number): void => {
|
|
||||||
// Launch the LTI.
|
|
||||||
AddonModLtiHelper.getDataAndLaunch(courseId, module);
|
|
||||||
},
|
|
||||||
}],
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handle custom icons.
|
// Handle custom icons.
|
||||||
CoreUtils.ignoreErrors(this.loadCustomIcon(module, courseId, data));
|
CoreUtils.ignoreErrors(this.loadCustomIcon(module, courseId, data));
|
||||||
|
@ -133,7 +118,7 @@ export class AddonModLtiModuleHandlerService implements CoreCourseModuleHandler
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async getMainComponent(): Promise<Type<unknown> | undefined> {
|
async getMainComponent(): Promise<Type<unknown>> {
|
||||||
return AddonModLtiIndexComponent;
|
return AddonModLtiIndexComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,24 +14,23 @@
|
||||||
|
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { AddonModPage } from '../page';
|
import { AddonModPage } from '../page';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { AddonModPageIndexComponent } from '../../components/index';
|
import { AddonModPageIndexComponent } from '../../components/index';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to support page modules.
|
* Handler to support page modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModPageModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModPageModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_page';
|
static readonly PAGE_NAME = 'mod_page';
|
||||||
|
|
||||||
name = 'AddonModPage';
|
name = 'AddonModPage';
|
||||||
modName = 'page';
|
modName = 'page';
|
||||||
|
protected pageName = AddonModPageModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
|
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
|
||||||
|
@ -46,46 +45,16 @@ export class AddonModPageModuleHandlerService implements CoreCourseModuleHandler
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the handler is enabled on a site level.
|
* @inheritdoc
|
||||||
*
|
|
||||||
* @return Whether or not the handler is enabled on a site level.
|
|
||||||
*/
|
*/
|
||||||
isEnabled(): Promise<boolean> {
|
isEnabled(): Promise<boolean> {
|
||||||
return AddonModPage.isPluginEnabled();
|
return AddonModPage.isPluginEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the data required to display the module in the course contents view.
|
* @inheritdoc
|
||||||
*
|
|
||||||
* @param module The module object.
|
|
||||||
* @return Data to render the module.
|
|
||||||
*/
|
*/
|
||||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
async getMainComponent(): Promise<Type<unknown>> {
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_page-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModPageModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
|
||||||
* The component returned must implement CoreCourseModuleMainComponent.
|
|
||||||
*
|
|
||||||
* @param course The course object.
|
|
||||||
* @param module The module object.
|
|
||||||
* @return The component to use, undefined if not found.
|
|
||||||
*/
|
|
||||||
async getMainComponent(): Promise<Type<unknown> | undefined> {
|
|
||||||
return AddonModPageIndexComponent;
|
return AddonModPageIndexComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,9 +52,17 @@ export class AddonModQuizAttemptPage implements OnInit {
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.attemptId = CoreNavigator.getRouteNumberParam('attemptId')!;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
this.attemptId = CoreNavigator.getRequiredRouteNumberParam('attemptId');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.fetchQuizData().finally(() => {
|
this.fetchQuizData().finally(() => {
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
|
|
|
@ -106,9 +106,17 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave {
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.moduleUrl = CoreNavigator.getRouteParam('moduleUrl');
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
this.moduleUrl = CoreNavigator.getRouteParam('moduleUrl');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Create the auto save instance.
|
// Create the auto save instance.
|
||||||
this.autoSave = new AddonModQuizAutoSave(
|
this.autoSave = new AddonModQuizAutoSave(
|
||||||
|
|
|
@ -83,11 +83,19 @@ export class AddonModQuizReviewPage implements OnInit {
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.attemptId = CoreNavigator.getRouteNumberParam('attemptId')!;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.currentPage = CoreNavigator.getRouteNumberParam('page') || -1;
|
this.attemptId = CoreNavigator.getRequiredRouteNumberParam('attemptId');
|
||||||
this.showAll = this.currentPage == -1;
|
this.currentPage = CoreNavigator.getRouteNumberParam('page') || -1;
|
||||||
|
this.showAll = this.currentPage == -1;
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.fetchData();
|
await this.fetchData();
|
||||||
|
|
|
@ -15,23 +15,22 @@
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { AddonModQuizIndexComponent } from '../../components/index';
|
import { AddonModQuizIndexComponent } from '../../components/index';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to support quiz modules.
|
* Handler to support quiz modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModQuizModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModQuizModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_quiz';
|
static readonly PAGE_NAME = 'mod_quiz';
|
||||||
|
|
||||||
name = 'AddonModQuiz';
|
name = 'AddonModQuiz';
|
||||||
modName = 'quiz';
|
modName = 'quiz';
|
||||||
|
protected pageName = AddonModQuizModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: true,
|
[CoreConstants.FEATURE_GROUPS]: true,
|
||||||
|
@ -48,46 +47,7 @@ export class AddonModQuizModuleHandlerService implements CoreCourseModuleHandler
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the handler is enabled on a site level.
|
* @inheritdoc
|
||||||
*
|
|
||||||
* @return Whether or not the handler is enabled on a site level.
|
|
||||||
*/
|
|
||||||
async isEnabled(): Promise<boolean> {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the data required to display the module in the course contents view.
|
|
||||||
*
|
|
||||||
* @param module The module object.
|
|
||||||
* @param courseId The course ID.
|
|
||||||
* @param sectionId The section ID.
|
|
||||||
* @return Data to render the module.
|
|
||||||
*/
|
|
||||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_quiz-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action: (event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) => {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModQuizModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
|
||||||
* The component returned must implement CoreCourseModuleMainComponent.
|
|
||||||
*
|
|
||||||
* @param course The course object.
|
|
||||||
* @param module The module object.
|
|
||||||
* @return The component to use, undefined if not found.
|
|
||||||
*/
|
*/
|
||||||
async getMainComponent(): Promise<Type<unknown>> {
|
async getMainComponent(): Promise<Type<unknown>> {
|
||||||
return AddonModQuizIndexComponent;
|
return AddonModQuizIndexComponent;
|
||||||
|
|
|
@ -14,12 +14,12 @@
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData, CoreCourseModuleContentFile } from '@features/course/services/course';
|
import { CoreCourse, CoreCourseAnyModuleData, CoreCourseModuleContentFile } from '@features/course/services/course';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
import { CoreCourseModule } from '@features/course/services/course-helper';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate';
|
import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate';
|
||||||
import { CoreFileHelper } from '@services/file-helper';
|
import { CoreFileHelper } from '@services/file-helper';
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { CoreMimetypeUtils } from '@services/utils/mimetype';
|
import { CoreMimetypeUtils } from '@services/utils/mimetype';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreTimeUtils } from '@services/utils/time';
|
import { CoreTimeUtils } from '@services/utils/time';
|
||||||
|
@ -33,12 +33,13 @@ import { AddonModResourceHelper } from '../resource-helper';
|
||||||
* Handler to support resource modules.
|
* Handler to support resource modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModResourceModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_resource';
|
static readonly PAGE_NAME = 'mod_resource';
|
||||||
|
|
||||||
name = 'AddonModResource';
|
name = 'AddonModResource';
|
||||||
modName = 'resource';
|
modName = 'resource';
|
||||||
|
protected pageName = AddonModResourceModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
|
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
|
||||||
|
@ -60,46 +61,37 @@ export class AddonModResourceModuleHandlerService implements CoreCourseModuleHan
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the data required to display the module in the course contents view.
|
* @inheritdoc
|
||||||
*
|
|
||||||
* @param module The module object.
|
|
||||||
* @param courseId The course ID.
|
|
||||||
* @param sectionId The section ID.
|
|
||||||
* @return Data to render the module.
|
|
||||||
*/
|
*/
|
||||||
getData(module: CoreCourseAnyModuleData, courseId: number): CoreCourseModuleHandlerData {
|
getData(
|
||||||
|
module: CoreCourseAnyModuleData,
|
||||||
|
courseId: number,
|
||||||
|
sectionId?: number,
|
||||||
|
forCoursePage?: boolean,
|
||||||
|
): CoreCourseModuleHandlerData {
|
||||||
const updateStatus = (status: string): void => {
|
const updateStatus = (status: string): void => {
|
||||||
handlerData.buttons![0].hidden = status !== CoreConstants.DOWNLOADED ||
|
if (!handlerData.buttons) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlerData.buttons[0].hidden = status !== CoreConstants.DOWNLOADED ||
|
||||||
AddonModResourceHelper.isDisplayedInIframe(module);
|
AddonModResourceHelper.isDisplayedInIframe(module);
|
||||||
};
|
};
|
||||||
const openWithPicker = CoreFileHelper.defaultIsOpenWithPicker();
|
const openWithPicker = CoreFileHelper.defaultIsOpenWithPicker();
|
||||||
|
|
||||||
const handlerData: CoreCourseModuleHandlerData = {
|
const handlerData = super.getData(module, courseId, sectionId, forCoursePage);
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
handlerData.updateStatus = updateStatus.bind(this);
|
||||||
title: module.name,
|
handlerData.buttons = [{
|
||||||
class: 'addon-mod_resource-handler',
|
hidden: true,
|
||||||
showDownloadButton: true,
|
icon: openWithPicker ? 'fas-share-square' : 'fas-file',
|
||||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
|
label: module.name + ': ' + Translate.instant(openWithPicker ? 'core.openwith' : 'addon.mod_resource.openthefile'),
|
||||||
options = options || {};
|
action: async (event: Event, module: CoreCourseModule, courseId: number): Promise<void> => {
|
||||||
options.params = options.params || {};
|
const hide = await this.hideOpenButton(module, courseId);
|
||||||
Object.assign(options.params, { module });
|
if (!hide) {
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
AddonModResourceHelper.openModuleFile(module, courseId);
|
||||||
|
}
|
||||||
CoreNavigator.navigateToSitePath(AddonModResourceModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
},
|
||||||
updateStatus: updateStatus.bind(this),
|
}];
|
||||||
buttons: [{
|
|
||||||
hidden: true,
|
|
||||||
icon: openWithPicker ? 'fas-share-square' : 'fas-file',
|
|
||||||
label: module.name + ': ' + Translate.instant(openWithPicker ? 'core.openwith' : 'addon.mod_resource.openthefile'),
|
|
||||||
action: async (event: Event, module: CoreCourseModule, courseId: number): Promise<void> => {
|
|
||||||
const hide = await this.hideOpenButton(module, courseId);
|
|
||||||
if (!hide) {
|
|
||||||
AddonModResourceHelper.openModuleFile(module, courseId);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}],
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getResourceData(module, courseId, handlerData).then((data) => {
|
this.getResourceData(module, courseId, handlerData).then((data) => {
|
||||||
handlerData.icon = data.icon;
|
handlerData.icon = data.icon;
|
||||||
|
@ -149,7 +141,11 @@ export class AddonModResourceModuleHandlerService implements CoreCourseModuleHan
|
||||||
|
|
||||||
// Check if the button needs to be shown or not.
|
// Check if the button needs to be shown or not.
|
||||||
promises.push(this.hideOpenButton(module, courseId).then((hideOpenButton) => {
|
promises.push(this.hideOpenButton(module, courseId).then((hideOpenButton) => {
|
||||||
handlerData.buttons![0].hidden = hideOpenButton;
|
if (!handlerData.buttons) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlerData.buttons[0].hidden = hideOpenButton;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}));
|
}));
|
||||||
|
@ -237,7 +233,7 @@ export class AddonModResourceModuleHandlerService implements CoreCourseModuleHan
|
||||||
|
|
||||||
// No previously set, just set the icon.
|
// No previously set, just set the icon.
|
||||||
if (resourceData.icon == '') {
|
if (resourceData.icon == '') {
|
||||||
resourceData.icon = CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined);
|
resourceData.icon = CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
return resourceData;
|
return resourceData;
|
||||||
|
@ -246,7 +242,7 @@ export class AddonModResourceModuleHandlerService implements CoreCourseModuleHan
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async getMainComponent(): Promise<Type<unknown> | undefined> {
|
async getMainComponent(): Promise<Type<unknown>> {
|
||||||
return AddonModResourceIndexComponent;
|
return AddonModResourceIndexComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ export class AddonModResourceHelperProvider {
|
||||||
// Error getting directory, there was an error downloading or we're in browser. Return online URL.
|
// Error getting directory, there was an error downloading or we're in browser. Return online URL.
|
||||||
if (CoreApp.isOnline() && mainFile.fileurl) {
|
if (CoreApp.isOnline() && mainFile.fileurl) {
|
||||||
// This URL is going to be injected in an iframe, we need this to make it work.
|
// This URL is going to be injected in an iframe, we need this to make it work.
|
||||||
return CoreSites.getCurrentSite()!.checkAndFixPluginfileURL(mainFile.fileurl);
|
return CoreSites.getRequiredCurrentSite().checkAndFixPluginfileURL(mainFile.fileurl);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw e;
|
throw e;
|
||||||
|
|
|
@ -88,14 +88,22 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.cmId = CoreNavigator.getRouteNumberParam('cmId')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.mode = CoreNavigator.getRouteParam('mode') || AddonModScormProvider.MODENORMAL;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.moduleUrl = CoreNavigator.getRouteParam('moduleUrl') || '';
|
this.mode = CoreNavigator.getRouteParam('mode') || AddonModScormProvider.MODENORMAL;
|
||||||
this.newAttempt = !!CoreNavigator.getRouteBooleanParam('newAttempt');
|
this.moduleUrl = CoreNavigator.getRouteParam('moduleUrl') || '';
|
||||||
this.organizationId = CoreNavigator.getRouteParam('organizationId');
|
this.newAttempt = !!CoreNavigator.getRouteBooleanParam('newAttempt');
|
||||||
this.initialScoId = CoreNavigator.getRouteNumberParam('scoId');
|
this.organizationId = CoreNavigator.getRouteParam('organizationId');
|
||||||
this.siteId = CoreSites.getCurrentSiteId();
|
this.initialScoId = CoreNavigator.getRouteNumberParam('scoId');
|
||||||
|
this.siteId = CoreSites.getCurrentSiteId();
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Fetch the SCORM data.
|
// Fetch the SCORM data.
|
||||||
|
|
|
@ -14,10 +14,8 @@
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { AddonModScormIndexComponent } from '../../components/index';
|
import { AddonModScormIndexComponent } from '../../components/index';
|
||||||
|
|
||||||
|
@ -25,12 +23,13 @@ import { AddonModScormIndexComponent } from '../../components/index';
|
||||||
* Handler to support SCORM modules.
|
* Handler to support SCORM modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModScormModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModScormModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_scorm';
|
static readonly PAGE_NAME = 'mod_scorm';
|
||||||
|
|
||||||
name = 'AddonModScorm';
|
name = 'AddonModScorm';
|
||||||
modName = 'scorm';
|
modName = 'scorm';
|
||||||
|
protected pageName = AddonModScormModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: true,
|
[CoreConstants.FEATURE_GROUPS]: true,
|
||||||
|
@ -44,33 +43,6 @@ export class AddonModScormModuleHandlerService implements CoreCourseModuleHandle
|
||||||
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
async isEnabled(): Promise<boolean> {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_scorm-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModScormModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -730,7 +730,7 @@ export class AddonModScormOfflineProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
const scoUserData = scoData?.userdata || {};
|
const scoUserData = scoData?.userdata || {};
|
||||||
const db = CoreSites.getCurrentSite()!.getDb();
|
const db = CoreSites.getRequiredCurrentSite().getDb();
|
||||||
let lessonStatusInserted = false;
|
let lessonStatusInserted = false;
|
||||||
|
|
||||||
if (forceCompleted) {
|
if (forceCompleted) {
|
||||||
|
|
|
@ -14,10 +14,8 @@
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { AddonModSurveyIndexComponent } from '../../components/index';
|
import { AddonModSurveyIndexComponent } from '../../components/index';
|
||||||
|
|
||||||
|
@ -25,12 +23,13 @@ import { AddonModSurveyIndexComponent } from '../../components/index';
|
||||||
* Handler to support survey modules.
|
* Handler to support survey modules.
|
||||||
*/
|
*/
|
||||||
@Injectable( { providedIn: 'root' })
|
@Injectable( { providedIn: 'root' })
|
||||||
export class AddonModSurveyModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModSurveyModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_survey';
|
static readonly PAGE_NAME = 'mod_survey';
|
||||||
|
|
||||||
name = 'AddonModSurvey';
|
name = 'AddonModSurvey';
|
||||||
modName = 'survey';
|
modName = 'survey';
|
||||||
|
protected pageName = AddonModSurveyModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: true,
|
[CoreConstants.FEATURE_GROUPS]: true,
|
||||||
|
@ -44,35 +43,6 @@ export class AddonModSurveyModuleHandlerService implements CoreCourseModuleHandl
|
||||||
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
async isEnabled(): Promise<boolean> {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
getData(
|
|
||||||
module: CoreCourseAnyModuleData,
|
|
||||||
): CoreCourseModuleHandlerData {
|
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_survey-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action: (event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) => {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModSurveyModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper';
|
import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper';
|
||||||
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
import { CoreCourseModule } from '@features/course/services/course-helper';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
||||||
|
@ -30,12 +31,13 @@ import { AddonModUrlHelper } from '../url-helper';
|
||||||
* Handler to support url modules.
|
* Handler to support url modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_url';
|
static readonly PAGE_NAME = 'mod_url';
|
||||||
|
|
||||||
name = 'AddonModUrl';
|
name = 'AddonModUrl';
|
||||||
modName = 'url';
|
modName = 'url';
|
||||||
|
protected pageName = AddonModUrlModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
|
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
|
||||||
|
@ -49,13 +51,6 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
|
||||||
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
async isEnabled(): Promise<boolean> {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
@ -82,7 +77,7 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlerData: CoreCourseModuleHandlerData = {
|
const handlerData: CoreCourseModuleHandlerData = {
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
icon: CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined),
|
||||||
title: module.name,
|
title: module.name,
|
||||||
class: 'addon-mod_url-handler',
|
class: 'addon-mod_url-handler',
|
||||||
showDownloadButton: false,
|
showDownloadButton: false,
|
||||||
|
@ -117,12 +112,16 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
|
||||||
};
|
};
|
||||||
|
|
||||||
this.hideLinkButton(module, courseId).then((hideButton) => {
|
this.hideLinkButton(module, courseId).then((hideButton) => {
|
||||||
handlerData.buttons![0]!.hidden = hideButton;
|
if (!handlerData.buttons) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlerData.buttons[0].hidden = hideButton;
|
||||||
|
|
||||||
if (module.contents && module.contents[0]) {
|
if (module.contents && module.contents[0]) {
|
||||||
// Calculate the icon to use.
|
// Calculate the icon to use.
|
||||||
handlerData.icon = AddonModUrl.guessIcon(module.contents[0].fileurl) ||
|
handlerData.icon = AddonModUrl.guessIcon(module.contents[0].fileurl) ||
|
||||||
CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined);
|
CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -154,7 +153,7 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async getMainComponent(): Promise<Type<unknown> | undefined> {
|
async getMainComponent(): Promise<Type<unknown>> {
|
||||||
return AddonModUrlIndexComponent;
|
return AddonModUrlIndexComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +164,7 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
|
||||||
* @param courseId Course ID.
|
* @param courseId Course ID.
|
||||||
* @return Promise resolved with boolean.
|
* @return Promise resolved with boolean.
|
||||||
*/
|
*/
|
||||||
protected async shouldOpenLink(module: CoreCourseModule, courseId: number): Promise<boolean> {
|
protected async shouldOpenLink(module: CoreCourseModule, courseId?: number): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
const contents = await CoreCourse.getModuleContents(module, courseId, undefined, false, false, undefined, this.modName);
|
const contents = await CoreCourse.getModuleContents(module, courseId, undefined, false, false, undefined, this.modName);
|
||||||
|
|
||||||
|
@ -177,7 +176,7 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// Not handled by the app, check the display type.
|
// Not handled by the app, check the display type.
|
||||||
const url = await CoreUtils.ignoreErrors(AddonModUrl.getUrl(courseId, module.id));
|
const url = courseId ? await CoreUtils.ignoreErrors(AddonModUrl.getUrl(courseId, module.id)) : undefined;
|
||||||
const displayType = AddonModUrl.getFinalDisplayType(url);
|
const displayType = AddonModUrl.getFinalDisplayType(url);
|
||||||
|
|
||||||
return displayType == CoreConstants.RESOURCELIB_DISPLAY_OPEN ||
|
return displayType == CoreConstants.RESOURCELIB_DISPLAY_OPEN ||
|
||||||
|
@ -192,7 +191,7 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
manualCompletionAlwaysShown(module: CoreCourseModule): Promise<boolean> {
|
manualCompletionAlwaysShown(module: CoreCourseModule): Promise<boolean> {
|
||||||
return this.shouldOpenLink(module, module.course!);
|
return this.shouldOpenLink(module, module.course);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -664,7 +664,7 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp
|
||||||
content = content.trim();
|
content = content.trim();
|
||||||
|
|
||||||
if (content.length > 0) {
|
if (content.length > 0) {
|
||||||
const editUrl = CoreTextUtils.concatenatePaths(CoreSites.getCurrentSite()!.getURL(), '/mod/wiki/edit.php');
|
const editUrl = CoreTextUtils.concatenatePaths(CoreSites.getRequiredCurrentSite().getURL(), '/mod/wiki/edit.php');
|
||||||
content = content.replace(/href="edit\.php/g, 'href="' + editUrl);
|
content = content.replace(/href="edit\.php/g, 'href="' + editUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,8 @@
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { AddonModWikiIndexComponent } from '../../components/index';
|
import { AddonModWikiIndexComponent } from '../../components/index';
|
||||||
|
|
||||||
|
@ -25,12 +23,13 @@ import { AddonModWikiIndexComponent } from '../../components/index';
|
||||||
* Handler to support wiki modules.
|
* Handler to support wiki modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModWikiModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModWikiModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_wiki';
|
static readonly PAGE_NAME = 'mod_wiki';
|
||||||
|
|
||||||
name = 'AddonModWiki';
|
name = 'AddonModWiki';
|
||||||
modName = 'wiki';
|
modName = 'wiki';
|
||||||
|
protected pageName = AddonModWikiModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: true,
|
[CoreConstants.FEATURE_GROUPS]: true,
|
||||||
|
@ -45,33 +44,6 @@ export class AddonModWikiModuleHandlerService implements CoreCourseModuleHandler
|
||||||
[CoreConstants.FEATURE_COMMENT]: true,
|
[CoreConstants.FEATURE_COMMENT]: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
async isEnabled(): Promise<boolean> {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_wiki-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action: (event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) => {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = `/${courseId}/${module.id}/page/root`;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModWikiModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -22,6 +22,10 @@ import { CanLeaveGuard } from '@guards/can-leave';
|
||||||
import { AddonModWikiEditPage } from './pages/edit/edit';
|
import { AddonModWikiEditPage } from './pages/edit/edit';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: ':courseId/:cmId',
|
||||||
|
redirectTo: ':courseId/:cmId/page/root',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: ':courseId/:cmId/page/:hash',
|
path: ':courseId/:cmId/page/:hash',
|
||||||
component: AddonModWikiIndexPage,
|
component: AddonModWikiIndexPage,
|
||||||
|
|
|
@ -117,10 +117,18 @@ export class AddonModWorkshopAssessmentPage implements OnInit, OnDestroy, CanLea
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.assessment = CoreNavigator.getRouteParam<AddonModWorkshopSubmissionAssessmentWithFormData>('assessment')!;
|
try {
|
||||||
this.submission = CoreNavigator.getRouteParam<AddonModWorkshopSubmissionData>('submission')!;
|
this.assessment = CoreNavigator.getRequiredRouteParam<AddonModWorkshopSubmissionAssessmentWithFormData>('assessment');
|
||||||
this.profile = CoreNavigator.getRouteParam<CoreUserProfile>('profile')!;
|
this.submission = CoreNavigator.getRequiredRouteParam<AddonModWorkshopSubmissionData>('submission');
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.profile = CoreNavigator.getRequiredRouteParam<CoreUserProfile>('profile');
|
||||||
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.assessmentId = this.assessment.id;
|
this.assessmentId = this.assessment.id;
|
||||||
this.workshopId = this.submission.workshopid;
|
this.workshopId = this.submission.workshopid;
|
||||||
|
|
|
@ -99,10 +99,18 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy, Ca
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.module = CoreNavigator.getRouteParam<CoreCourseModule>('module')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.module = CoreNavigator.getRequiredRouteParam<CoreCourseModule>('module');
|
||||||
this.access = CoreNavigator.getRouteParam<AddonModWorkshopGetWorkshopAccessInformationWSResponse>('access')!;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.submissionId = CoreNavigator.getRouteNumberParam('submissionId') || 0;
|
this.access = CoreNavigator.getRequiredRouteParam<AddonModWorkshopGetWorkshopAccessInformationWSResponse>('access');
|
||||||
|
this.submissionId = CoreNavigator.getRouteNumberParam('submissionId') || 0;
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.submissionId > 0) {
|
if (this.submissionId > 0) {
|
||||||
this.editorExtraParams.id = this.submissionId;
|
this.editorExtraParams.id = this.submissionId;
|
||||||
|
|
|
@ -130,15 +130,22 @@ export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy, CanLea
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
|
try {
|
||||||
|
this.submissionId = CoreNavigator.getRequiredRouteNumberParam('submissionId');
|
||||||
|
this.module = CoreNavigator.getRequiredRouteParam<CoreCourseModule>('module');
|
||||||
|
this.workshop = CoreNavigator.getRequiredRouteParam<AddonModWorkshopData>('workshop');
|
||||||
|
this.access = CoreNavigator.getRequiredRouteParam<AddonModWorkshopGetWorkshopAccessInformationWSResponse>('access');
|
||||||
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
this.profile = CoreNavigator.getRouteParam<CoreUserProfile>('profile');
|
||||||
|
this.submissionInfo = CoreNavigator.getRequiredRouteParam<AddonModWorkshopSubmissionDataWithOfflineData>('submission');
|
||||||
|
this.assessment = CoreNavigator.getRouteParam<AddonModWorkshopSubmissionAssessmentWithFormData>('assessment');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
this.submissionId = CoreNavigator.getRouteNumberParam('submissionId')!;
|
CoreNavigator.back();
|
||||||
this.module = CoreNavigator.getRouteParam<CoreCourseModule>('module')!;
|
|
||||||
this.workshop = CoreNavigator.getRouteParam<AddonModWorkshopData>('workshop')!;
|
return;
|
||||||
this.access = CoreNavigator.getRouteParam<AddonModWorkshopGetWorkshopAccessInformationWSResponse>('access')!;
|
}
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
|
||||||
this.profile = CoreNavigator.getRouteParam<CoreUserProfile>('profile');
|
|
||||||
this.submissionInfo = CoreNavigator.getRouteParam<AddonModWorkshopSubmissionDataWithOfflineData>('submission')!;
|
|
||||||
this.assessment = CoreNavigator.getRouteParam<AddonModWorkshopSubmissionAssessmentWithFormData>('assessment');
|
|
||||||
|
|
||||||
this.title = this.module.name;
|
this.title = this.module.name;
|
||||||
this.workshopId = this.module.instance || this.workshop.id;
|
this.workshopId = this.module.instance || this.workshop.id;
|
||||||
|
|
|
@ -14,10 +14,8 @@
|
||||||
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { AddonModWorkshopIndexComponent } from '../../components/index';
|
import { AddonModWorkshopIndexComponent } from '../../components/index';
|
||||||
|
|
||||||
|
@ -25,12 +23,13 @@ import { AddonModWorkshopIndexComponent } from '../../components/index';
|
||||||
* Handler to support workshop modules.
|
* Handler to support workshop modules.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModWorkshopModuleHandlerService implements CoreCourseModuleHandler {
|
export class AddonModWorkshopModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_workshop';
|
static readonly PAGE_NAME = 'mod_workshop';
|
||||||
|
|
||||||
name = 'AddonModWorkshop';
|
name = 'AddonModWorkshop';
|
||||||
modName = 'workshop';
|
modName = 'workshop';
|
||||||
|
protected pageName = AddonModWorkshopModuleHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: true,
|
[CoreConstants.FEATURE_GROUPS]: true,
|
||||||
|
@ -46,30 +45,6 @@ export class AddonModWorkshopModuleHandlerService implements CoreCourseModuleHan
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async isEnabled(): Promise<boolean> {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
|
||||||
return {
|
|
||||||
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
|
||||||
title: module.name,
|
|
||||||
class: 'addon-mod_workshop-handler',
|
|
||||||
showDownloadButton: true,
|
|
||||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
|
|
||||||
options = options || {};
|
|
||||||
options.params = options.params || {};
|
|
||||||
Object.assign(options.params, { module });
|
|
||||||
const routeParams = '/' + courseId + '/' + module.id;
|
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(AddonModWorkshopModuleHandlerService.PAGE_NAME + routeParams, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async getMainComponent(): Promise<Type<unknown>> {
|
async getMainComponent(): Promise<Type<unknown>> {
|
||||||
return AddonModWorkshopIndexComponent;
|
return AddonModWorkshopIndexComponent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ export class AddonNotesListPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@ViewChild(IonContent) content?: IonContent;
|
@ViewChild(IonContent) content?: IonContent;
|
||||||
|
|
||||||
courseId: number;
|
courseId!: number;
|
||||||
userId?: number;
|
userId?: number;
|
||||||
type: AddonNotesPublishState = 'course';
|
type: AddonNotesPublishState = 'course';
|
||||||
refreshIcon = CoreConstants.ICON_LOADING;
|
refreshIcon = CoreConstants.ICON_LOADING;
|
||||||
|
@ -51,13 +51,21 @@ export class AddonNotesListPage implements OnInit, OnDestroy {
|
||||||
user?: CoreUserProfile;
|
user?: CoreUserProfile;
|
||||||
showDelete = false;
|
showDelete = false;
|
||||||
canDeleteNotes = false;
|
canDeleteNotes = false;
|
||||||
currentUserId: number;
|
currentUserId!: number;
|
||||||
|
|
||||||
protected syncObserver: CoreEventObserver;
|
protected syncObserver!: CoreEventObserver;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
try {
|
||||||
this.userId = CoreNavigator.getRouteNumberParam('userId');
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
this.userId = CoreNavigator.getRouteNumberParam('userId');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Refresh data if notes are synchronized automatically.
|
// Refresh data if notes are synchronized automatically.
|
||||||
this.syncObserver = CoreEvents.on(AddonNotesSyncProvider.AUTO_SYNCED, (data) => {
|
this.syncObserver = CoreEvents.on(AddonNotesSyncProvider.AUTO_SYNCED, (data) => {
|
||||||
|
|
|
@ -69,19 +69,27 @@ export class AddonPrivateFilesIndexPage implements OnInit, OnDestroy {
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.root = CoreNavigator.getRouteParam('root');
|
try {
|
||||||
const contextId = CoreNavigator.getRouteNumberParam('contextid');
|
this.root = CoreNavigator.getRouteParam('root');
|
||||||
|
const contextId = CoreNavigator.getRouteNumberParam('contextid');
|
||||||
|
|
||||||
if (contextId) {
|
if (contextId) {
|
||||||
// Loading a certain folder.
|
// Loading a certain folder.
|
||||||
this.path = {
|
this.path = {
|
||||||
contextid: contextId,
|
contextid: contextId,
|
||||||
component: CoreNavigator.getRouteParam<string>('component')!,
|
component: CoreNavigator.getRequiredRouteParam<string>('component'),
|
||||||
filearea: CoreNavigator.getRouteParam<string>('filearea')!,
|
filearea: CoreNavigator.getRequiredRouteParam<string>('filearea'),
|
||||||
itemid: CoreNavigator.getRouteNumberParam('itemid')!,
|
itemid: CoreNavigator.getRequiredRouteNumberParam('itemid'),
|
||||||
filepath: CoreNavigator.getRouteParam<string>('filepath')!,
|
filepath: CoreNavigator.getRequiredRouteParam<string>('filepath'),
|
||||||
filename: CoreNavigator.getRouteParam<string>('filename')!,
|
filename: CoreNavigator.getRequiredRouteParam<string>('filename'),
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.title = this.path?.filename || Translate.instant('addon.privatefiles.files');
|
this.title = this.path?.filename || Translate.instant('addon.privatefiles.files');
|
||||||
|
|
|
@ -42,7 +42,15 @@ export class AddonStorageManagerCourseStoragePage implements OnInit {
|
||||||
* View loaded.
|
* View loaded.
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.course = CoreNavigator.getRouteParam<CoreEnrolledCourseData>('course')!;
|
try {
|
||||||
|
this.course = CoreNavigator.getRequiredRouteParam<CoreEnrolledCourseData>('course');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.sections = await CoreCourse.getSections(this.course.id, false, true);
|
this.sections = await CoreCourse.getSections(this.course.id, false, true);
|
||||||
CoreCourseHelper.addHandlerDataForModules(this.sections, this.course.id);
|
CoreCourseHelper.addHandlerDataForModules(this.sections, this.course.id);
|
||||||
|
|
|
@ -66,14 +66,8 @@ export class CoreSplitViewComponent implements AfterViewInit, OnDestroy {
|
||||||
this.disableScrollOnParent();
|
this.disableScrollOnParent();
|
||||||
|
|
||||||
this.subscriptions = [
|
this.subscriptions = [
|
||||||
this.contentOutlet.activateEvents.subscribe(() => {
|
this.contentOutlet.activateEvents.subscribe(() => this.updateOutletRoute()),
|
||||||
this.updateClasses();
|
this.contentOutlet.deactivateEvents.subscribe(() => this.updateOutletRoute()),
|
||||||
this.outletRouteSubject.next(this.contentOutlet.activatedRoute.snapshot);
|
|
||||||
}),
|
|
||||||
this.contentOutlet.deactivateEvents.subscribe(() => {
|
|
||||||
this.updateClasses();
|
|
||||||
this.outletRouteSubject.next(null);
|
|
||||||
}),
|
|
||||||
CoreScreen.layoutObservable.subscribe(() => this.updateClasses()),
|
CoreScreen.layoutObservable.subscribe(() => this.updateClasses()),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -89,6 +83,17 @@ export class CoreSplitViewComponent implements AfterViewInit, OnDestroy {
|
||||||
this.enableScrollOnParent();
|
this.enableScrollOnParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update outlet status.
|
||||||
|
*/
|
||||||
|
private updateOutletRoute(): void {
|
||||||
|
const outletRoute = this.contentOutlet.isActivated ? this.contentOutlet.activatedRoute.snapshot : null;
|
||||||
|
|
||||||
|
this.updateClasses();
|
||||||
|
|
||||||
|
this.outletRouteSubject.next(outletRoute);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update host classes.
|
* Update host classes.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -110,19 +110,28 @@ export class CoreCommentsViewerPage implements OnInit, OnDestroy {
|
||||||
* View loaded.
|
* View loaded.
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
|
try {
|
||||||
|
this.contextLevel = CoreNavigator.getRequiredRouteParam<ContextLevel>('contextLevel');
|
||||||
|
this.instanceId = CoreNavigator.getRequiredRouteNumberParam('instanceId');
|
||||||
|
this.componentName = CoreNavigator.getRequiredRouteParam<string>('componentName');
|
||||||
|
this.itemId = CoreNavigator.getRequiredRouteNumberParam('itemId');
|
||||||
|
this.area = CoreNavigator.getRouteParam('area') || '';
|
||||||
|
this.title = CoreNavigator.getRouteNumberParam('title') ||
|
||||||
|
Translate.instant('core.comments.comments');
|
||||||
|
this.courseId = CoreNavigator.getRouteNumberParam('courseId');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Is implicit the user can delete if he can add.
|
// Is implicit the user can delete if he can add.
|
||||||
this.addDeleteCommentsAvailable = await CoreComments.isAddCommentsAvailable();
|
this.addDeleteCommentsAvailable = await CoreComments.isAddCommentsAvailable();
|
||||||
this.currentUserId = CoreSites.getCurrentSiteUserId();
|
this.currentUserId = CoreSites.getCurrentSiteUserId();
|
||||||
|
|
||||||
this.commentsLoaded = false;
|
this.commentsLoaded = false;
|
||||||
this.contextLevel = CoreNavigator.getRouteParam<ContextLevel>('contextLevel')!;
|
|
||||||
this.instanceId = CoreNavigator.getRouteNumberParam('instanceId')!;
|
|
||||||
this.componentName = CoreNavigator.getRouteParam<string>('componentName')!;
|
|
||||||
this.itemId = CoreNavigator.getRouteNumberParam('itemId')!;
|
|
||||||
this.area = CoreNavigator.getRouteParam('area') || '';
|
|
||||||
this.title = CoreNavigator.getRouteNumberParam('title') ||
|
|
||||||
Translate.instant('core.comments.comments');
|
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId');
|
|
||||||
|
|
||||||
await this.fetchComments(true);
|
await this.fetchComments(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { CoreNavigator } from '@services/navigator';
|
import { CoreNavigator } from '@services/navigator';
|
||||||
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreCourseAnyModuleData } from '../services/course';
|
import { CoreCourseAnyModuleData } from '../services/course';
|
||||||
import { CoreCourseModuleMainResourceComponent } from './main-resource-component';
|
import { CoreCourseModuleMainResourceComponent } from './main-resource-component';
|
||||||
|
|
||||||
/**
|
|
||||||
/**
|
/**
|
||||||
* Template class to easily create CoreCourseModuleMainComponent of resources (or activities without syncing).
|
* Template class to easily create CoreCourseModuleMainComponent of resources (or activities without syncing).
|
||||||
*/
|
*/
|
||||||
|
@ -36,8 +36,17 @@ export class CoreCourseModuleMainActivityPage<ActivityType extends CoreCourseMod
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.module = CoreNavigator.getRouteParam<CoreCourseAnyModuleData>('module')!;
|
try {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
this.module = CoreNavigator.getRequiredRouteParam<CoreCourseAnyModuleData>('module');
|
||||||
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.title = this.module?.name;
|
this.title = this.module?.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
// (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 { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
||||||
|
import { CoreCourse, CoreCourseAnyModuleData } from '../services/course';
|
||||||
|
import { CoreCourseModule } from '../services/course-helper';
|
||||||
|
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '../services/module-delegate';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base module handler to be registered.
|
||||||
|
*/
|
||||||
|
export class CoreModuleHandlerBase implements Partial<CoreCourseModuleHandler> {
|
||||||
|
|
||||||
|
protected pageName = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async isEnabled(): Promise<boolean> {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
getData(
|
||||||
|
module: CoreCourseAnyModuleData,
|
||||||
|
courseId: number, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
|
sectionId?: number, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
|
forCoursePage?: boolean, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
|
): CoreCourseModuleHandlerData {
|
||||||
|
return {
|
||||||
|
icon: CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined),
|
||||||
|
title: module.name,
|
||||||
|
class: 'addon-mod_' + module.modname + '-handler',
|
||||||
|
showDownloadButton: true,
|
||||||
|
action: (event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void => {
|
||||||
|
options = options || {};
|
||||||
|
options.params = options.params || {};
|
||||||
|
Object.assign(options.params, { module });
|
||||||
|
const routeParams = '/' + courseId + '/' + module.id;
|
||||||
|
|
||||||
|
CoreNavigator.navigateToSitePath(this.pageName + routeParams, options);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -78,17 +78,17 @@ export type CoreCourseModulePrefetchInfo = {
|
||||||
/**
|
/**
|
||||||
* Downloaded size.
|
* Downloaded size.
|
||||||
*/
|
*/
|
||||||
size?: number;
|
size: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downloadable size in a readable format.
|
* Downloadable size in a readable format.
|
||||||
*/
|
*/
|
||||||
sizeReadable?: string;
|
sizeReadable: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Module status.
|
* Module status.
|
||||||
*/
|
*/
|
||||||
status?: string;
|
status: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Icon's name of the module status.
|
* Icon's name of the module status.
|
||||||
|
@ -98,12 +98,12 @@ export type CoreCourseModulePrefetchInfo = {
|
||||||
/**
|
/**
|
||||||
* Time when the module was last downloaded.
|
* Time when the module was last downloaded.
|
||||||
*/
|
*/
|
||||||
downloadTime?: number;
|
downloadTime: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download time in a readable format.
|
* Download time in a readable format.
|
||||||
*/
|
*/
|
||||||
downloadTimeReadable?: string;
|
downloadTimeReadable: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -539,18 +539,14 @@ export class CoreCourseHelperProvider {
|
||||||
total: true,
|
total: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!section && !sections) {
|
|
||||||
throw new CoreError('Either section or list of sections needs to be supplied.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the size of the download.
|
// Calculate the size of the download.
|
||||||
if (section && section.id != CoreCourseProvider.ALL_SECTIONS_ID) {
|
if (section && section.id != CoreCourseProvider.ALL_SECTIONS_ID) {
|
||||||
sizeSum = await CoreCourseModulePrefetchDelegate.getDownloadSize(section.modules, courseId);
|
sizeSum = await CoreCourseModulePrefetchDelegate.getDownloadSize(section.modules, courseId);
|
||||||
|
|
||||||
// Check if the section has embedded files in the description.
|
// Check if the section has embedded files in the description.
|
||||||
hasEmbeddedFiles = CoreFilepool.extractDownloadableFilesFromHtml(section.summary).length > 0;
|
hasEmbeddedFiles = CoreFilepool.extractDownloadableFilesFromHtml(section.summary).length > 0;
|
||||||
} else {
|
} else if (sections) {
|
||||||
await Promise.all(sections!.map(async (section) => {
|
await Promise.all(sections.map(async (section) => {
|
||||||
if (section.id == CoreCourseProvider.ALL_SECTIONS_ID) {
|
if (section.id == CoreCourseProvider.ALL_SECTIONS_ID) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -565,6 +561,8 @@ export class CoreCourseHelperProvider {
|
||||||
hasEmbeddedFiles = true;
|
hasEmbeddedFiles = true;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
} else {
|
||||||
|
throw new CoreError('Either section or list of sections needs to be supplied.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasEmbeddedFiles) {
|
if (hasEmbeddedFiles) {
|
||||||
|
@ -1057,7 +1055,7 @@ export class CoreCourseHelperProvider {
|
||||||
|
|
||||||
const moduleInfo = await this.getModulePrefetchInfo(module, courseId, invalidateCache, component);
|
const moduleInfo = await this.getModulePrefetchInfo(module, courseId, invalidateCache, component);
|
||||||
|
|
||||||
instance.size = moduleInfo.size && moduleInfo.size > 0 ? moduleInfo.sizeReadable! : '';
|
instance.size = moduleInfo.sizeReadable;
|
||||||
instance.prefetchStatusIcon = moduleInfo.statusIcon;
|
instance.prefetchStatusIcon = moduleInfo.statusIcon;
|
||||||
instance.prefetchStatus = moduleInfo.status;
|
instance.prefetchStatus = moduleInfo.status;
|
||||||
|
|
||||||
|
@ -1443,7 +1441,7 @@ export class CoreCourseHelperProvider {
|
||||||
invalidateCache?: boolean,
|
invalidateCache?: boolean,
|
||||||
component?: string,
|
component?: string,
|
||||||
): Promise<CoreCourseModulePrefetchInfo> {
|
): Promise<CoreCourseModulePrefetchInfo> {
|
||||||
const moduleInfo: CoreCourseModulePrefetchInfo = {};
|
|
||||||
const siteId = CoreSites.getCurrentSiteId();
|
const siteId = CoreSites.getCurrentSiteId();
|
||||||
|
|
||||||
if (invalidateCache) {
|
if (invalidateCache) {
|
||||||
|
@ -1459,45 +1457,59 @@ export class CoreCourseHelperProvider {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Treat stored size.
|
// Treat stored size.
|
||||||
moduleInfo.size = results[0];
|
const size = results[0];
|
||||||
moduleInfo.sizeReadable = CoreTextUtils.bytesToSize(results[0], 2);
|
const sizeReadable = CoreTextUtils.bytesToSize(results[0], 2);
|
||||||
|
|
||||||
// Treat module status.
|
// Treat module status.
|
||||||
moduleInfo.status = results[1];
|
const status = results[1];
|
||||||
|
let statusIcon: string | undefined;
|
||||||
switch (results[1]) {
|
switch (results[1]) {
|
||||||
case CoreConstants.NOT_DOWNLOADED:
|
case CoreConstants.NOT_DOWNLOADED:
|
||||||
moduleInfo.statusIcon = CoreConstants.ICON_NOT_DOWNLOADED;
|
statusIcon = CoreConstants.ICON_NOT_DOWNLOADED;
|
||||||
break;
|
break;
|
||||||
case CoreConstants.DOWNLOADING:
|
case CoreConstants.DOWNLOADING:
|
||||||
moduleInfo.statusIcon = CoreConstants.ICON_DOWNLOADING;
|
statusIcon = CoreConstants.ICON_DOWNLOADING;
|
||||||
break;
|
break;
|
||||||
case CoreConstants.OUTDATED:
|
case CoreConstants.OUTDATED:
|
||||||
moduleInfo.statusIcon = CoreConstants.ICON_OUTDATED;
|
statusIcon = CoreConstants.ICON_OUTDATED;
|
||||||
break;
|
break;
|
||||||
case CoreConstants.DOWNLOADED:
|
case CoreConstants.DOWNLOADED:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
moduleInfo.statusIcon = '';
|
statusIcon = '';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Treat download time.
|
// Treat download time.
|
||||||
if (!results[2] || !results[2].downloadTime || !CoreFileHelper.isStateDownloaded(results[2].status || '')) {
|
if (!results[2] || !results[2].downloadTime || !CoreFileHelper.isStateDownloaded(results[2].status || '')) {
|
||||||
// Not downloaded.
|
// Not downloaded.
|
||||||
moduleInfo.downloadTime = 0;
|
return {
|
||||||
|
size,
|
||||||
return moduleInfo;
|
sizeReadable,
|
||||||
|
status,
|
||||||
|
statusIcon,
|
||||||
|
downloadTime: 0,
|
||||||
|
downloadTimeReadable: '',
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const now = CoreTimeUtils.timestamp();
|
const now = CoreTimeUtils.timestamp();
|
||||||
moduleInfo.downloadTime = results[2].downloadTime;
|
const downloadTime = results[2].downloadTime;
|
||||||
|
let downloadTimeReadable = '';
|
||||||
if (now - results[2].downloadTime < 7 * 86400) {
|
if (now - results[2].downloadTime < 7 * 86400) {
|
||||||
moduleInfo.downloadTimeReadable = moment(results[2].downloadTime * 1000).fromNow();
|
downloadTimeReadable = moment(results[2].downloadTime * 1000).fromNow();
|
||||||
} else {
|
} else {
|
||||||
moduleInfo.downloadTimeReadable = moment(results[2].downloadTime * 1000).calendar();
|
downloadTimeReadable = moment(results[2].downloadTime * 1000).calendar();
|
||||||
}
|
}
|
||||||
|
|
||||||
return moduleInfo;
|
return {
|
||||||
|
size,
|
||||||
|
sizeReadable,
|
||||||
|
status,
|
||||||
|
statusIcon,
|
||||||
|
downloadTime,
|
||||||
|
downloadTimeReadable,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1616,7 +1628,7 @@ export class CoreCourseHelperProvider {
|
||||||
|
|
||||||
this.logger.warn('navCtrl was not passed to navigateToModule by the link handler for ' + module.modname);
|
this.logger.warn('navCtrl was not passed to navigateToModule by the link handler for ' + module.modname);
|
||||||
|
|
||||||
const params = {
|
const params: Params = {
|
||||||
course: { id: courseId },
|
course: { id: courseId },
|
||||||
module: module,
|
module: module,
|
||||||
sectionId: sectionId,
|
sectionId: sectionId,
|
||||||
|
@ -1690,20 +1702,20 @@ export class CoreCourseHelperProvider {
|
||||||
courseMenuHandlers: CoreCourseOptionsMenuHandlerToDisplay[],
|
courseMenuHandlers: CoreCourseOptionsMenuHandlerToDisplay[],
|
||||||
siteId?: string,
|
siteId?: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
siteId = siteId || CoreSites.getCurrentSiteId();
|
const requiredSiteId = siteId || CoreSites.getRequiredCurrentSite().getId();
|
||||||
|
|
||||||
if (this.courseDwnPromises[siteId] && this.courseDwnPromises[siteId][course.id]) {
|
if (this.courseDwnPromises[requiredSiteId] && this.courseDwnPromises[requiredSiteId][course.id] !== undefined) {
|
||||||
// There's already a download ongoing for this course, return the promise.
|
// There's already a download ongoing for this course, return the promise.
|
||||||
return this.courseDwnPromises[siteId][course.id];
|
return this.courseDwnPromises[requiredSiteId][course.id];
|
||||||
} else if (!this.courseDwnPromises[siteId]) {
|
} else if (!this.courseDwnPromises[requiredSiteId]) {
|
||||||
this.courseDwnPromises[siteId] = {};
|
this.courseDwnPromises[requiredSiteId] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// First of all, mark the course as being downloaded.
|
// First of all, mark the course as being downloaded.
|
||||||
this.courseDwnPromises[siteId][course.id] = CoreCourse.setCourseStatus(
|
this.courseDwnPromises[requiredSiteId][course.id] = CoreCourse.setCourseStatus(
|
||||||
course.id,
|
course.id,
|
||||||
CoreConstants.DOWNLOADING,
|
CoreConstants.DOWNLOADING,
|
||||||
siteId,
|
requiredSiteId,
|
||||||
).then(async () => {
|
).then(async () => {
|
||||||
|
|
||||||
const promises: Promise<unknown>[] = [];
|
const promises: Promise<unknown>[] = [];
|
||||||
|
@ -1740,17 +1752,17 @@ export class CoreCourseHelperProvider {
|
||||||
await CoreUtils.allPromises(promises);
|
await CoreUtils.allPromises(promises);
|
||||||
|
|
||||||
// Download success, mark the course as downloaded.
|
// Download success, mark the course as downloaded.
|
||||||
return CoreCourse.setCourseStatus(course.id, CoreConstants.DOWNLOADED, siteId);
|
return CoreCourse.setCourseStatus(course.id, CoreConstants.DOWNLOADED, requiredSiteId);
|
||||||
}).catch(async (error) => {
|
}).catch(async (error) => {
|
||||||
// Error, restore previous status.
|
// Error, restore previous status.
|
||||||
await CoreCourse.setCoursePreviousStatus(course.id, siteId);
|
await CoreCourse.setCoursePreviousStatus(course.id, requiredSiteId);
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
delete this.courseDwnPromises[siteId!][course.id];
|
delete this.courseDwnPromises[requiredSiteId][course.id];
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.courseDwnPromises[siteId][course.id];
|
return this.courseDwnPromises[requiredSiteId][course.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -633,9 +633,6 @@ export class CoreCourseProvider {
|
||||||
* @return The IMG src.
|
* @return The IMG src.
|
||||||
*/
|
*/
|
||||||
getModuleIconSrc(moduleName: string, modicon?: string): string {
|
getModuleIconSrc(moduleName: string, modicon?: string): string {
|
||||||
// @TODO: Check modicon url theme to apply other theme icons.
|
|
||||||
|
|
||||||
// Use default icon on core themes.
|
|
||||||
if (this.CORE_MODULES.indexOf(moduleName) < 0) {
|
if (this.CORE_MODULES.indexOf(moduleName) < 0) {
|
||||||
if (modicon) {
|
if (modicon) {
|
||||||
return modicon;
|
return modicon;
|
||||||
|
@ -644,6 +641,7 @@ export class CoreCourseProvider {
|
||||||
moduleName = 'external-tool';
|
moduleName = 'external-tool';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use default icon on core modules.
|
||||||
return 'assets/img/mod/' + moduleName + '.svg';
|
return 'assets/img/mod/' + moduleName + '.svg';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,7 @@ import { Injectable, Type } from '@angular/core';
|
||||||
|
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '../module-delegate';
|
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '../module-delegate';
|
||||||
import { CoreCourse, CoreCourseAnyModuleData, CoreCourseWSModule } from '../course';
|
import { CoreCourse, CoreCourseAnyModuleData } from '../course';
|
||||||
import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
|
|
||||||
import { CoreCourseModule } from '../course-helper';
|
import { CoreCourseModule } from '../course-helper';
|
||||||
import { CoreCourseUnsupportedModuleComponent } from '@features/course/components/unsupported-module/unsupported-module';
|
import { CoreCourseUnsupportedModuleComponent } from '@features/course/components/unsupported-module/unsupported-module';
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
||||||
|
@ -30,29 +29,20 @@ export class CoreCourseModuleDefaultHandler implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
name = 'CoreCourseModuleDefault';
|
name = 'CoreCourseModuleDefault';
|
||||||
modName = 'default';
|
modName = 'default';
|
||||||
|
protected pageName = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not the handler is enabled on a site level.
|
* @inheritdoc
|
||||||
*
|
|
||||||
* @return True or promise resolved with true if enabled.
|
|
||||||
*/
|
*/
|
||||||
async isEnabled(): Promise<boolean> {
|
async isEnabled(): Promise<boolean> {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the data required to display the module in the course contents view.
|
* @inheritdoc
|
||||||
*
|
|
||||||
* @param module The module object.
|
|
||||||
* @param courseId The course ID.
|
|
||||||
* @param sectionId The section ID.
|
|
||||||
* @return Data to render the module.
|
|
||||||
*/
|
*/
|
||||||
getData(
|
getData(
|
||||||
module: CoreCourseAnyModuleData,
|
module: CoreCourseAnyModuleData,
|
||||||
courseId: number, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
||||||
sectionId?: number, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
||||||
forCoursePage?: boolean, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
||||||
): CoreCourseModuleHandlerData {
|
): CoreCourseModuleHandlerData {
|
||||||
// Return the default data.
|
// Return the default data.
|
||||||
const defaultData: CoreCourseModuleHandlerData = {
|
const defaultData: CoreCourseModuleHandlerData = {
|
||||||
|
@ -71,6 +61,8 @@ export class CoreCourseModuleDefaultHandler implements CoreCourseModuleHandler {
|
||||||
};
|
};
|
||||||
|
|
||||||
if ('url' in module && module.url) {
|
if ('url' in module && module.url) {
|
||||||
|
const url = module.url;
|
||||||
|
|
||||||
defaultData.buttons = [{
|
defaultData.buttons = [{
|
||||||
icon: 'fas-external-link-alt',
|
icon: 'fas-external-link-alt',
|
||||||
label: 'core.openinbrowser',
|
label: 'core.openinbrowser',
|
||||||
|
@ -78,7 +70,7 @@ export class CoreCourseModuleDefaultHandler implements CoreCourseModuleHandler {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
CoreSites.getCurrentSite()!.openInBrowserWithAutoLoginIfSameSite(module.url!);
|
CoreSites.getRequiredCurrentSite().openInBrowserWithAutoLoginIfSameSite(url);
|
||||||
},
|
},
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
@ -87,24 +79,14 @@ export class CoreCourseModuleDefaultHandler implements CoreCourseModuleHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
* @inheritdoc
|
||||||
* The component returned must implement CoreCourseModuleMainComponent.
|
|
||||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
|
||||||
*
|
|
||||||
* @param course The course object.
|
|
||||||
* @param module The module object.
|
|
||||||
* @return The component (or promise resolved with component) to use, undefined if not found.
|
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
async getMainComponent(): Promise<Type<unknown>> {
|
||||||
async getMainComponent(course: CoreCourseAnyCourseData, module: CoreCourseWSModule): Promise<Type<unknown> | undefined> {
|
|
||||||
return CoreCourseUnsupportedModuleComponent;
|
return CoreCourseUnsupportedModuleComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to display the course refresher in single activity course format. If it returns false, a refresher must be
|
* @inheritdoc
|
||||||
* included in the template that calls the doRefresh method of the component. Defaults to true.
|
|
||||||
*
|
|
||||||
* @return Whether the refresher should be displayed.
|
|
||||||
*/
|
*/
|
||||||
displayRefresherInSingleActivity(): boolean {
|
displayRefresherInSingleActivity(): boolean {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -345,9 +345,10 @@ export class CoreCourseModuleDelegateService extends CoreDelegate<CoreCourseModu
|
||||||
* @param modicon The mod icon string.
|
* @param modicon The mod icon string.
|
||||||
* @return The icon src.
|
* @return The icon src.
|
||||||
*/
|
*/
|
||||||
getModuleIconSrc(modname: string, modicon?: string): string | undefined {
|
getModuleIconSrc(modname: string, modicon?: string): string {
|
||||||
return this.executeFunctionOnEnabled<string>(modname, 'getIconSrc') ||
|
return this.executeFunctionOnEnabled<string>(modname, 'getIconSrc') ||
|
||||||
CoreCourse.getModuleIconSrc(modname, modicon);
|
CoreCourse.getModuleIconSrc(modname, modicon) ||
|
||||||
|
'';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -59,7 +59,7 @@ export class CoreCoursesCategoriesPage implements OnInit {
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected async fetchCategories(): Promise<void> {
|
protected async fetchCategories(): Promise<void> {
|
||||||
try{
|
try {
|
||||||
const categories: CoreCategoryData[] = await CoreCourses.getCategories(this.categoryId, true);
|
const categories: CoreCategoryData[] = await CoreCourses.getCategories(this.categoryId, true);
|
||||||
|
|
||||||
this.currentCategory = undefined;
|
this.currentCategory = undefined;
|
||||||
|
|
|
@ -40,14 +40,26 @@ import { CoreNavigator } from '@services/navigator';
|
||||||
})
|
})
|
||||||
export class CoreGradesCoursePage implements AfterViewInit, OnDestroy {
|
export class CoreGradesCoursePage implements AfterViewInit, OnDestroy {
|
||||||
|
|
||||||
grades: CoreGradesCourseManager;
|
grades!: CoreGradesCourseManager;
|
||||||
splitViewMode?: CoreSplitViewMode;
|
splitViewMode?: CoreSplitViewMode;
|
||||||
|
|
||||||
@ViewChild(CoreSplitViewComponent) splitView!: CoreSplitViewComponent;
|
@ViewChild(CoreSplitViewComponent) splitView!: CoreSplitViewComponent;
|
||||||
|
|
||||||
constructor(protected route: ActivatedRoute) {
|
constructor(protected route: ActivatedRoute) {
|
||||||
const courseId = CoreNavigator.getRouteNumberParam('courseId', { route })!;
|
let courseId: number;
|
||||||
const userId = CoreNavigator.getRouteNumberParam('userId', { route }) ?? CoreSites.getCurrentSiteUserId();
|
let userId: number;
|
||||||
|
|
||||||
|
try {
|
||||||
|
courseId = CoreNavigator.getRequiredRouteNumberParam('courseId', { route });
|
||||||
|
userId = CoreNavigator.getRouteNumberParam('userId', { route }) ?? CoreSites.getCurrentSiteUserId();
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const useSplitView = route.snapshot.data.useSplitView ?? true;
|
const useSplitView = route.snapshot.data.useSplitView ?? true;
|
||||||
const outsideGradesTab = route.snapshot.data.outsideGradesTab ?? false;
|
const outsideGradesTab = route.snapshot.data.outsideGradesTab ?? false;
|
||||||
|
|
||||||
|
|
|
@ -31,16 +31,24 @@ import { CoreNavigator } from '@services/navigator';
|
||||||
})
|
})
|
||||||
export class CoreGradesGradePage implements OnInit {
|
export class CoreGradesGradePage implements OnInit {
|
||||||
|
|
||||||
courseId: number;
|
courseId!: number;
|
||||||
userId: number;
|
userId!: number;
|
||||||
gradeId: number;
|
gradeId!: number;
|
||||||
grade?: CoreGradesFormattedRow | null;
|
grade?: CoreGradesFormattedRow | null;
|
||||||
gradeLoaded = false;
|
gradeLoaded = false;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
try {
|
||||||
this.gradeId = CoreNavigator.getRouteNumberParam('gradeId')!;
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.userId = CoreNavigator.getRouteNumberParam('userId') ?? CoreSites.getCurrentSiteUserId();
|
this.gradeId = CoreNavigator.getRequiredRouteNumberParam('gradeId');
|
||||||
|
this.userId = CoreNavigator.getRouteNumberParam('userId') ?? CoreSites.getCurrentSiteUserId();
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,6 +15,11 @@
|
||||||
color: var(--color);
|
color: var(--color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
form div {
|
||||||
|
color: var(--color);
|
||||||
|
}
|
||||||
|
|
||||||
ion-button.core-button-as-link {
|
ion-button.core-button-as-link {
|
||||||
--color: var(--core-login-text-color);
|
--color: var(--core-login-text-color);
|
||||||
text-decoration-color: var(--core-login-text-color);
|
text-decoration-color: var(--core-login-text-color);
|
||||||
|
|
|
@ -35,7 +35,7 @@ import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreForms } from '@singletons/form';
|
import { CoreForms } from '@singletons/form';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that displays a "splash screen" while the app is being initialized.
|
* Site (url) chooser when adding a new site.
|
||||||
*/
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'page-core-login-site',
|
selector: 'page-core-login-site',
|
||||||
|
|
|
@ -33,7 +33,7 @@ import { CoreUtils } from '@services/utils/utils';
|
||||||
})
|
})
|
||||||
export class CoreUserParticipantsPage implements OnInit, AfterViewInit, OnDestroy {
|
export class CoreUserParticipantsPage implements OnInit, AfterViewInit, OnDestroy {
|
||||||
|
|
||||||
participants: CoreUserParticipantsManager;
|
participants!: CoreUserParticipantsManager;
|
||||||
searchQuery: string | null = null;
|
searchQuery: string | null = null;
|
||||||
searchInProgress = false;
|
searchInProgress = false;
|
||||||
searchEnabled = false;
|
searchEnabled = false;
|
||||||
|
@ -43,7 +43,17 @@ export class CoreUserParticipantsPage implements OnInit, AfterViewInit, OnDestro
|
||||||
@ViewChild(CoreSplitViewComponent) splitView!: CoreSplitViewComponent;
|
@ViewChild(CoreSplitViewComponent) splitView!: CoreSplitViewComponent;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
const courseId = CoreNavigator.getRouteNumberParam('courseId')!;
|
let courseId: number;
|
||||||
|
|
||||||
|
try {
|
||||||
|
courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
CoreNavigator.back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.participants = new CoreUserParticipantsManager(CoreUserParticipantsPage, courseId);
|
this.participants = new CoreUserParticipantsManager(CoreUserParticipantsPage, courseId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import { makeSingleton, NavController, Router } from '@singletons';
|
||||||
import { CoreScreen } from './screen';
|
import { CoreScreen } from './screen';
|
||||||
import { CoreApp } from './app';
|
import { CoreApp } from './app';
|
||||||
import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins';
|
import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins';
|
||||||
|
import { CoreError } from '@classes/errors/error';
|
||||||
|
|
||||||
const DEFAULT_MAIN_MENU_TAB = CoreMainMenuHomeHandlerService.PAGE_NAME;
|
const DEFAULT_MAIN_MENU_TAB = CoreMainMenuHomeHandlerService.PAGE_NAME;
|
||||||
|
|
||||||
|
@ -269,7 +270,7 @@ export class CoreNavigatorService {
|
||||||
|
|
||||||
const value = route.snapshot.queryParams[name] ?? route.snapshot.params[name];
|
const value = route.snapshot.queryParams[name] ?? route.snapshot.params[name];
|
||||||
|
|
||||||
if (typeof value != 'undefined') {
|
if (value !== undefined) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +301,7 @@ export class CoreNavigatorService {
|
||||||
value = routeOptions.params[name];
|
value = routeOptions.params[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof value == 'undefined') {
|
if (value === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +346,7 @@ export class CoreNavigatorService {
|
||||||
getRouteBooleanParam(name: string, routeOptions: CoreNavigatorCurrentRouteOptions = {}): boolean | undefined {
|
getRouteBooleanParam(name: string, routeOptions: CoreNavigatorCurrentRouteOptions = {}): boolean | undefined {
|
||||||
const value = this.getRouteParam<string>(name, routeOptions);
|
const value = this.getRouteParam<string>(name, routeOptions);
|
||||||
|
|
||||||
if (typeof value == 'undefined') {
|
if (value === undefined) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,6 +361,67 @@ export class CoreNavigatorService {
|
||||||
return Boolean(value);
|
return Boolean(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a parameter for the current route.
|
||||||
|
* Please notice that objects can only be retrieved once. You must call this function only once per page and parameter,
|
||||||
|
* unless there's a new navigation to the page.
|
||||||
|
*
|
||||||
|
* This function will fail if parameter is not found.
|
||||||
|
*
|
||||||
|
* @param name Name of the parameter.
|
||||||
|
* @param routeOptions Optional routeOptions to get the params or route value from. If missing, it will autodetect.
|
||||||
|
* @return Value of the parameter, undefined if not found.
|
||||||
|
*/
|
||||||
|
getRequiredRouteParam<T = unknown>(name: string, routeOptions: CoreNavigatorCurrentRouteOptions = {}): T {
|
||||||
|
const value = this.getRouteParam<T>(name, routeOptions);
|
||||||
|
|
||||||
|
if (value === undefined) {
|
||||||
|
throw new CoreError(`Required param '${name}' not found.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a number route param.
|
||||||
|
* Angular router automatically converts numbers to string, this function automatically converts it back to number.
|
||||||
|
*
|
||||||
|
* This function will fail if parameter is not found.
|
||||||
|
*
|
||||||
|
* @param name Name of the parameter.
|
||||||
|
* @param routeOptions Optional routeOptions to get the params or route value from. If missing, it will autodetect.
|
||||||
|
* @return Value of the parameter, undefined if not found.
|
||||||
|
*/
|
||||||
|
getRequiredRouteNumberParam(name: string, routeOptions: CoreNavigatorCurrentRouteOptions = {}): number {
|
||||||
|
const value = this.getRouteNumberParam(name, routeOptions);
|
||||||
|
|
||||||
|
if (value === undefined) {
|
||||||
|
throw new CoreError(`Required number param '${name}' not found.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a boolean route param.
|
||||||
|
* Angular router automatically converts booleans to string, this function automatically converts it back to boolean.
|
||||||
|
*
|
||||||
|
* This function will fail if parameter is not found.
|
||||||
|
*
|
||||||
|
* @param name Name of the parameter.
|
||||||
|
* @param routeOptions Optional routeOptions to get the params or route value from. If missing, it will autodetect.
|
||||||
|
* @return Value of the parameter, undefined if not found.
|
||||||
|
*/
|
||||||
|
getRequiredRouteBooleanParam(name: string, routeOptions: CoreNavigatorCurrentRouteOptions = {}): boolean {
|
||||||
|
const value = this.getRouteBooleanParam(name, routeOptions);
|
||||||
|
|
||||||
|
if (value === undefined) {
|
||||||
|
throw new CoreError(`Required boolean param '${name}' not found.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Navigate back.
|
* Navigate back.
|
||||||
*
|
*
|
||||||
|
|
|
@ -305,7 +305,7 @@ export class CoreSitesProvider {
|
||||||
if (data.errorcode && (data.errorcode == 'enablewsdescription' || data.errorcode == 'requirecorrectaccess')) {
|
if (data.errorcode && (data.errorcode == 'enablewsdescription' || data.errorcode == 'requirecorrectaccess')) {
|
||||||
throw new CoreSiteError({
|
throw new CoreSiteError({
|
||||||
errorcode: data.errorcode,
|
errorcode: data.errorcode,
|
||||||
message: data.error!,
|
message: data.error ?? '',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -816,11 +816,24 @@ export class CoreSitesProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current site.
|
* Get current site or undefined if none.
|
||||||
|
*
|
||||||
|
* @return Current site or undefined if none.
|
||||||
|
*/
|
||||||
|
getCurrentSite(): CoreSite | undefined {
|
||||||
|
return this.currentSite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current site or fail if none.
|
||||||
*
|
*
|
||||||
* @return Current site.
|
* @return Current site.
|
||||||
*/
|
*/
|
||||||
getCurrentSite(): CoreSite | undefined {
|
getRequiredCurrentSite(): CoreSite {
|
||||||
|
if (!this.currentSite) {
|
||||||
|
throw new CoreError('You aren\'t authenticated in any site.');
|
||||||
|
}
|
||||||
|
|
||||||
return this.currentSite;
|
return this.currentSite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1487,7 +1500,9 @@ export class CoreSitesProvider {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.siteSchemasMigration[site.id]) {
|
const siteId = site.id;
|
||||||
|
|
||||||
|
if (this.siteSchemasMigration[site.id] !== undefined) {
|
||||||
return this.siteSchemasMigration[site.id];
|
return this.siteSchemasMigration[site.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1500,7 +1515,7 @@ export class CoreSitesProvider {
|
||||||
this.siteSchemasMigration[site.id] = promise;
|
this.siteSchemasMigration[site.id] = promise;
|
||||||
|
|
||||||
return promise.finally(() => {
|
return promise.finally(() => {
|
||||||
delete this.siteSchemasMigration[site.id!];
|
delete this.siteSchemasMigration[siteId];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -548,6 +548,10 @@ ion-card ion-item img.core-module-icon[slot="start"] {
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ion-card ion-item:only-child {
|
||||||
|
--inner-border-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
[dir=rtl] ion-item img.core-module-icon[slot="start"] {
|
[dir=rtl] ion-item img.core-module-icon[slot="start"] {
|
||||||
margin-right: unset;
|
margin-right: unset;
|
||||||
margin-left: 32px;
|
margin-left: 32px;
|
||||||
|
|
Loading…
Reference in New Issue