Merge pull request #2858 from dpalou/MOBILE-3320

Mobile 3320
main
Pau Ferrer Ocaña 2021-06-30 15:27:23 +02:00 committed by GitHub
commit 709d8bf43b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 47 additions and 33 deletions

View File

@ -270,10 +270,13 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
async ngOnInit(): Promise<void> {
this.route.queryParams.subscribe(async (params) => {
// When a child page loads this callback is triggered too.
this.selectedConversationId =
CoreNavigator.getRouteNumberParam('conversationId', { params }) ?? this.selectedConversationId;
this.selectedUserId =
CoreNavigator.getRouteNumberParam('userId', { params }) ?? this.selectedUserId;
const conversationId =CoreNavigator.getRouteNumberParam('conversationId', { params });
const userId = CoreNavigator.getRouteNumberParam('userId', { params });
if (conversationId || userId) {
// Update the selected ones.
this.selectedConversationId = conversationId;
this.selectedUserId = userId;
}
});
await this.fetchData();

View File

@ -280,9 +280,11 @@
</ion-item>
</ng-container>
<addon-mod-assign-feedback-plugin *ngFor="let plugin of feedback!.plugins" [assign]="assign"
<ng-container *ngIf="feedback">
<addon-mod-assign-feedback-plugin *ngFor="let plugin of feedback.plugins" [assign]="assign"
[submission]="userSubmission" [userId]="submitId" [plugin]="plugin" [canEdit]="canSaveGrades">
</addon-mod-assign-feedback-plugin>
</ng-container>
<!-- Workflow status. -->
<ion-item class="ion-text-wrap" *ngIf="workflowStatusTranslationId">
@ -338,7 +340,7 @@
</ion-item>
<!-- Grader is hidden, display only the grade date. -->
<ion-item class="ion-text-wrap" *ngIf="!grader && feedback!.gradeddate">
<ion-item class="ion-text-wrap" *ngIf="!grader && feedback?.gradeddate">
<ion-label>
<h2>{{ 'addon.mod_assign.gradedon' | translate }}</h2>
<p>{{ feedback!.gradeddate * 1000 | coreFormatDate }}</p>

View File

@ -671,8 +671,8 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
AddonModAssign.getSubmissionGradingStatusTranslationId(this.grade.gradingStatus);
}
if (this.lastAttempt?.gradingstatus == 'graded' && !this.assign!.markingworkflow) {
if (this.feedback!.gradeddate < this.lastAttempt!.submission!.timemodified) {
if (this.lastAttempt?.gradingstatus == 'graded' && !this.assign!.markingworkflow && this.userSubmission && feedback) {
if (feedback.gradeddate < this.userSubmission.timemodified) {
this.lastAttempt.gradingstatus = AddonModAssignProvider.GRADED_FOLLOWUP_SUBMIT;
// Get grading text and color.

View File

@ -29,6 +29,7 @@ import {
AddonModAssignSubmission,
AddonModAssignProvider,
AddonModAssign,
AddonModAssignGrade,
} from '../../services/assign';
import { AddonModAssignHelper, AddonModAssignSubmissionFormatted } from '../../services/assign-helper';
import { AddonModAssignOffline } from '../../services/assign-offline';
@ -252,7 +253,10 @@ export class AddonModAssignSubmissionListPage implements AfterViewInit, OnDestro
// Get the last grade of the submission.
const grade = grades
.filter((grade) => grade.userid == submission.userid)
.reduce((a, b) => (a.timemodified > b.timemodified ? a : b));
.reduce(
(a, b) => (a && a.timemodified > b.timemodified ? a : b),
<AddonModAssignGrade | undefined> undefined,
);
if (grade && grade.timemodified < submission.timemodified) {
submission.gradingstatus = AddonModAssignProvider.GRADED_FOLLOWUP_SUBMIT;

View File

@ -1377,6 +1377,8 @@ export class AddonModAssignProvider {
// The WebService returned warnings, reject.
throw new CoreWSError(warnings[0]);
}
return;
}
// WS not available, fallback to save_grade.

View File

@ -458,6 +458,11 @@ export class AddonModAssignPrefetchHandlerService extends CoreCourseActivityPref
userIds.push(userSubmission.userid);
}
}
if (assign.teamsubmission && submission.lastattempt.submissiongroup) {
// Prefetch group info.
promises.push(CoreGroups.getActivityAllowedGroups(assign.cmid));
}
}
// Prefetch grade items.

View File

@ -190,7 +190,10 @@ export class AddonModLessonOfflineProvider {
const attempts = await this.getRetakeAttemptsForPage(lessonId, retake, retakeData.lastquestionpage, siteId);
// Return the attempt with highest timemodified.
return attempts.reduce((a, b) => a.timemodified > b.timemodified ? a : b);
return attempts.reduce(
(a, b) => a && a.timemodified > b.timemodified ? a : b,
<AddonModLessonPageAttemptRecord | undefined> undefined,
);
} catch {
// Error, return undefined.
}

View File

@ -53,7 +53,7 @@
[access]="access" [assessmentId]="assessmentId" [userId]="profile && profile.id" [strategy]="strategy">
</addon-mod-workshop-assessment-strategy>
<form ion-list [formGroup]="evaluateForm" *ngIf="evaluating" #evaluateFormEl>
<form [formGroup]="evaluateForm" *ngIf="evaluating" #evaluateFormEl>
<ion-item class="ion-text-wrap">
<ion-label><h2>{{ 'addon.mod_workshop.assessmentsettings' | translate }}</h2></ion-label>
</ion-item>

View File

@ -13,7 +13,7 @@
</ion-header>
<ion-content>
<core-loading [hideUntil]="loaded">
<form ion-list [formGroup]="editForm" *ngIf="workshop" #editFormEl>
<form [formGroup]="editForm" *ngIf="workshop" #editFormEl>
<ion-item class="ion-text-wrap">
<ion-label position="stacked">
<span core-mark-required="true">

View File

@ -97,7 +97,7 @@
</addon-mod-workshop-assessment>
</ion-list>
<form ion-list [formGroup]="feedbackForm" *ngIf="canAddFeedback && submission" #feedbackFormEl>
<form [formGroup]="feedbackForm" *ngIf="canAddFeedback && submission" #feedbackFormEl>
<ion-item class="ion-text-wrap">
<ion-label>
<h2>{{ 'addon.mod_workshop.feedbackauthor' | translate }}</h2>

View File

@ -632,7 +632,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
const completionModules = (<CoreCourseModule[]> [])
.concat(...this.sections!.map((section) => section.modules))
.map((module) => module.completion && module.completion > 0 ? 1 : module.completion)
.reduce((accumulator, currentValue) => (accumulator || 0) + (currentValue || 0));
.reduce((accumulator, currentValue) => (accumulator || 0) + (currentValue || 0), 0);
const moduleProgressPercent = 100 / (completionModules || 1);
// Use min/max here to avoid floating point rounding errors over/under-flowing the progress bar.

View File

@ -52,9 +52,8 @@ export class CoreLoginHelperProvider {
static readonly FAQ_QRCODE_IMAGE_HTML = '<img src="assets/img/login/faq_qrcode.png" role="presentation" alt="">';
protected logger: CoreLogger;
protected isSSOConfirmShown = false;
protected sessionExpiredCheckingSite: Record<string, boolean> = {};
protected isOpenEditAlertShown = false;
protected isOpeningReconnect = false;
protected waitingForBrowser = false;
constructor() {
@ -885,6 +884,12 @@ export class CoreLoginHelperProvider {
return; // Site that triggered the event is not current site.
}
if (this.sessionExpiredCheckingSite[siteId || '']) {
return; // Operation pending.
}
this.sessionExpiredCheckingSite[siteId || ''] = true;
try {
// Check authentication method.
const result = await CoreSites.checkSite(siteUrl);
@ -895,9 +900,7 @@ export class CoreLoginHelperProvider {
if (this.isSSOLoginNeeded(result.code)) {
// SSO. User needs to authenticate in a browser. Check if we need to display a message.
if (!CoreApp.isSSOAuthenticationOngoing() && !this.isSSOConfirmShown && !this.waitingForBrowser) {
this.isSSOConfirmShown = true;
if (!CoreApp.isSSOAuthenticationOngoing() && !this.waitingForBrowser) {
try {
if (this.shouldShowSSOConfirm(result.code)) {
await CoreDomUtils.showConfirm(Translate.instant('core.login.' +
@ -917,8 +920,6 @@ export class CoreLoginHelperProvider {
} catch (error) {
// User cancelled, logout him.
CoreSites.logout();
} finally {
this.isSSOConfirmShown = false;
}
}
} else {
@ -932,10 +933,8 @@ export class CoreLoginHelperProvider {
});
if (providerToUse) {
if (!CoreApp.isSSOAuthenticationOngoing() && !this.isSSOConfirmShown && !this.waitingForBrowser) {
if (!CoreApp.isSSOAuthenticationOngoing() && !this.waitingForBrowser) {
// Open browser to perform the OAuth.
this.isSSOConfirmShown = true;
const confirmMessage = Translate.instant('core.login.' +
(currentSite.isLoggedOut() ? 'loggedoutssodescription' : 'reconnectssodescription'));
@ -955,8 +954,6 @@ export class CoreLoginHelperProvider {
} catch (error) {
// User cancelled, logout him.
CoreSites.logout();
} finally {
this.isSSOConfirmShown = false;
}
}
@ -965,14 +962,12 @@ export class CoreLoginHelperProvider {
}
const info = currentSite.getInfo();
if (typeof info != 'undefined' && typeof info.username != 'undefined' && !this.isOpeningReconnect) {
if (typeof info != 'undefined' && typeof info.username != 'undefined') {
// If current page is already reconnect, stop.
if (CoreNavigator.isCurrent('/login/reconnect')) {
return;
}
this.isOpeningReconnect = true;
await CoreUtils.ignoreErrors(CoreNavigator.navigate('/login/reconnect', {
params: {
siteId,
@ -981,8 +976,6 @@ export class CoreLoginHelperProvider {
},
reset: true,
}));
this.isOpeningReconnect = false;
}
}
} catch (error) {
@ -992,6 +985,8 @@ export class CoreLoginHelperProvider {
CoreDomUtils.showErrorModalDefault(error, 'core.networkerrormsg', true);
CoreSites.logout();
}
} finally {
this.sessionExpiredCheckingSite[siteId || ''] = false;
}
}