MOBILE-3109 survey: Add return types to survey
parent
a2fbe1c808
commit
a779e69b49
|
@ -36,14 +36,14 @@
|
|||
|
||||
<ng-container *ngFor="let question of questions; let index=index; let isEven=even;">
|
||||
<!-- Parent question (Category header) -->
|
||||
<div *ngIf="question.multi && question.multi.length" [attr.padding-top]="index == 1">
|
||||
<div *ngIf="question.multiArray && question.multiArray.length" [attr.padding-top]="index == 1">
|
||||
<h3 padding-horizontal>{{ question.text }}</h3>
|
||||
<ion-grid no-padding>
|
||||
<ion-row no-padding align-items-center class="hidden-phone">
|
||||
<ion-col col-7>
|
||||
<div padding>{{ 'addon.mod_survey.responses' | translate }}</div>
|
||||
</ion-col>
|
||||
<ion-col text-center *ngFor="let option of question.options">
|
||||
<ion-col text-center *ngFor="let option of question.optionsArray">
|
||||
<div padding>{{ option }}</div>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
@ -61,20 +61,20 @@
|
|||
</ion-col>
|
||||
|
||||
<!-- Tablet view: radio buttons -->
|
||||
<ion-col class="hidden-phone" text-center *ngFor="let option of question.options; let value=index;">
|
||||
<ion-col class="hidden-phone" text-center *ngFor="let option of question.optionsArray; let value=index;">
|
||||
<ion-radio [value]="value + 1" [attr.aria-labelledby]="'addon-mod_survey-'+question.name"></ion-radio>
|
||||
</ion-col>
|
||||
<ion-col class="hidden-tablet">
|
||||
<ion-select padding [(ngModel)]="answers[question.name]" [attr.aria-labelledby]="'addon-mod_survey-'+question.name" interface="action-sheet" [required]="question.required">
|
||||
<ion-option value="-1" selected disabled>{{ 'core.choose' | translate }}</ion-option>
|
||||
<ion-option *ngFor="let option of question.options; let value=index;" [value]="value +1">{{option}}</ion-option>
|
||||
<ion-option *ngFor="let option of question.optionsArray; let value=index;" [value]="value +1">{{option}}</ion-option>
|
||||
</ion-select>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
|
||||
<!-- Single question (don't belong to a category) -->
|
||||
<ng-container *ngIf="(!question.multi || question.multi.length == 0) && question.parent === 0">
|
||||
<ng-container *ngIf="(!question.multiArray || question.multiArray.length == 0) && question.parent === 0">
|
||||
<ion-grid no-padding text-wrap *ngIf="question.type > 0" [class.even]="isEven">
|
||||
<ion-row no-padding align-items-center>
|
||||
<ion-col col-7>
|
||||
|
@ -82,7 +82,7 @@
|
|||
</ion-col>
|
||||
<ion-col col-5>
|
||||
<ion-select padding [(ngModel)]="answers[question.name]" [attr.aria-labelledby]="'addon-mod_survey-'+question.name" interface="action-sheet" [required]="question.required">
|
||||
<ion-option *ngFor="let option of question.options; let value=index;" [value]="value">{{option}}</ion-option>
|
||||
<ion-option *ngFor="let option of question.optionsArray; let value=index;" [value]="value">{{option}}</ion-option>
|
||||
</ion-select>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
import { Component, Optional, Injector } from '@angular/core';
|
||||
import { Content } from 'ionic-angular';
|
||||
import { CoreCourseModuleMainActivityComponent } from '@core/course/classes/main-activity-component';
|
||||
import { AddonModSurveyProvider } from '../../providers/survey';
|
||||
import { AddonModSurveyHelperProvider } from '../../providers/helper';
|
||||
import { AddonModSurveyProvider, AddonModSurveySurvey } from '../../providers/survey';
|
||||
import { AddonModSurveyHelperProvider, AddonModSurveyQuestionFormatted } from '../../providers/helper';
|
||||
import { AddonModSurveyOfflineProvider } from '../../providers/offline';
|
||||
import { AddonModSurveySyncProvider } from '../../providers/sync';
|
||||
|
||||
|
@ -31,8 +31,8 @@ export class AddonModSurveyIndexComponent extends CoreCourseModuleMainActivityCo
|
|||
component = AddonModSurveyProvider.COMPONENT;
|
||||
moduleName = 'survey';
|
||||
|
||||
survey: any;
|
||||
questions: any;
|
||||
survey: AddonModSurveySurvey;
|
||||
questions: AddonModSurveyQuestionFormatted[];
|
||||
answers = {};
|
||||
|
||||
protected userId: number;
|
||||
|
@ -103,7 +103,7 @@ export class AddonModSurveyIndexComponent extends CoreCourseModuleMainActivityCo
|
|||
return this.surveyProvider.getSurvey(this.courseId, this.module.id).then((survey) => {
|
||||
this.survey = survey;
|
||||
|
||||
this.description = survey.intro || survey.description;
|
||||
this.description = survey.intro;
|
||||
this.dataRetrieved.emit(survey);
|
||||
|
||||
if (sync) {
|
||||
|
@ -144,13 +144,13 @@ export class AddonModSurveyIndexComponent extends CoreCourseModuleMainActivityCo
|
|||
// Init answers object.
|
||||
this.questions.forEach((q) => {
|
||||
if (q.name) {
|
||||
const isTextArea = q.multi && q.multi.length === 0 && q.type === 0;
|
||||
const isTextArea = q.multiArray && q.multiArray.length === 0 && q.type === 0;
|
||||
this.answers[q.name] = q.required ? -1 : (isTextArea ? '' : '0');
|
||||
}
|
||||
|
||||
if (q.multi && !q.multi.length && q.parent === 0 && q.type > 0) {
|
||||
if (q.multiArray && !q.multiArray.length && q.parent === 0 && q.type > 0) {
|
||||
// Options shown in a select. Remove all HTML.
|
||||
q.options = q.options.map((option) => {
|
||||
q.optionsArray = q.optionsArray.map((option) => {
|
||||
return this.textUtils.cleanTags(option);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonModSurveyQuestion } from './survey';
|
||||
|
||||
/**
|
||||
* Service that provides helper functions for surveys.
|
||||
|
@ -29,7 +30,7 @@ export class AddonModSurveyHelperProvider {
|
|||
* @param value Value to convert.
|
||||
* @return Array.
|
||||
*/
|
||||
protected commaStringToArray(value: any): string[] {
|
||||
protected commaStringToArray(value: string | string[]): string[] {
|
||||
if (typeof value == 'string') {
|
||||
if (value.length > 0) {
|
||||
return value.split(',');
|
||||
|
@ -47,7 +48,7 @@ export class AddonModSurveyHelperProvider {
|
|||
* @param questions Questions.
|
||||
* @return Object with parent questions.
|
||||
*/
|
||||
protected getParentQuestions(questions: any[]): any {
|
||||
protected getParentQuestions(questions: AddonModSurveyQuestion[]): {[id: number]: AddonModSurveyQuestion} {
|
||||
const parents = {};
|
||||
|
||||
questions.forEach((question) => {
|
||||
|
@ -66,24 +67,24 @@ export class AddonModSurveyHelperProvider {
|
|||
* @param questions Questions.
|
||||
* @return Promise resolved with the formatted questions.
|
||||
*/
|
||||
formatQuestions(questions: any[]): any[] {
|
||||
formatQuestions(questions: AddonModSurveyQuestion[]): AddonModSurveyQuestionFormatted[] {
|
||||
|
||||
const strIPreferThat = this.translate.instant('addon.mod_survey.ipreferthat'),
|
||||
strIFoundThat = this.translate.instant('addon.mod_survey.ifoundthat'),
|
||||
strChoose = this.translate.instant('core.choose'),
|
||||
formatted = [],
|
||||
formatted: AddonModSurveyQuestionFormatted[] = [],
|
||||
parents = this.getParentQuestions(questions);
|
||||
|
||||
let num = 1;
|
||||
|
||||
questions.forEach((question) => {
|
||||
// Copy the object to prevent modifying the original.
|
||||
const q1 = Object.assign({}, question),
|
||||
const q1: AddonModSurveyQuestionFormatted = Object.assign({}, question),
|
||||
parent = parents[q1.parent];
|
||||
|
||||
// Turn multi and options into arrays.
|
||||
q1.multi = this.commaStringToArray(q1.multi);
|
||||
q1.options = this.commaStringToArray(q1.options);
|
||||
q1.multiArray = this.commaStringToArray(q1.multi);
|
||||
q1.optionsArray = this.commaStringToArray(q1.options);
|
||||
|
||||
if (parent) {
|
||||
// It's a sub-question.
|
||||
|
@ -114,7 +115,7 @@ export class AddonModSurveyHelperProvider {
|
|||
q1.name = 'q' + q1.id;
|
||||
q1.num = num++;
|
||||
if (q1.type > 0) { // Add "choose" option since this question is not required.
|
||||
q1.options.unshift(strChoose);
|
||||
q1.optionsArray.unshift(strChoose);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,5 +124,15 @@ export class AddonModSurveyHelperProvider {
|
|||
|
||||
return formatted;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Survey question with some calculated data.
|
||||
*/
|
||||
export type AddonModSurveyQuestionFormatted = AddonModSurveyQuestion & {
|
||||
required?: boolean; // Calculated in the app. Whether the question is required.
|
||||
name?: string; // Calculated in the app. The name of the question.
|
||||
num?: number; // Calculated in the app. Number of the question.
|
||||
multiArray?: string[]; // Subquestions ids, converted to an array.
|
||||
optionsArray?: string[]; // Question options, converted to an array.
|
||||
};
|
||||
|
|
|
@ -21,6 +21,7 @@ import { CoreFilepoolProvider } from '@providers/filepool';
|
|||
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
|
||||
import { AddonModSurveyOfflineProvider } from './offline';
|
||||
import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
|
||||
import { CoreWSExternalWarning, CoreWSExternalFile } from '@providers/ws';
|
||||
|
||||
/**
|
||||
* Service that provides some features for surveys.
|
||||
|
@ -46,7 +47,7 @@ export class AddonModSurveyProvider {
|
|||
* @param siteId Site ID. If not defined, current site.
|
||||
* @return Promise resolved when the questions are retrieved.
|
||||
*/
|
||||
getQuestions(surveyId: number, ignoreCache?: boolean, siteId?: string): Promise<any> {
|
||||
getQuestions(surveyId: number, ignoreCache?: boolean, siteId?: string): Promise<AddonModSurveyQuestion[]> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
const params = {
|
||||
surveyid: surveyId
|
||||
|
@ -61,7 +62,9 @@ export class AddonModSurveyProvider {
|
|||
preSets.emergencyCache = false;
|
||||
}
|
||||
|
||||
return site.read('mod_survey_get_questions', params, preSets).then((response) => {
|
||||
return site.read('mod_survey_get_questions', params, preSets)
|
||||
.then((response: AddonModSurveyGetQuestionsResult): any => {
|
||||
|
||||
if (response.questions) {
|
||||
return response.questions;
|
||||
}
|
||||
|
@ -101,7 +104,9 @@ export class AddonModSurveyProvider {
|
|||
* @param siteId Site ID. If not defined, current site.
|
||||
* @return Promise resolved when the survey is retrieved.
|
||||
*/
|
||||
protected getSurveyDataByKey(courseId: number, key: string, value: any, ignoreCache?: boolean, siteId?: string): Promise<any> {
|
||||
protected getSurveyDataByKey(courseId: number, key: string, value: any, ignoreCache?: boolean, siteId?: string)
|
||||
: Promise<AddonModSurveySurvey> {
|
||||
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
const params = {
|
||||
courseids: [courseId]
|
||||
|
@ -116,7 +121,9 @@ export class AddonModSurveyProvider {
|
|||
preSets.emergencyCache = false;
|
||||
}
|
||||
|
||||
return site.read('mod_survey_get_surveys_by_courses', params, preSets).then((response) => {
|
||||
return site.read('mod_survey_get_surveys_by_courses', params, preSets)
|
||||
.then((response: AddonModSurveyGetSurveysByCoursesResult): any => {
|
||||
|
||||
if (response && response.surveys) {
|
||||
const currentSurvey = response.surveys.find((survey) => {
|
||||
return survey[key] == value;
|
||||
|
@ -140,7 +147,7 @@ export class AddonModSurveyProvider {
|
|||
* @param siteId Site ID. If not defined, current site.
|
||||
* @return Promise resolved when the survey is retrieved.
|
||||
*/
|
||||
getSurvey(courseId: number, cmId: number, ignoreCache?: boolean, siteId?: string): Promise<any> {
|
||||
getSurvey(courseId: number, cmId: number, ignoreCache?: boolean, siteId?: string): Promise<AddonModSurveySurvey> {
|
||||
return this.getSurveyDataByKey(courseId, 'coursemodule', cmId, ignoreCache, siteId);
|
||||
}
|
||||
|
||||
|
@ -153,7 +160,7 @@ export class AddonModSurveyProvider {
|
|||
* @param siteId Site ID. If not defined, current site.
|
||||
* @return Promise resolved when the survey is retrieved.
|
||||
*/
|
||||
getSurveyById(courseId: number, id: number, ignoreCache?: boolean, siteId?: string): Promise<any> {
|
||||
getSurveyById(courseId: number, id: number, ignoreCache?: boolean, siteId?: string): Promise<AddonModSurveySurvey> {
|
||||
return this.getSurveyDataByKey(courseId, 'id', id, ignoreCache, siteId);
|
||||
}
|
||||
|
||||
|
@ -277,17 +284,16 @@ export class AddonModSurveyProvider {
|
|||
* @param surveyId Survey ID.
|
||||
* @param answers Answers.
|
||||
* @param siteId Site ID. If not defined, current site.
|
||||
* @return Promise resolved when answers are successfully submitted. Rejected with object containing
|
||||
* the error message (if any) and a boolean indicating if the error was returned by WS.
|
||||
* @return Promise resolved when answers are successfully submitted.
|
||||
*/
|
||||
submitAnswersOnline(surveyId: number, answers: any[], siteId?: string): Promise<any> {
|
||||
submitAnswersOnline(surveyId: number, answers: any[], siteId?: string): Promise<void> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
const params = {
|
||||
surveyid: surveyId,
|
||||
answers: answers
|
||||
};
|
||||
|
||||
return site.write('mod_survey_submit_answers', params).then((response) => {
|
||||
return site.write('mod_survey_submit_answers', params).then((response: AddonModSurveySubmitAnswersResult) => {
|
||||
if (!response.status) {
|
||||
return Promise.reject(this.utils.createFakeWSError(''));
|
||||
}
|
||||
|
@ -295,3 +301,64 @@ export class AddonModSurveyProvider {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Survey returned by WS mod_survey_get_surveys_by_courses.
|
||||
*/
|
||||
export type AddonModSurveySurvey = {
|
||||
id: number; // Survey id.
|
||||
coursemodule: number; // Course module id.
|
||||
course: number; // Course id.
|
||||
name: string; // Survey name.
|
||||
intro?: string; // The Survey intro.
|
||||
introformat?: number; // Intro format (1 = HTML, 0 = MOODLE, 2 = PLAIN or 4 = MARKDOWN).
|
||||
introfiles?: CoreWSExternalFile[]; // @since 3.2.
|
||||
template?: number; // Survey type.
|
||||
days?: number; // Days.
|
||||
questions?: string; // Question ids.
|
||||
surveydone?: number; // Did I finish the survey?.
|
||||
timecreated?: number; // Time of creation.
|
||||
timemodified?: number; // Time of last modification.
|
||||
section?: number; // Course section id.
|
||||
visible?: number; // Visible.
|
||||
groupmode?: number; // Group mode.
|
||||
groupingid?: number; // Group id.
|
||||
};
|
||||
|
||||
/**
|
||||
* Survey question.
|
||||
*/
|
||||
export type AddonModSurveyQuestion = {
|
||||
id: number; // Question id.
|
||||
text: string; // Question text.
|
||||
shorttext: string; // Question short text.
|
||||
multi: string; // Subquestions ids.
|
||||
intro: string; // The question intro.
|
||||
type: number; // Question type.
|
||||
options: string; // Question options.
|
||||
parent: number; // Parent question (for subquestions).
|
||||
};
|
||||
|
||||
/**
|
||||
* Result of WS mod_survey_get_questions.
|
||||
*/
|
||||
export type AddonModSurveyGetQuestionsResult = {
|
||||
questions: AddonModSurveyQuestion[];
|
||||
warnings?: CoreWSExternalWarning[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Result of WS mod_survey_get_surveys_by_courses.
|
||||
*/
|
||||
export type AddonModSurveyGetSurveysByCoursesResult = {
|
||||
surveys: AddonModSurveySurvey[];
|
||||
warnings?: CoreWSExternalWarning[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Result of WS mod_survey_submit_answers.
|
||||
*/
|
||||
export type AddonModSurveySubmitAnswersResult = {
|
||||
status: boolean; // Status: true if success.
|
||||
warnings?: CoreWSExternalWarning[];
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue