MOBILE-3636 assign: Use list manager on submission list

main
Pau Ferrer Ocaña 2021-02-22 15:58:52 +01:00
parent 5c56bf0635
commit d6169879fd
2 changed files with 67 additions and 59 deletions

View File

@ -14,11 +14,11 @@
<ion-content> <ion-content>
<core-split-view> <core-split-view>
<ion-refresher slot="fixed" [disabled]="!loaded" (ionRefresh)="refreshList($event)"> <ion-refresher slot="fixed" [disabled]="!loaded || !submissions.loaded" (ionRefresh)="refreshList($event)">
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
</ion-refresher> </ion-refresher>
<core-loading [hideUntil]="loaded"> <core-loading [hideUntil]="loaded && submissions.loaded">
<core-empty-box *ngIf="!submissions || submissions.length == 0" icon="fas-file-signature" <core-empty-box *ngIf="!submissions || submissions.empty" icon="fas-file-signature"
[message]="'addon.mod_assign.submissionstatus_' | translate"> [message]="'addon.mod_assign.submissionstatus_' | translate">
</core-empty-box> </core-empty-box>
@ -38,9 +38,9 @@
</ion-select> </ion-select>
</ion-item> </ion-item>
<!-- List of submissions. --> <!-- List of submissions. -->
<ng-container *ngFor="let submission of submissions"> <ng-container *ngFor="let submission of submissions.items">
<ion-item class="ion-text-wrap" (click)="loadSubmission(submission)" <ion-item class="ion-text-wrap" (click)="submissions.select(submission)"
[class.core-selected-item]="submission.submitid == selectedSubmissionId"> [class.core-selected-item]="submissions.isSelected(submission)">
<core-user-avatar [user]="submission" [linkProfile]="false" slot="start"></core-user-avatar> <core-user-avatar [user]="submission" [linkProfile]="false" slot="start"></core-user-avatar>
<ion-label> <ion-label>
<h2 *ngIf="submission.userfullname">{{submission.userfullname}}</h2> <h2 *ngIf="submission.userfullname">{{submission.userfullname}}</h2>

View File

@ -12,17 +12,19 @@
// 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 } from '@angular/core'; import { Component, OnDestroy, AfterViewInit, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute, ActivatedRouteSnapshot, Params } from '@angular/router';
import { CorePageItemsListManager } from '@classes/page-items-list-manager';
import { CoreSplitViewComponent } from '@components/split-view/split-view';
import { IonRefresher } from '@ionic/angular'; import { IonRefresher } from '@ionic/angular';
import { CoreGroupInfo, CoreGroups } from '@services/groups'; import { CoreGroupInfo, CoreGroups } from '@services/groups';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreScreen } from '@services/screen';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { Translate } from '@singletons'; import { Translate } from '@singletons';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreObject } from '@singletons/object';
import { import {
AddonModAssignAssign, AddonModAssignAssign,
AddonModAssignSubmission, AddonModAssignSubmission,
@ -38,7 +40,6 @@ import {
AddonModAssignManualSyncData, AddonModAssignManualSyncData,
AddonModAssignAutoSyncData, AddonModAssignAutoSyncData,
} from '../../services/assign-sync'; } from '../../services/assign-sync';
import { AddonModAssignModuleHandlerService } from '../../services/handlers/module';
/** /**
* Page that displays a list of submissions of an assignment. * Page that displays a list of submissions of an assignment.
@ -47,16 +48,15 @@ import { AddonModAssignModuleHandlerService } from '../../services/handlers/modu
selector: 'page-addon-mod-assign-submission-list', selector: 'page-addon-mod-assign-submission-list',
templateUrl: 'submission-list.html', templateUrl: 'submission-list.html',
}) })
export class AddonModAssignSubmissionListPage implements OnInit, OnDestroy { export class AddonModAssignSubmissionListPage implements AfterViewInit, OnDestroy {
// @ViewChild(CoreSplitViewComponent) splitviewCtrl: CoreSplitViewComponent; @ViewChild(CoreSplitViewComponent) splitView!: CoreSplitViewComponent;
title = ''; // Title to display. title = ''; // Title to display.
assign?: AddonModAssignAssign; // Assignment. assign?: AddonModAssignAssign; // Assignment.
submissions: AddonModAssignSubmissionForList[] = []; // List of submissions submissions: AddonModAssignSubmissionListManager; // List of submissions
loaded = false; // Whether data has been loaded. loaded = false; // Whether data has been loaded.
haveAllParticipants = true; // Whether all participants have been loaded. haveAllParticipants = true; // Whether all participants have been loaded.
selectedSubmissionId?: number; // Selected submission ID.
groupId = 0; // Group ID to show. groupId = 0; // Group ID to show.
courseId!: number; // Course ID the assignment belongs to. courseId!: number; // Course ID the assignment belongs to.
moduleId!: number; // Module ID the submission belongs to. moduleId!: number; // Module ID the submission belongs to.
@ -78,6 +78,8 @@ export class AddonModAssignSubmissionListPage implements OnInit, OnDestroy {
constructor( constructor(
protected route: ActivatedRoute, protected route: ActivatedRoute,
) { ) {
this.submissions = new AddonModAssignSubmissionListManager(AddonModAssignSubmissionListPage);
// Update data if some grade changes. // Update data if some grade changes.
this.gradedObserver = CoreEvents.on<AddonModAssignGradedEventData>( this.gradedObserver = CoreEvents.on<AddonModAssignGradedEventData>(
AddonModAssignProvider.GRADED_EVENT, AddonModAssignProvider.GRADED_EVENT,
@ -121,31 +123,24 @@ export class AddonModAssignSubmissionListPage implements OnInit, OnDestroy {
/** /**
* Component being initialized. * Component being initialized.
*/ */
ngOnInit(): void { ngAfterViewInit(): void {
this.moduleId = CoreNavigator.instance.getRouteNumberParam('cmId')!; this.moduleId = CoreNavigator.instance.getRouteNumberParam('cmId')!;
this.courseId = CoreNavigator.instance.getRouteNumberParam('courseId')!; this.courseId = CoreNavigator.instance.getRouteNumberParam('courseId')!;
this.groupId = CoreNavigator.instance.getRouteNumberParam('groupId') || 0;
this.selectedStatus = CoreNavigator.instance.getRouteParam('status');
this.route.queryParams.subscribe((params) => { if (this.selectedStatus) {
this.groupId = CoreNavigator.instance.getRouteNumberParam('groupId', params) || 0; if (this.selectedStatus == AddonModAssignProvider.NEED_GRADING) {
this.selectedStatus = CoreNavigator.instance.getRouteParam('status', params); this.title = Translate.instance.instant('addon.mod_assign.numberofsubmissionsneedgrading');
if (this.selectedStatus) {
if (this.selectedStatus == AddonModAssignProvider.NEED_GRADING) {
this.title = Translate.instance.instant('addon.mod_assign.numberofsubmissionsneedgrading');
} else {
this.title = Translate.instance.instant('addon.mod_assign.submissionstatus_' + this.selectedStatus);
}
} else { } else {
this.title = Translate.instance.instant('addon.mod_assign.numberofparticipants'); this.title = Translate.instance.instant('addon.mod_assign.submissionstatus_' + this.selectedStatus);
} }
this.fetchAssignment(true).finally(() => { } else {
if (!this.selectedSubmissionId && CoreScreen.instance.isTablet && this.submissions.length > 0) { this.title = Translate.instance.instant('addon.mod_assign.numberofparticipants');
// Take first and load it. }
this.loadSubmission(this.submissions[0]); this.fetchAssignment(true).finally(() => {
} this.loaded = true;
this.submissions.start(this.splitView);
this.loaded = true;
});
}); });
} }
@ -215,7 +210,7 @@ export class AddonModAssignSubmissionListPage implements OnInit, OnDestroy {
if (!CoreSites.instance.getCurrentSite()?.wsAvailable('mod_assign_list_participants')) { if (!CoreSites.instance.getCurrentSite()?.wsAvailable('mod_assign_list_participants')) {
// Submissions are not displayed in Moodle 3.1 without the local plugin, see MOBILE-2968. // Submissions are not displayed in Moodle 3.1 without the local plugin, see MOBILE-2968.
this.haveAllParticipants = false; this.haveAllParticipants = false;
this.submissions = []; this.submissions.resetItems();
return; return;
} }
@ -303,30 +298,7 @@ export class AddonModAssignSubmissionListPage implements OnInit, OnDestroy {
await Promise.all(promises); await Promise.all(promises);
this.submissions = showSubmissions; this.submissions.setItems(showSubmissions);
}
/**
* Load a certain submission.
*
* @param submission The submission to load.
*/
loadSubmission(submission: AddonModAssignSubmissionForList): void {
if (this.selectedSubmissionId === submission.submitid) {
// Already selected.
return;
}
this.selectedSubmissionId = submission.submitid;
CoreNavigator.instance.navigateToSitePath(
AddonModAssignModuleHandlerService.PAGE_NAME+'/'+this.courseId+'/'+this.moduleId+'/submission/'+submission.submitid,
{
params: {
blindId: submission.blindid,
},
},
);
} }
/** /**
@ -370,6 +342,42 @@ export class AddonModAssignSubmissionListPage implements OnInit, OnDestroy {
ngOnDestroy(): void { ngOnDestroy(): void {
this.gradedObserver?.off(); this.gradedObserver?.off();
this.syncObserver?.off(); this.syncObserver?.off();
this.submissions.destroy();
}
}
/**
* Helper class to manage submissions.
*/
class AddonModAssignSubmissionListManager extends CorePageItemsListManager<AddonModAssignSubmissionForList> {
constructor(pageComponent: unknown) {
super(pageComponent);
}
/**
* @inheritdoc
*/
protected getItemPath(submission: AddonModAssignSubmissionForList): string {
return String(submission.submitid);
}
/**
* @inheritdoc
*/
protected getItemQueryParams(submission: AddonModAssignSubmissionForList): Params {
return CoreObject.withoutEmpty({
blindId: submission.blindid,
});
}
/**
* @inheritdoc
*/
protected getSelectedItemPath(route: ActivatedRouteSnapshot): string | null {
return route.params.submitId ?? null;
} }
} }