2021-04-22 15:19:15 +02:00
|
|
|
// (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.
|
|
|
|
|
2021-12-09 13:47:36 +01:00
|
|
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
2024-01-11 15:33:14 +01:00
|
|
|
import { ActivatedRoute, ActivatedRouteSnapshot } from '@angular/router';
|
2021-12-09 13:47:36 +01:00
|
|
|
import { CoreRoutedItemsManagerSourcesTracker } from '@classes/items-management/routed-items-manager-sources-tracker';
|
|
|
|
import { CoreSwipeNavigationItemsManager } from '@classes/items-management/swipe-navigation-items-manager';
|
2021-04-22 15:19:15 +02:00
|
|
|
import { CoreNavigator } from '@services/navigator';
|
|
|
|
import { CoreDomUtils } from '@services/utils/dom';
|
|
|
|
import { CoreTextUtils } from '@services/utils/text';
|
2021-12-09 13:47:36 +01:00
|
|
|
import { AddonModFeedbackAttemptsSource } from '../../classes/feedback-attempts-source';
|
2021-04-22 15:19:15 +02:00
|
|
|
import {
|
|
|
|
AddonModFeedback,
|
|
|
|
AddonModFeedbackProvider,
|
|
|
|
AddonModFeedbackWSAnonAttempt,
|
|
|
|
AddonModFeedbackWSFeedback,
|
|
|
|
} from '../../services/feedback';
|
2023-05-11 12:19:16 +02:00
|
|
|
import { AddonModFeedbackAttempt, AddonModFeedbackFormItem, AddonModFeedbackHelper } from '../../services/feedback-helper';
|
2023-06-22 11:09:33 +02:00
|
|
|
import { CoreTime } from '@singletons/time';
|
|
|
|
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
|
2021-04-22 15:19:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Page that displays a feedback attempt review.
|
|
|
|
*/
|
|
|
|
@Component({
|
|
|
|
selector: 'page-addon-mod-feedback-attempt',
|
|
|
|
templateUrl: 'attempt.html',
|
|
|
|
})
|
2021-12-09 13:47:36 +01:00
|
|
|
export class AddonModFeedbackAttemptPage implements OnInit, OnDestroy {
|
2021-04-22 15:19:15 +02:00
|
|
|
|
2021-12-09 15:19:37 +01:00
|
|
|
cmId: number;
|
|
|
|
courseId: number;
|
2021-04-22 15:19:15 +02:00
|
|
|
feedback?: AddonModFeedbackWSFeedback;
|
2023-05-11 12:19:16 +02:00
|
|
|
attempt?: AddonModFeedbackAttempt;
|
2021-12-09 15:19:37 +01:00
|
|
|
attempts: AddonModFeedbackAttemptsSwipeManager;
|
2021-04-22 15:19:15 +02:00
|
|
|
anonAttempt?: AddonModFeedbackWSAnonAttempt;
|
|
|
|
items: AddonModFeedbackAttemptItem[] = [];
|
|
|
|
component = AddonModFeedbackProvider.COMPONENT;
|
|
|
|
loaded = false;
|
|
|
|
|
2021-12-09 15:19:37 +01:00
|
|
|
protected attemptId: number;
|
2023-09-13 12:35:59 +02:00
|
|
|
protected groupId?: number;
|
2023-06-22 11:09:33 +02:00
|
|
|
protected logView: () => void;
|
2021-12-09 15:19:37 +01:00
|
|
|
|
|
|
|
constructor() {
|
|
|
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
|
|
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
|
|
|
this.attemptId = CoreNavigator.getRequiredRouteNumberParam('attemptId');
|
2023-09-13 12:35:59 +02:00
|
|
|
this.groupId = CoreNavigator.getRouteNumberParam('groupId');
|
2021-12-09 15:19:37 +01:00
|
|
|
|
|
|
|
const source = CoreRoutedItemsManagerSourcesTracker.getOrCreateSource(
|
|
|
|
AddonModFeedbackAttemptsSource,
|
|
|
|
[this.courseId, this.cmId],
|
|
|
|
);
|
|
|
|
|
|
|
|
this.attempts = new AddonModFeedbackAttemptsSwipeManager(source);
|
2023-06-22 11:09:33 +02:00
|
|
|
|
|
|
|
this.logView = CoreTime.once(() => {
|
|
|
|
if (!this.feedback) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
CoreAnalytics.logEvent({
|
|
|
|
type: CoreAnalyticsEventType.VIEW_ITEM,
|
|
|
|
ws: 'mod_feedback_get_responses_analysis',
|
|
|
|
name: this.feedback.name,
|
|
|
|
data: { id: this.attemptId, feedbackid: this.feedback.id, category: 'feedback' },
|
|
|
|
url: `/mod/feedback/show_entries.php?id=${this.cmId}` +
|
|
|
|
(this.attempt ? `userid=${this.attempt.userid}` : '' ) + `&showcompleted=${this.attemptId}`,
|
|
|
|
});
|
|
|
|
});
|
2021-12-09 15:19:37 +01:00
|
|
|
}
|
|
|
|
|
2021-04-22 15:19:15 +02:00
|
|
|
/**
|
|
|
|
* @inheritdoc
|
|
|
|
*/
|
2022-08-31 13:36:05 +02:00
|
|
|
async ngOnInit(): Promise<void> {
|
2021-09-09 16:38:38 +02:00
|
|
|
try {
|
2022-08-31 13:36:05 +02:00
|
|
|
await this.attempts.start();
|
2021-09-09 16:38:38 +02:00
|
|
|
} catch (error) {
|
|
|
|
CoreDomUtils.showErrorModal(error);
|
|
|
|
|
|
|
|
CoreNavigator.back();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2021-04-22 15:19:15 +02:00
|
|
|
|
|
|
|
this.fetchData();
|
|
|
|
}
|
|
|
|
|
2021-12-09 13:47:36 +01:00
|
|
|
/**
|
|
|
|
* @inheritdoc
|
|
|
|
*/
|
|
|
|
ngOnDestroy(): void {
|
2021-12-09 15:19:37 +01:00
|
|
|
this.attempts.destroy();
|
2021-12-09 13:47:36 +01:00
|
|
|
}
|
|
|
|
|
2021-04-22 15:19:15 +02:00
|
|
|
/**
|
|
|
|
* Fetch all the data required for the view.
|
|
|
|
*
|
2022-12-01 12:31:00 +01:00
|
|
|
* @returns Promise resolved when done.
|
2021-04-22 15:19:15 +02:00
|
|
|
*/
|
|
|
|
protected async fetchData(): Promise<void> {
|
|
|
|
try {
|
|
|
|
this.feedback = await AddonModFeedback.getFeedback(this.courseId, this.cmId);
|
|
|
|
|
2023-09-13 12:35:59 +02:00
|
|
|
const attempt = await AddonModFeedback.getAttempt(this.feedback.id, this.attemptId, {
|
|
|
|
cmId: this.cmId,
|
|
|
|
groupId: this.groupId,
|
|
|
|
});
|
2021-04-22 15:19:15 +02:00
|
|
|
|
|
|
|
if (this.isAnonAttempt(attempt)) {
|
|
|
|
this.anonAttempt = attempt;
|
|
|
|
delete this.attempt;
|
|
|
|
} else {
|
2023-05-11 12:19:16 +02:00
|
|
|
this.attempt = (await AddonModFeedbackHelper.addImageProfile([attempt]))[0];
|
2021-04-22 15:19:15 +02:00
|
|
|
delete this.anonAttempt;
|
|
|
|
}
|
|
|
|
|
|
|
|
const items = await AddonModFeedback.getItems(this.feedback.id, { cmId: this.cmId });
|
|
|
|
|
|
|
|
// Add responses and format items.
|
|
|
|
this.items = <AddonModFeedbackAttemptItem[]> items.items.map((item) => {
|
|
|
|
const formItem = AddonModFeedbackHelper.getItemForm(item, true);
|
|
|
|
if (!formItem) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const attemptItem = <AddonModFeedbackAttemptItem> formItem;
|
|
|
|
|
|
|
|
if (item.typ == 'label') {
|
|
|
|
attemptItem.submittedValue = CoreTextUtils.replacePluginfileUrls(item.presentation, item.itemfiles);
|
|
|
|
} else {
|
|
|
|
for (const x in attempt.responses) {
|
|
|
|
if (attempt.responses[x].id == item.id) {
|
|
|
|
attemptItem.submittedValue = attempt.responses[x].printval;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return attemptItem;
|
|
|
|
}).filter((itemData) => itemData); // Filter items with errors.
|
2023-06-22 11:09:33 +02:00
|
|
|
|
|
|
|
this.logView();
|
2021-04-22 15:19:15 +02:00
|
|
|
} catch (message) {
|
|
|
|
// Some call failed on fetch, go back.
|
|
|
|
CoreDomUtils.showErrorModalDefault(message, 'core.course.errorgetmodule', true);
|
|
|
|
CoreNavigator.back();
|
|
|
|
} finally {
|
|
|
|
this.loaded = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if an attempt is anonymous or not.
|
|
|
|
*
|
|
|
|
* @param attempt Attempt to check.
|
2022-12-01 12:31:00 +01:00
|
|
|
* @returns If attempt is anonymous.
|
2021-04-22 15:19:15 +02:00
|
|
|
*/
|
2023-05-11 12:19:16 +02:00
|
|
|
isAnonAttempt(attempt: AddonModFeedbackAttempt | AddonModFeedbackWSAnonAttempt): attempt is AddonModFeedbackWSAnonAttempt {
|
2021-04-22 15:19:15 +02:00
|
|
|
return !('fullname' in attempt);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
type AddonModFeedbackAttemptItem = AddonModFeedbackFormItem & {
|
|
|
|
submittedValue?: string;
|
|
|
|
};
|
2021-12-09 13:47:36 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper to manage swiping within a collection of discussions.
|
|
|
|
*/
|
|
|
|
class AddonModFeedbackAttemptsSwipeManager extends CoreSwipeNavigationItemsManager {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @inheritdoc
|
|
|
|
*/
|
2024-01-11 15:33:14 +01:00
|
|
|
protected getSelectedItemPathFromRoute(route: ActivatedRouteSnapshot | ActivatedRoute): string | null {
|
|
|
|
const snapshot = route instanceof ActivatedRouteSnapshot ? route : route.snapshot;
|
|
|
|
|
|
|
|
return snapshot.params.attemptId;
|
2021-12-09 13:47:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|