Merge pull request #3478 from crazyserver/MOBILE-4081

Mobile 4081
main
Dani Palou 2022-11-28 08:56:30 +01:00 committed by GitHub
commit 4c885b592d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 108 additions and 6 deletions

View File

@ -14,11 +14,13 @@
import { APP_INITIALIZER, NgModule, Type } from '@angular/core';
import { Routes } from '@angular/router';
import { CoreContentLinksDelegate } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreCourseIndexRoutingModule } from '@features/course/pages/index/index-routing.module';
import { CoreCourseOptionsDelegate } from '@features/course/services/course-options-delegate';
import { CoreMainMenuTabRoutingModule } from '@features/mainmenu/mainmenu-tab-routing.module';
import { CoreUserDelegate } from '@features/user/services/user-delegate';
import { AddonCourseCompletionProvider } from './services/coursecompletion';
import { AddonCourseCompletionStatusLinkHandler } from './services/handlers/completionstatus-link';
import { AddonCourseCompletionCourseOptionHandler } from './services/handlers/course-option';
import { AddonCourseCompletionUserHandler } from './services/handlers/user';
@ -45,6 +47,7 @@ const routes: Routes = [
useValue: () => {
CoreUserDelegate.registerHandler(AddonCourseCompletionUserHandler.instance);
CoreCourseOptionsDelegate.registerHandler(AddonCourseCompletionCourseOptionHandler.instance);
CoreContentLinksDelegate.registerHandler(AddonCourseCompletionStatusLinkHandler.instance);
},
},
],

View File

@ -13,6 +13,13 @@
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
</ion-refresher>
<core-loading [hideUntil]="completionLoaded">
<ion-item class="ion-text-wrap" *ngIf="user">
<core-user-avatar [user]="user" [courseId]="courseId" slot="start" [linkProfile]="false"></core-user-avatar>
<ion-label>
<h2>{{user!.fullname}}</h2>
</ion-label>
</ion-item>
<ion-card *ngIf="completion && tracked">
<ion-item class="ion-text-wrap">
<ion-label>

View File

@ -17,6 +17,7 @@ import {
AddonCourseCompletionCourseCompletionStatus,
} from '@addons/coursecompletion/services/coursecompletion';
import { Component, OnInit } from '@angular/core';
import { CoreUser, CoreUserProfile } from '@features/user/services/user';
import { IonRefresher } from '@ionic/angular';
import { CoreNavigator } from '@services/navigator';
import { CoreSites } from '@services/sites';
@ -31,14 +32,15 @@ import { CoreDomUtils } from '@services/utils/dom';
})
export class AddonCourseCompletionReportPage implements OnInit {
protected courseId!: number;
protected userId!: number;
courseId!: number;
completionLoaded = false;
completion?: AddonCourseCompletionCourseCompletionStatus;
showSelfComplete = false;
tracked = true; // Whether completion is tracked.
statusText?: string;
user?: CoreUserProfile;
/**
* @inheritdoc
@ -67,6 +69,8 @@ export class AddonCourseCompletionReportPage implements OnInit {
*/
protected async fetchCompletion(): Promise<void> {
try {
this.user = await CoreUser.getProfile(this.userId, this.courseId, true);
this.completion = await AddonCourseCompletion.getCompletion(this.courseId, this.userId);
this.statusText = AddonCourseCompletion.getCompletedStatusText(this.completion);

View File

@ -224,7 +224,7 @@ export class AddonCourseCompletionProvider {
// Check if user wants to view his own completion.
try {
if (!userId || userId == currentUserId) {
if (!userId || userId === currentUserId) {
// Viewing own completion. Get the course to check if it has completion criteria.
const course = await CoreCourses.getUserCourse(courseId, true);

View File

@ -0,0 +1,80 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base-handler';
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreNavigator } from '@services/navigator';
import { CoreSites } from '@services/sites';
import { makeSingleton } from '@singletons';
import { AddonCourseCompletion } from '../coursecompletion';
/**
* Handler to treat links to user course completion status.
*/
@Injectable({ providedIn: 'root' })
export class AddonCourseCompletionStatusLinkHandlerService extends CoreContentLinksHandlerBase {
name = 'AddonCourseCompletionStatusLinkHandler';
pattern = /\/blocks\/completionstatus\/details\.php.*([?&](course|user)=\d+)/;
/**
* @inheritdoc
*/
getActions(
siteIds: string[],
url: string,
params: Record<string, string>,
): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
return [{
action: async (siteId): Promise<void> => {
let userId = params.user ? parseInt(params.user, 10) : undefined;
const courseId = parseInt(params.course, 10);
if (!userId) {
const site = await CoreSites.getSite(siteId);
userId = site.getUserId();
}
const pageParams = {
courseId,
userId,
};
CoreNavigator.navigateToSitePath(
'/coursecompletion',
{ params: pageParams, siteId },
);
},
}];
}
/**
* @inheritdoc
*/
async isEnabled(siteId: string, url: string, params: Record<string, string>): Promise<boolean> {
let userId = params.user ? parseInt(params.user, 10) : undefined;
const courseId = parseInt(params.course, 10);
if (!userId) {
const site = await CoreSites.getSite(siteId);
userId = site.getUserId();
}
return AddonCourseCompletion.isPluginViewEnabledForUser(courseId, userId, siteId);
}
}
export const AddonCourseCompletionStatusLinkHandler = makeSingleton(AddonCourseCompletionStatusLinkHandlerService);

View File

@ -17,6 +17,7 @@ import { Injectable } from '@angular/core';
import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base-handler';
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreNavigator } from '@services/navigator';
import { CoreSites } from '@services/sites';
import { makeSingleton } from '@singletons';
/**
@ -27,7 +28,7 @@ export class CoreUserProfileLinkHandlerService extends CoreContentLinksHandlerBa
name = 'CoreUserProfileLinkHandler';
// Match user/view.php and user/profile.php but NOT grade/report/user/.
pattern = /((\/user\/view\.php)|(\/user\/profile\.php)).*([?&]id=\d+)/;
pattern = /(\/user\/view\.php)|(\/user\/profile\.php)/;
/**
* @inheritdoc
@ -37,11 +38,18 @@ export class CoreUserProfileLinkHandlerService extends CoreContentLinksHandlerBa
url: string,
params: Record<string, string>,
): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
return [{
action: (siteId): void => {
action: async (siteId): Promise<void> => {
let userId = params.id ? parseInt(params.id, 10) : 0;
if (!userId) {
const site = await CoreSites.getSite(siteId);
userId = site.getUserId();
}
const pageParams = {
courseId: params.course,
userId: parseInt(params.id, 10),
userId,
};
CoreNavigator.navigateToSitePath('/user', { params: pageParams, siteId });
@ -53,7 +61,7 @@ export class CoreUserProfileLinkHandlerService extends CoreContentLinksHandlerBa
* @inheritdoc
*/
async isEnabled(siteId: string, url: string): Promise<boolean> {
return url.indexOf('/grade/report/') == -1;
return url.indexOf('/grade/report/') === -1;
}
}