forked from CIT/Vmeda.Online
		
	Merge pull request #4212 from crazyserver/MOBILE-4616
MOBILE-4616 feedback: Fix tab selection after submit form
This commit is contained in:
		
						commit
						cd848c5879
					
				@ -20,20 +20,13 @@
 | 
			
		||||
        [courseId]="courseId" [hasDataToSync]="hasOffline" (completionChanged)="onCompletionChange()" />
 | 
			
		||||
 | 
			
		||||
    <core-tabs [hideUntil]="tabsReady" [selectedIndex]="firstSelectedTab">
 | 
			
		||||
        <core-tab [title]="'addon.mod_feedback.overview' | translate" id="overview" (ionSelect)="tabChanged('overview')">
 | 
			
		||||
        <core-tab [title]="tabs.overview.label | translate" [id]="tabs.overview.name" (ionSelect)="tabChanged(tabs.overview.name)">
 | 
			
		||||
            <ng-template>
 | 
			
		||||
                <ng-container *ngTemplateOutlet="tabOverview" />
 | 
			
		||||
            </ng-template>
 | 
			
		||||
        </core-tab>
 | 
			
		||||
        <core-tab *ngIf="showAnalysis && access && access.canviewreports" id="analysis" [title]="'addon.mod_feedback.analysis' | translate"
 | 
			
		||||
            (ionSelect)="tabChanged('analysis')">
 | 
			
		||||
            <ng-template>
 | 
			
		||||
                <ng-container *ngTemplateOutlet="tabAnalysis" />
 | 
			
		||||
            </ng-template>
 | 
			
		||||
        </core-tab>
 | 
			
		||||
 | 
			
		||||
        <core-tab *ngIf="showAnalysis && access && !access.canviewreports" id="analysis"
 | 
			
		||||
            [title]="'addon.mod_feedback.completed_feedbacks' | translate" (ionSelect)="tabChanged('analysis')">
 | 
			
		||||
        <core-tab *ngIf="showAnalysis && access" [id]="tabs.analysis.name" [title]="tabs.analysis.label | translate"
 | 
			
		||||
            (ionSelect)="tabChanged(tabs.analysis.name)">
 | 
			
		||||
            <ng-template>
 | 
			
		||||
                <ng-container *ngTemplateOutlet="tabAnalysis" />
 | 
			
		||||
            </ng-template>
 | 
			
		||||
@ -101,7 +94,7 @@
 | 
			
		||||
 | 
			
		||||
<!-- Template to render the overview. -->
 | 
			
		||||
<ng-template #tabOverview>
 | 
			
		||||
    <core-loading [hideUntil]="tabsLoaded.overview">
 | 
			
		||||
    <core-loading [hideUntil]="tabs.overview.loaded">
 | 
			
		||||
        <ng-container *ngTemplateOutlet="basicInfo" />
 | 
			
		||||
 | 
			
		||||
        <ion-card class="core-info-card" *ngIf="access && access.cancomplete && !access.isopen">
 | 
			
		||||
@ -153,7 +146,7 @@
 | 
			
		||||
 | 
			
		||||
<!-- Template to render the analysis. -->
 | 
			
		||||
<ng-template #tabAnalysis>
 | 
			
		||||
    <core-loading [hideUntil]="tabsLoaded.analysis">
 | 
			
		||||
    <core-loading [hideUntil]="tabs.analysis.loaded">
 | 
			
		||||
        <ng-container *ngTemplateOutlet="basicInfo" />
 | 
			
		||||
 | 
			
		||||
        <ng-container *ngIf="access && (access.canedititems || !access.isempty)">
 | 
			
		||||
 | 
			
		||||
@ -38,7 +38,12 @@ import {
 | 
			
		||||
    AddonModFeedbackSyncResult,
 | 
			
		||||
} from '../../services/feedback-sync';
 | 
			
		||||
import { AddonModFeedbackPrefetchHandler } from '../../services/handlers/prefetch';
 | 
			
		||||
import { ADDON_MOD_FEEDBACK_COMPONENT, ADDON_MOD_FEEDBACK_FORM_SUBMITTED, ADDON_MOD_FEEDBACK_PAGE_NAME } from '../../constants';
 | 
			
		||||
import {
 | 
			
		||||
    ADDON_MOD_FEEDBACK_COMPONENT,
 | 
			
		||||
    ADDON_MOD_FEEDBACK_FORM_SUBMITTED,
 | 
			
		||||
    ADDON_MOD_FEEDBACK_PAGE_NAME,
 | 
			
		||||
    AddonModFeedbackIndexTabName,
 | 
			
		||||
} from '../../constants';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component that displays a feedback index page.
 | 
			
		||||
@ -51,7 +56,7 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
 | 
			
		||||
    @ViewChild(CoreTabsComponent) tabsComponent?: CoreTabsComponent;
 | 
			
		||||
 | 
			
		||||
    @Input() tab = 'overview';
 | 
			
		||||
    @Input() selectedTab: AddonModFeedbackIndexTabName = AddonModFeedbackIndexTabName.OVERVIEW;
 | 
			
		||||
    @Input() group = 0;
 | 
			
		||||
 | 
			
		||||
    component = ADDON_MOD_FEEDBACK_COMPONENT;
 | 
			
		||||
@ -75,9 +80,9 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
        closeTimeReadable: '',
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    tabsLoaded = {
 | 
			
		||||
        overview: false,
 | 
			
		||||
        analysis: false,
 | 
			
		||||
    tabs = {
 | 
			
		||||
        overview: { name: AddonModFeedbackIndexTabName.OVERVIEW, label: 'addon.mod_feedback.overview', loaded: false },
 | 
			
		||||
        analysis: { name: AddonModFeedbackIndexTabName.ANALYSIS, label: 'addon.mod_feedback.analysis', loaded: false },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    protected submitObserver: CoreEventObserver;
 | 
			
		||||
@ -92,12 +97,12 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
 | 
			
		||||
        // Listen for form submit events.
 | 
			
		||||
        this.submitObserver = CoreEvents.on(ADDON_MOD_FEEDBACK_FORM_SUBMITTED, async (data) => {
 | 
			
		||||
            if (!this.feedback || data.feedbackId != this.feedback.id) {
 | 
			
		||||
            if (!this.feedback || data.feedbackId !== this.feedback.id) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.tabsLoaded.analysis = false;
 | 
			
		||||
            this.tabsLoaded.overview = false;
 | 
			
		||||
            this.tabs.analysis.loaded = false;
 | 
			
		||||
            this.tabs.overview.loaded = false;
 | 
			
		||||
            this.showLoading = true;
 | 
			
		||||
 | 
			
		||||
            // Prefetch data if needed.
 | 
			
		||||
@ -110,7 +115,7 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Load the right tab.
 | 
			
		||||
            if (data.tab != this.tab) {
 | 
			
		||||
            if (data.tab !== this.selectedTab) {
 | 
			
		||||
                this.tabChanged(data.tab);
 | 
			
		||||
            } else {
 | 
			
		||||
                this.loadContent(true);
 | 
			
		||||
@ -149,7 +154,9 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
     */
 | 
			
		||||
    protected callAnalyticsLogEvent(): void {
 | 
			
		||||
        this.analyticsLogEvent('mod_feedback_view_feedback', {
 | 
			
		||||
            url: this.tab === 'analysis' ? `/mod/feedback/analysis.php?id=${this.module.id}` : undefined,
 | 
			
		||||
            url: this.selectedTab === AddonModFeedbackIndexTabName.ANALYSIS
 | 
			
		||||
                ? `/mod/feedback/analysis.php?id=${this.module.id}`
 | 
			
		||||
                : undefined,
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -168,8 +175,8 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
            promises.push(AddonModFeedback.invalidateResumePageData(this.feedback.id));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.tabsLoaded.analysis = false;
 | 
			
		||||
        this.tabsLoaded.overview = false;
 | 
			
		||||
        this.tabs.analysis.loaded = false;
 | 
			
		||||
        this.tabs.overview.loaded = false;
 | 
			
		||||
 | 
			
		||||
        await Promise.all(promises);
 | 
			
		||||
    }
 | 
			
		||||
@ -178,7 +185,7 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected isRefreshSyncNeeded(syncEventData: AddonModFeedbackAutoSyncData): boolean {
 | 
			
		||||
        if (this.feedback && syncEventData.feedbackId == this.feedback.id) {
 | 
			
		||||
        if (syncEventData.feedbackId === this.feedback?.id) {
 | 
			
		||||
            // Refresh the data.
 | 
			
		||||
            this.content?.scrollToTop();
 | 
			
		||||
 | 
			
		||||
@ -207,12 +214,17 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
            this.access = await AddonModFeedback.getFeedbackAccessInformation(this.feedback.id, { cmId: this.module.id });
 | 
			
		||||
 | 
			
		||||
            this.showAnalysis = (this.access.canviewreports || this.access.canviewanalysis) && !this.access.isempty;
 | 
			
		||||
 | 
			
		||||
            this.tabs.analysis.label = this.access.canviewreports
 | 
			
		||||
                ? 'addon.mod_feedback.analysis'
 | 
			
		||||
                : 'addon.mod_feedback.completed_feedbacks';
 | 
			
		||||
 | 
			
		||||
            this.firstSelectedTab = 0;
 | 
			
		||||
            if (!this.showAnalysis) {
 | 
			
		||||
                this.tab = 'overview';
 | 
			
		||||
                this.selectedTab = AddonModFeedbackIndexTabName.OVERVIEW;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (this.tab == 'analysis') {
 | 
			
		||||
            if (this.selectedTab === AddonModFeedbackIndexTabName.ANALYSIS) {
 | 
			
		||||
                this.firstSelectedTab = 1;
 | 
			
		||||
 | 
			
		||||
                return await this.fetchFeedbackAnalysisData();
 | 
			
		||||
@ -227,34 +239,36 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
 | 
			
		||||
            if (this.tabsReady) {
 | 
			
		||||
                // Make sure the right tab is selected.
 | 
			
		||||
                this.tabsComponent?.selectTab(this.tab || 'overview');
 | 
			
		||||
                this.tabsComponent?.selectTab(this.selectedTab ?? AddonModFeedbackIndexTabName.OVERVIEW);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convenience function to get feedback overview data.
 | 
			
		||||
     *
 | 
			
		||||
     * @returns Resolved when done.
 | 
			
		||||
     */
 | 
			
		||||
    protected async fetchFeedbackOverviewData(): Promise<void> {
 | 
			
		||||
        if (!this.access || !this.feedback) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const promises: Promise<void>[] = [];
 | 
			
		||||
 | 
			
		||||
        if (this.access!.cancomplete && this.access!.cansubmit && this.access!.isopen) {
 | 
			
		||||
            promises.push(AddonModFeedback.getResumePage(this.feedback!.id, { cmId: this.module.id }).then((goPage) => {
 | 
			
		||||
        if (this.access.cancomplete && this.access.cansubmit && this.access.isopen) {
 | 
			
		||||
            promises.push(AddonModFeedback.getResumePage(this.feedback.id, { cmId: this.module.id }).then((goPage) => {
 | 
			
		||||
                this.goPage = goPage > 0 ? goPage : undefined;
 | 
			
		||||
 | 
			
		||||
                return;
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.access!.canedititems) {
 | 
			
		||||
            this.overview.timeopen = (this.feedback!.timeopen || 0) * 1000;
 | 
			
		||||
        if (this.access.canedititems) {
 | 
			
		||||
            this.overview.timeopen = (this.feedback.timeopen || 0) * 1000;
 | 
			
		||||
            this.overview.openTimeReadable = this.overview.timeopen ? CoreTimeUtils.userDate(this.overview.timeopen) : '';
 | 
			
		||||
            this.overview.timeclose = (this.feedback!.timeclose || 0) * 1000;
 | 
			
		||||
            this.overview.timeclose = (this.feedback.timeclose || 0) * 1000;
 | 
			
		||||
            this.overview.closeTimeReadable = this.overview.timeclose ? CoreTimeUtils.userDate(this.overview.timeclose) : '';
 | 
			
		||||
        }
 | 
			
		||||
        if (this.access!.canviewanalysis) {
 | 
			
		||||
        if (this.access.canviewanalysis) {
 | 
			
		||||
            // Get groups (only for teachers).
 | 
			
		||||
            promises.push(this.fetchGroupInfo(this.module.id));
 | 
			
		||||
        }
 | 
			
		||||
@ -262,7 +276,7 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
        try {
 | 
			
		||||
            await Promise.all(promises);
 | 
			
		||||
        } finally {
 | 
			
		||||
            this.tabsLoaded.overview = true;
 | 
			
		||||
            this.tabs.overview.loaded = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -273,15 +287,14 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
     */
 | 
			
		||||
    protected async fetchFeedbackAnalysisData(): Promise<void> {
 | 
			
		||||
        try {
 | 
			
		||||
            if (this.access!.canviewanalysis) {
 | 
			
		||||
            if (this.access?.canviewanalysis) {
 | 
			
		||||
                // Get groups (only for teachers).
 | 
			
		||||
                await this.fetchGroupInfo(this.module.id);
 | 
			
		||||
            } else {
 | 
			
		||||
                this.tabChanged('overview');
 | 
			
		||||
                this.tabChanged(AddonModFeedbackIndexTabName.OVERVIEW);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            this.tabsLoaded.analysis = true;
 | 
			
		||||
            this.tabs.analysis.loaded = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -419,7 +432,7 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
     * Open attempts page.
 | 
			
		||||
     */
 | 
			
		||||
    openAttempts(): void {
 | 
			
		||||
        if (!this.access!.canviewreports || this.completedCount <= 0) {
 | 
			
		||||
        if (!this.access || !this.access.canviewreports || this.completedCount <= 0) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -438,11 +451,11 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
     *
 | 
			
		||||
     * @param tabName New tab name.
 | 
			
		||||
     */
 | 
			
		||||
    tabChanged(tabName: string): void {
 | 
			
		||||
        const tabHasChanged = this.tab !== undefined && this.tab !== tabName;
 | 
			
		||||
        this.tab = tabName;
 | 
			
		||||
    tabChanged(tabName: AddonModFeedbackIndexTabName): void {
 | 
			
		||||
        const tabHasChanged = this.selectedTab !== undefined && this.selectedTab !== tabName;
 | 
			
		||||
        this.selectedTab = tabName;
 | 
			
		||||
 | 
			
		||||
        if (!this.tabsLoaded[this.tab]) {
 | 
			
		||||
        if (!this.tabs[this.selectedTab].loaded) {
 | 
			
		||||
            this.loadContent(false, false, true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -455,17 +468,20 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
     * Set group to see the analysis.
 | 
			
		||||
     *
 | 
			
		||||
     * @param groupId Group ID.
 | 
			
		||||
     * @returns Resolved when done.
 | 
			
		||||
     */
 | 
			
		||||
    async setGroup(groupId: number): Promise<void> {
 | 
			
		||||
        if (!this.feedback) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.group = groupId;
 | 
			
		||||
 | 
			
		||||
        const analysis = await AddonModFeedback.getAnalysis(this.feedback!.id, { groupId, cmId: this.module.id });
 | 
			
		||||
        const analysis = await AddonModFeedback.getAnalysis(this.feedback.id, { groupId, cmId: this.module.id });
 | 
			
		||||
 | 
			
		||||
        this.completedCount = analysis.completedcount;
 | 
			
		||||
        this.itemsCount = analysis.itemscount;
 | 
			
		||||
 | 
			
		||||
        if (this.tab == 'analysis') {
 | 
			
		||||
        if (this.selectedTab === AddonModFeedbackIndexTabName.ANALYSIS) {
 | 
			
		||||
            let num = 1;
 | 
			
		||||
 | 
			
		||||
            this.items = <AddonModFeedbackItem[]> analysis.itemsdata.map((itemData) => {
 | 
			
		||||
 | 
			
		||||
@ -24,3 +24,11 @@ export const ADDON_MOD_FEEDBACK_MULTICHOICE_HIDENOSELECT = 'h';
 | 
			
		||||
export const ADDON_MOD_FEEDBACK_MULTICHOICERATED_VALUE_SEP = '####';
 | 
			
		||||
 | 
			
		||||
export const ADDON_MOD_FEEDBACK_PER_PAGE = 20;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Index Tabs.
 | 
			
		||||
 */
 | 
			
		||||
export enum AddonModFeedbackIndexTabName {
 | 
			
		||||
    OVERVIEW = 'overview',
 | 
			
		||||
    ANALYSIS = 'analysis',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -36,8 +36,14 @@ import {
 | 
			
		||||
import { AddonModFeedbackFormItem, AddonModFeedbackHelper } from '../../services/feedback-helper';
 | 
			
		||||
import { AddonModFeedbackSync } from '../../services/feedback-sync';
 | 
			
		||||
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
 | 
			
		||||
import { ADDON_MOD_FEEDBACK_COMPONENT, ADDON_MOD_FEEDBACK_FORM_SUBMITTED, ADDON_MOD_FEEDBACK_PAGE_NAME } from '../../constants';
 | 
			
		||||
import {
 | 
			
		||||
    ADDON_MOD_FEEDBACK_COMPONENT,
 | 
			
		||||
    ADDON_MOD_FEEDBACK_FORM_SUBMITTED,
 | 
			
		||||
    ADDON_MOD_FEEDBACK_PAGE_NAME,
 | 
			
		||||
    AddonModFeedbackIndexTabName,
 | 
			
		||||
} from '../../constants';
 | 
			
		||||
import { CoreLoadings } from '@services/loadings';
 | 
			
		||||
import { CoreError } from '@classes/errors/error';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Page that displays feedback form.
 | 
			
		||||
@ -117,14 +123,14 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!this.feedback) {
 | 
			
		||||
        if (!this.feedback || !this.module) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            await AddonModFeedback.logView(this.feedback.id, true);
 | 
			
		||||
 | 
			
		||||
            CoreCourse.checkModuleCompletion(this.courseId, this.module!.completiondata);
 | 
			
		||||
            CoreCourse.checkModuleCompletion(this.courseId, this.module.completiondata);
 | 
			
		||||
        } catch {
 | 
			
		||||
            // Ignore errors.
 | 
			
		||||
        }
 | 
			
		||||
@ -183,7 +189,7 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
 | 
			
		||||
            let page = 0;
 | 
			
		||||
 | 
			
		||||
            if (!this.preview && this.access!.cansubmit && !this.access!.isempty) {
 | 
			
		||||
            if (!this.preview && this.access?.cansubmit && !this.access?.isempty) {
 | 
			
		||||
                page = this.currentPage ?? await this.fetchResumePage(options);
 | 
			
		||||
            } else {
 | 
			
		||||
                this.preview = true;
 | 
			
		||||
@ -203,11 +209,14 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
     * Fetch access information.
 | 
			
		||||
     *
 | 
			
		||||
     * @param options Options.
 | 
			
		||||
     * @returns Promise resolved when done.
 | 
			
		||||
     */
 | 
			
		||||
    protected async fetchAccessData(options: CoreCourseCommonModWSOptions): Promise<void> {
 | 
			
		||||
        if (!this.feedback) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            this.access = await AddonModFeedback.getFeedbackAccessInformation(this.feedback!.id, options);
 | 
			
		||||
            this.access = await AddonModFeedback.getFeedbackAccessInformation(this.feedback.id, options);
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            if (this.offline || CoreUtils.isWebServiceError(error)) {
 | 
			
		||||
                // Already offline or shouldn't go offline, fail.
 | 
			
		||||
@ -218,7 +227,7 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
            this.offline = true;
 | 
			
		||||
            options.readingStrategy = CoreSitesReadingStrategy.PREFER_CACHE;
 | 
			
		||||
 | 
			
		||||
            this.access = await AddonModFeedback.getFeedbackAccessInformation(this.feedback!.id, options);
 | 
			
		||||
            this.access = await AddonModFeedback.getFeedbackAccessInformation(this.feedback.id, options);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -229,8 +238,12 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
     * @returns Promise resolved with the page to resume.
 | 
			
		||||
     */
 | 
			
		||||
    protected async fetchResumePage(options: CoreCourseCommonModWSOptions): Promise<number> {
 | 
			
		||||
        if (!this.feedback) {
 | 
			
		||||
            throw new CoreError('Cannot fetch resume page: missing feedback');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            return await AddonModFeedback.getResumePage(this.feedback!.id, options);
 | 
			
		||||
            return await AddonModFeedback.getResumePage(this.feedback.id, options);
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            if (this.offline || CoreUtils.isWebServiceError(error)) {
 | 
			
		||||
                // Already offline or shouldn't go offline, fail.
 | 
			
		||||
@ -241,7 +254,7 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
            this.offline = true;
 | 
			
		||||
            options.readingStrategy = CoreSitesReadingStrategy.PREFER_CACHE;
 | 
			
		||||
 | 
			
		||||
            return AddonModFeedback.getResumePage(this.feedback!.id, options);
 | 
			
		||||
            return AddonModFeedback.getResumePage(this.feedback.id, options);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -249,7 +262,6 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
     * Fetch page data.
 | 
			
		||||
     *
 | 
			
		||||
     * @param page Page to load.
 | 
			
		||||
     * @returns Promise resolved when done.
 | 
			
		||||
     */
 | 
			
		||||
    protected async fetchFeedbackPageData(page: number = 0): Promise<void> {
 | 
			
		||||
        this.items = [];
 | 
			
		||||
@ -274,6 +286,10 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
     * @returns Promise resolved with WS response.
 | 
			
		||||
     */
 | 
			
		||||
    protected async fetchPageItems(page: number): Promise<AddonModFeedbackPageItems> {
 | 
			
		||||
        if (!this.feedback) {
 | 
			
		||||
            throw new CoreError('Cannot fetch page items: missing feedback');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const options = {
 | 
			
		||||
            cmId: this.cmId,
 | 
			
		||||
            readingStrategy: this.offline ? CoreSitesReadingStrategy.PREFER_CACHE : CoreSitesReadingStrategy.ONLY_NETWORK,
 | 
			
		||||
@ -281,7 +297,7 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if (this.preview) {
 | 
			
		||||
            const response = await AddonModFeedback.getItems(this.feedback!.id, options);
 | 
			
		||||
            const response = await AddonModFeedback.getItems(this.feedback.id, options);
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                items: response.items,
 | 
			
		||||
@ -295,7 +311,7 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
        let response: AddonModFeedbackPageItems;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            response = await AddonModFeedback.getPageItemsWithValues(this.feedback!.id, page, options);
 | 
			
		||||
            response = await AddonModFeedback.getPageItemsWithValues(this.feedback.id, page, options);
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            if (this.offline || CoreUtils.isWebServiceError(error)) {
 | 
			
		||||
                // Already offline or shouldn't go offline, fail.
 | 
			
		||||
@ -306,7 +322,7 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
            this.offline = true;
 | 
			
		||||
            options.readingStrategy = CoreSitesReadingStrategy.PREFER_CACHE;
 | 
			
		||||
 | 
			
		||||
            response = await AddonModFeedback.getPageItemsWithValues(this.feedback!.id, page, options);
 | 
			
		||||
            response = await AddonModFeedback.getPageItemsWithValues(this.feedback.id, page, options);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.hasPrevPage = !!response.hasprevpage;
 | 
			
		||||
@ -319,9 +335,12 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
     * Function to allow page navigation through the questions form.
 | 
			
		||||
     *
 | 
			
		||||
     * @param goPrevious If true it will go back to the previous page, if false, it will go forward.
 | 
			
		||||
     * @returns Resolved when done.
 | 
			
		||||
     */
 | 
			
		||||
    async gotoPage(goPrevious: boolean): Promise<void> {
 | 
			
		||||
        if (!this.feedback || this.currentPage === undefined) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.content?.scrollToTop();
 | 
			
		||||
        this.feedbackLoaded = false;
 | 
			
		||||
 | 
			
		||||
@ -330,9 +349,9 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            // Sync other pages first.
 | 
			
		||||
            await CoreUtils.ignoreErrors(AddonModFeedbackSync.syncFeedback(this.feedback!.id));
 | 
			
		||||
            await CoreUtils.ignoreErrors(AddonModFeedbackSync.syncFeedback(this.feedback.id));
 | 
			
		||||
 | 
			
		||||
            const response = await AddonModFeedback.processPage(this.feedback!.id, this.currentPage!, responses, {
 | 
			
		||||
            const response = await AddonModFeedback.processPage(this.feedback.id, this.currentPage, responses, {
 | 
			
		||||
                goPrevious,
 | 
			
		||||
                formHasErrors,
 | 
			
		||||
                courseId: this.courseId,
 | 
			
		||||
@ -351,14 +370,14 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
 | 
			
		||||
                // Invalidate access information so user will see home page updated (continue form or completion messages).
 | 
			
		||||
                await Promise.all([
 | 
			
		||||
                    AddonModFeedback.invalidateFeedbackAccessInformationData(this.feedback!.id),
 | 
			
		||||
                    AddonModFeedback.invalidateResumePageData(this.feedback!.id),
 | 
			
		||||
                    AddonModFeedback.invalidateFeedbackAccessInformationData(this.feedback.id),
 | 
			
		||||
                    AddonModFeedback.invalidateResumePageData(this.feedback.id),
 | 
			
		||||
                ]);
 | 
			
		||||
 | 
			
		||||
                // If form has been submitted, the info has been already invalidated but we should update index view.
 | 
			
		||||
                CoreEvents.trigger(ADDON_MOD_FEEDBACK_FORM_SUBMITTED, {
 | 
			
		||||
                    feedbackId: this.feedback!.id,
 | 
			
		||||
                    tab: 'overview',
 | 
			
		||||
                    feedbackId: this.feedback.id,
 | 
			
		||||
                    tab: AddonModFeedbackIndexTabName.OVERVIEW,
 | 
			
		||||
                    offline: this.completedOffline,
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
@ -371,11 +390,11 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
                // Errors on questions, stay in page.
 | 
			
		||||
            } else {
 | 
			
		||||
                // Invalidate access information so user will see home page updated (continue form).
 | 
			
		||||
                await AddonModFeedback.invalidateResumePageData(this.feedback!.id);
 | 
			
		||||
                await AddonModFeedback.invalidateResumePageData(this.feedback.id);
 | 
			
		||||
 | 
			
		||||
                CoreEvents.trigger(ADDON_MOD_FEEDBACK_FORM_SUBMITTED, {
 | 
			
		||||
                    feedbackId: this.feedback!.id,
 | 
			
		||||
                    tab: 'overview',
 | 
			
		||||
                    feedbackId: this.feedback.id,
 | 
			
		||||
                    tab: AddonModFeedbackIndexTabName.OVERVIEW,
 | 
			
		||||
                    offline: this.completedOffline,
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
@ -393,11 +412,15 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
     * Function to link implemented features.
 | 
			
		||||
     */
 | 
			
		||||
    showAnalysis(): void {
 | 
			
		||||
        if (!this.feedback) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.fromIndex) {
 | 
			
		||||
            // Previous page is the index page, go back.
 | 
			
		||||
            CoreEvents.trigger(ADDON_MOD_FEEDBACK_FORM_SUBMITTED, {
 | 
			
		||||
                feedbackId: this.feedback!.id,
 | 
			
		||||
                tab: 'analysis',
 | 
			
		||||
                feedbackId: this.feedback.id,
 | 
			
		||||
                tab: AddonModFeedbackIndexTabName.ANALYSIS,
 | 
			
		||||
                offline: this.completedOffline,
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
@ -409,7 +432,7 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
        CoreNavigator.navigateToSitePath(ADDON_MOD_FEEDBACK_PAGE_NAME + `/${this.courseId}/${this.cmId}`, {
 | 
			
		||||
            params: {
 | 
			
		||||
                module: this.module,
 | 
			
		||||
                tab: 'analysis',
 | 
			
		||||
                tab: AddonModFeedbackIndexTabName.ANALYSIS,
 | 
			
		||||
            },
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,6 @@
 | 
			
		||||
        <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}" />
 | 
			
		||||
    </ion-refresher>
 | 
			
		||||
 | 
			
		||||
    <addon-mod-feedback-index [module]="module" [courseId]="courseId" [group]="selectedGroup" [tab]="selectedTab"
 | 
			
		||||
    <addon-mod-feedback-index [module]="module" [courseId]="courseId" [group]="selectedGroup" [selectedTab]="selectedTab"
 | 
			
		||||
        (dataRetrieved)="updateData($event)" />
 | 
			
		||||
</ion-content>
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@ import { Component, OnInit, ViewChild } from '@angular/core';
 | 
			
		||||
import { CoreCourseModuleMainActivityPage } from '@features/course/classes/main-activity-page';
 | 
			
		||||
import { CoreNavigator } from '@services/navigator';
 | 
			
		||||
import { AddonModFeedbackIndexComponent } from '../../components/index/index';
 | 
			
		||||
import { AddonModFeedbackIndexTabName } from '../../constants';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Page that displays a feedback.
 | 
			
		||||
@ -28,7 +29,7 @@ export class AddonModFeedbackIndexPage extends CoreCourseModuleMainActivityPage<
 | 
			
		||||
 | 
			
		||||
    @ViewChild(AddonModFeedbackIndexComponent) activityComponent?: AddonModFeedbackIndexComponent;
 | 
			
		||||
 | 
			
		||||
    selectedTab?: string;
 | 
			
		||||
    selectedTab?: AddonModFeedbackIndexTabName;
 | 
			
		||||
    selectedGroup?: number;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -34,6 +34,7 @@ import {
 | 
			
		||||
    ADDON_MOD_FEEDBACK_MULTICHOICE_TYPE_SEP,
 | 
			
		||||
    ADDON_MOD_FEEDBACK_MULTICHOICERATED_VALUE_SEP,
 | 
			
		||||
    ADDON_MOD_FEEDBACK_PER_PAGE,
 | 
			
		||||
    AddonModFeedbackIndexTabName,
 | 
			
		||||
} from '../constants';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -1263,7 +1264,7 @@ declare module '@singletons/events' {
 | 
			
		||||
 */
 | 
			
		||||
export type AddonModFeedbackFormSubmittedData = {
 | 
			
		||||
    feedbackId: number;
 | 
			
		||||
    tab: string;
 | 
			
		||||
    tab: AddonModFeedbackIndexTabName;
 | 
			
		||||
    offline: boolean;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,7 @@ import { CoreCourse } from '@features/course/services/course';
 | 
			
		||||
import { CoreNavigator } from '@services/navigator';
 | 
			
		||||
import { CoreDomUtils } from '@services/utils/dom';
 | 
			
		||||
import { makeSingleton } from '@singletons';
 | 
			
		||||
import { ADDON_MOD_FEEDBACK_PAGE_NAME } from '../../constants';
 | 
			
		||||
import { ADDON_MOD_FEEDBACK_PAGE_NAME, AddonModFeedbackIndexTabName } from '../../constants';
 | 
			
		||||
import { CoreLoadings } from '@services/loadings';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -59,7 +59,7 @@ export class AddonModFeedbackAnalysisLinkHandlerService extends CoreContentLinks
 | 
			
		||||
                        {
 | 
			
		||||
                            params: {
 | 
			
		||||
                                module,
 | 
			
		||||
                                tab: 'analysis',
 | 
			
		||||
                                tab: AddonModFeedbackIndexTabName.ANALYSIS,
 | 
			
		||||
                            },
 | 
			
		||||
                            siteId,
 | 
			
		||||
                        },
 | 
			
		||||
 | 
			
		||||
@ -221,7 +221,7 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements AfterViewIn
 | 
			
		||||
        this.swiper.update();
 | 
			
		||||
        await CoreWait.nextTick();
 | 
			
		||||
 | 
			
		||||
        if (!this.hasSliddenToInitial && this.selectedIndex && this.selectedIndex >= this.swiper.slidesPerViewDynamic()) {
 | 
			
		||||
        if (!this.hasSliddenToInitial && this.selectedIndex >= this.swiper.slidesPerViewDynamic()) {
 | 
			
		||||
            this.hasSliddenToInitial = true;
 | 
			
		||||
            this.shouldSlideToInitial = true;
 | 
			
		||||
 | 
			
		||||
@ -233,7 +233,7 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements AfterViewIn
 | 
			
		||||
            }, 400);
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        } else if (this.selectedIndex) {
 | 
			
		||||
        } else {
 | 
			
		||||
            this.hasSliddenToInitial = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -301,21 +301,21 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements AfterViewIn
 | 
			
		||||
     * @returns Initial tab, undefined if no valid tab found.
 | 
			
		||||
     */
 | 
			
		||||
    protected calculateInitialTab(): T | undefined {
 | 
			
		||||
        const selectedTab: T | undefined = this.tabs[this.selectedIndex || 0] || undefined;
 | 
			
		||||
        const selectedTab: T | undefined = this.tabs[this.selectedIndex] || undefined;
 | 
			
		||||
 | 
			
		||||
        if (selectedTab && selectedTab.enabled) {
 | 
			
		||||
        if (selectedTab?.enabled) {
 | 
			
		||||
            return selectedTab;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // The tab is not enabled or not shown. Get the first tab that is enabled.
 | 
			
		||||
        return this.tabs.find((tab) => tab.enabled) || undefined;
 | 
			
		||||
        return this.tabs.find((tab) => tab.enabled);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method executed when the slides are changed.
 | 
			
		||||
     */
 | 
			
		||||
    slideChanged(): void {
 | 
			
		||||
        if (!this.swiper) {
 | 
			
		||||
        if (!this.swiper || this.swiper.destroyed) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -340,7 +340,7 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements AfterViewIn
 | 
			
		||||
     * Calculate the number of slides that can fit on the screen.
 | 
			
		||||
     */
 | 
			
		||||
    protected async calculateMaxSlides(): Promise<void> {
 | 
			
		||||
        if (!this.swiper) {
 | 
			
		||||
        if (!this.swiper || this.swiper.destroyed) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -456,7 +456,7 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements AfterViewIn
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.selected && this.swiper) {
 | 
			
		||||
        if (this.selected && this.swiper && !this.swiper.destroyed) {
 | 
			
		||||
            // Check if we need to slide to the tab because it's not visible.
 | 
			
		||||
            const firstVisibleTab = this.swiper.activeIndex;
 | 
			
		||||
            const lastVisibleTab = firstVisibleTab + this.swiper.slidesPerViewDynamic() - 1;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user