forked from EVOgeek/Vmeda.Online
		
	Merge pull request #3618 from NoelDeMartin/MOBILE-4284
MOBILE-4284: Implement custom question numbers in quiz
This commit is contained in:
		
						commit
						9e72d79eba
					
				| @ -18,11 +18,11 @@ | |||||||
|                 (click)="loadPage(question.page, question.slot)" detail="false"> |                 (click)="loadPage(question.page, question.slot)" detail="false"> | ||||||
| 
 | 
 | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <span *ngIf="question.number">{{ 'core.question.questionno' | translate:{$a: question.number} }}</span> |                     <span *ngIf="question.questionnumber">{{ 'core.question.questionno' | translate:{$a: question.questionnumber} }}</span> | ||||||
|                     <span *ngIf="!question.number">{{ 'core.question.information' | translate }}</span> |                     <span *ngIf="!question.questionnumber">{{ 'core.question.information' | translate }}</span> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
| 
 | 
 | ||||||
|                 <ion-icon *ngIf="!question.number" name="fas-circle-info" slot="end" aria-hidden="true"></ion-icon> |                 <ion-icon *ngIf="!question.questionnumber" name="fas-circle-info" slot="end" aria-hidden="true"></ion-icon> | ||||||
|                 <ion-icon *ngIf="question.stateClass == 'core-question-requiresgrading'" name="fas-circle-question" |                 <ion-icon *ngIf="question.stateClass == 'core-question-requiresgrading'" name="fas-circle-question" | ||||||
|                     [attr.aria-label]="question.status" slot="end"> |                     [attr.aria-label]="question.status" slot="end"> | ||||||
|                 </ion-icon> |                 </ion-icon> | ||||||
|  | |||||||
| @ -44,10 +44,10 @@ | |||||||
|                     <!-- "Header" of the question. --> |                     <!-- "Header" of the question. --> | ||||||
|                     <ion-item-divider> |                     <ion-item-divider> | ||||||
|                         <ion-label> |                         <ion-label> | ||||||
|                             <h2 *ngIf="question.number" class="inline"> |                             <h2 *ngIf="question.questionnumber" class="inline"> | ||||||
|                                 {{ 'core.question.questionno' | translate:{$a: question.number} }} |                                 {{ 'core.question.questionno' | translate:{$a: question.questionnumber} }} | ||||||
|                             </h2> |                             </h2> | ||||||
|                             <h2 *ngIf="!question.number" class="inline">{{ 'core.question.information' | translate }}</h2> |                             <h2 *ngIf="!question.questionnumber" class="inline">{{ 'core.question.information' | translate }}</h2> | ||||||
|                         </ion-label> |                         </ion-label> | ||||||
|                         <div *ngIf="question.status || question.readableMark" slot="end" |                         <div *ngIf="question.status || question.readableMark" slot="end" | ||||||
|                             class="ion-text-wrap ion-margin-horizontal addon-mod_quiz-question-note"> |                             class="ion-text-wrap ion-margin-horizontal addon-mod_quiz-question-note"> | ||||||
| @ -108,12 +108,12 @@ | |||||||
| 
 | 
 | ||||||
|             <!-- List of questions of the summary table. --> |             <!-- List of questions of the summary table. --> | ||||||
|             <ng-container *ngFor="let question of summaryQuestions"> |             <ng-container *ngFor="let question of summaryQuestions"> | ||||||
|                 <ion-item *ngIf="question.number" (click)="changePage(question.page, false, question.slot)" |                 <ion-item *ngIf="question.questionnumber" (click)="changePage(question.page, false, question.slot)" | ||||||
|                     [attr.aria-label]="'core.question.questionno' | translate:{$a: question.number}" [detail]="!isSequential && canReturn" |                     [attr.aria-label]="'core.question.questionno' | translate:{$a: question.questionnumber}" | ||||||
|                     [button]="!isSequential && canReturn"> |                     [detail]="!isSequential && canReturn" [button]="!isSequential && canReturn"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <ion-row class="ion-align-items-center"> |                         <ion-row class="ion-align-items-center"> | ||||||
|                             <ion-col size="3" class="ion-text-center">{{ question.number }}</ion-col> |                             <ion-col size="3" class="ion-text-center">{{ question.questionnumber }}</ion-col> | ||||||
|                             <ion-col size="9" class="ion-text-center ion-text-wrap">{{ question.status }}</ion-col> |                             <ion-col size="9" class="ion-text-center ion-text-wrap">{{ question.status }}</ion-col> | ||||||
|                         </ion-row> |                         </ion-row> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|  | |||||||
| @ -86,8 +86,9 @@ | |||||||
|                     <!-- "Header" of the question. --> |                     <!-- "Header" of the question. --> | ||||||
|                     <ion-item-divider> |                     <ion-item-divider> | ||||||
|                         <ion-label> |                         <ion-label> | ||||||
|                             <h2 *ngIf="question.number">{{ 'core.question.questionno' | translate:{$a: question.number} }}</h2> |                             <h2 *ngIf="question.questionnumber">{{ 'core.question.questionno' | translate:{$a: question.questionnumber} }} | ||||||
|                             <h2 *ngIf="!question.number">{{ 'core.question.information' | translate }}</h2> |                             </h2> | ||||||
|  |                             <h2 *ngIf="!question.questionnumber">{{ 'core.question.information' | translate }}</h2> | ||||||
|                         </ion-label> |                         </ion-label> | ||||||
|                         <div class="ion-text-wrap ion-margin-horizontal addon-mod_quiz-question-note" slot="end" |                         <div class="ion-text-wrap ion-margin-horizontal addon-mod_quiz-question-note" slot="end" | ||||||
|                             *ngIf="question.status || question.readableMark"> |                             *ngIf="question.status || question.readableMark"> | ||||||
|  | |||||||
| @ -12,16 +12,17 @@ | |||||||
| // 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 { SQLiteDB } from '@classes/sqlitedb'; | ||||||
| import { CoreSiteSchema } from '@services/sites'; | import { CoreSiteSchema } from '@services/sites'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Database variables for CoreQuestion service. |  * Database variables for CoreQuestion service. | ||||||
|  */ |  */ | ||||||
| export const QUESTION_TABLE_NAME = 'questions'; | export const QUESTION_TABLE_NAME = 'questions_2'; | ||||||
| export const QUESTION_ANSWERS_TABLE_NAME = 'question_answers'; | export const QUESTION_ANSWERS_TABLE_NAME = 'question_answers'; | ||||||
| export const QUESTION_SITE_SCHEMA: CoreSiteSchema = { | export const QUESTION_SITE_SCHEMA: CoreSiteSchema = { | ||||||
|     name: 'CoreQuestionProvider', |     name: 'CoreQuestionProvider', | ||||||
|     version: 1, |     version: 2, | ||||||
|     tables: [ |     tables: [ | ||||||
|         { |         { | ||||||
|             name: QUESTION_TABLE_NAME, |             name: QUESTION_TABLE_NAME, | ||||||
| @ -45,14 +46,6 @@ export const QUESTION_SITE_SCHEMA: CoreSiteSchema = { | |||||||
|                     name: 'componentid', |                     name: 'componentid', | ||||||
|                     type: 'INTEGER', |                     type: 'INTEGER', | ||||||
|                 }, |                 }, | ||||||
|                 { |  | ||||||
|                     name: 'userid', |  | ||||||
|                     type: 'INTEGER', |  | ||||||
|                 }, |  | ||||||
|                 { |  | ||||||
|                     name: 'number', |  | ||||||
|                     type: 'INTEGER', |  | ||||||
|                 }, |  | ||||||
|                 { |                 { | ||||||
|                     name: 'state', |                     name: 'state', | ||||||
|                     type: 'TEXT', |                     type: 'TEXT', | ||||||
| @ -102,6 +95,15 @@ export const QUESTION_SITE_SCHEMA: CoreSiteSchema = { | |||||||
|             primaryKeys: ['component', 'attemptid', 'name'], |             primaryKeys: ['component', 'attemptid', 'name'], | ||||||
|         }, |         }, | ||||||
|     ], |     ], | ||||||
|  |     async migrate(db: SQLiteDB, oldVersion: number): Promise<void> { | ||||||
|  |         if (oldVersion < 2) { | ||||||
|  |             await db.migrateTable( | ||||||
|  |                 'questions', | ||||||
|  |                 QUESTION_TABLE_NAME, | ||||||
|  |                 ({ component, componentid, attemptid, slot, state }) => ({ component, componentid, attemptid, slot, state }), | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -112,8 +114,6 @@ export type CoreQuestionDBRecord = { | |||||||
|     attemptid: number; |     attemptid: number; | ||||||
|     slot: number; |     slot: number; | ||||||
|     componentid: number; |     componentid: number; | ||||||
|     userid: number; |  | ||||||
|     number?: number; // eslint-disable-line id-blacklist
 |  | ||||||
|     state: string; |     state: string; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -637,7 +637,7 @@ export class CoreQuestionHelperProvider { | |||||||
|     ): Promise<void> { |     ): Promise<void> { | ||||||
|         if (!component) { |         if (!component) { | ||||||
|             component = CoreQuestionProvider.COMPONENT; |             component = CoreQuestionProvider.COMPONENT; | ||||||
|             componentId = question.number; |             componentId = question.questionnumber; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const files = CoreQuestionDelegate.getAdditionalDownloadableFiles(question, usageId) || []; |         const files = CoreQuestionDelegate.getAdditionalDownloadableFiles(question, usageId) || []; | ||||||
|  | |||||||
| @ -314,7 +314,7 @@ export class CoreQuestionProvider { | |||||||
|      * @returns Question component ID. |      * @returns Question component ID. | ||||||
|      */ |      */ | ||||||
|     getQuestionComponentId(question: CoreQuestionQuestionParsed, componentId: string | number): string { |     getQuestionComponentId(question: CoreQuestionQuestionParsed, componentId: string | number): string { | ||||||
|         return componentId + '_' + question.number; |         return componentId + '_' + question.questionnumber; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -385,6 +385,10 @@ export class CoreQuestionProvider { | |||||||
|         const parsedQuestions: CoreQuestionQuestionParsed[] = questions; |         const parsedQuestions: CoreQuestionQuestionParsed[] = questions; | ||||||
| 
 | 
 | ||||||
|         parsedQuestions.forEach((question) => { |         parsedQuestions.forEach((question) => { | ||||||
|  |             if (typeof question.questionnumber === 'undefined' && typeof question.number === 'number') { | ||||||
|  |                 question.questionnumber = String(question.number); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             if (!question.settings) { |             if (!question.settings) { | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
| @ -547,14 +551,11 @@ export class CoreQuestionProvider { | |||||||
|         state: string, |         state: string, | ||||||
|         siteId?: string, |         siteId?: string, | ||||||
|     ): Promise<void> { |     ): Promise<void> { | ||||||
| 
 |  | ||||||
|         const site = await CoreSites.getSite(siteId); |         const site = await CoreSites.getSite(siteId); | ||||||
|         const entry: CoreQuestionDBRecord = { |         const entry: CoreQuestionDBRecord = { | ||||||
|             component, |             component, | ||||||
|             componentid: componentId, |             componentid: componentId, | ||||||
|             attemptid: attemptId, |             attemptid: attemptId, | ||||||
|             userid: userId, |  | ||||||
|             number: question.number, // eslint-disable-line id-blacklist
 |  | ||||||
|             slot: question.slot, |             slot: question.slot, | ||||||
|             state: state, |             state: state, | ||||||
|         }; |         }; | ||||||
| @ -594,14 +595,16 @@ export type CoreQuestionQuestionWSData = { | |||||||
|     lastactiontime?: number; // The timestamp of the most recent step in this question attempt.
 |     lastactiontime?: number; // The timestamp of the most recent step in this question attempt.
 | ||||||
|     hasautosavedstep?: boolean; // Whether this question attempt has autosaved data.
 |     hasautosavedstep?: boolean; // Whether this question attempt has autosaved data.
 | ||||||
|     flagged: boolean; // Whether the question is flagged or not.
 |     flagged: boolean; // Whether the question is flagged or not.
 | ||||||
|     // eslint-disable-next-line id-blacklist
 |     questionnumber?: string; // @since 4.2. Question ordering number in the quiz.
 | ||||||
|     number?: number; // Question ordering number in the quiz.
 |  | ||||||
|     state?: string; // The state where the question is in. It won't be returned if the user cannot see it.
 |     state?: string; // The state where the question is in. It won't be returned if the user cannot see it.
 | ||||||
|     status?: string; // Current formatted state of the question.
 |     status?: string; // Current formatted state of the question.
 | ||||||
|     blockedbyprevious?: boolean; // Whether the question is blocked by the previous question.
 |     blockedbyprevious?: boolean; // Whether the question is blocked by the previous question.
 | ||||||
|     mark?: string; // The mark awarded. It will be returned only if the user is allowed to see it.
 |     mark?: string; // The mark awarded. It will be returned only if the user is allowed to see it.
 | ||||||
|     maxmark?: number; // The maximum mark possible for this question attempt.
 |     maxmark?: number; // The maximum mark possible for this question attempt.
 | ||||||
|     settings?: string; // Question settings (JSON encoded).
 |     settings?: string; // Question settings (JSON encoded).
 | ||||||
|  | 
 | ||||||
|  |     /** @deprecated Since 4.2. Use questionnumber instead. */ | ||||||
|  |     number?: number; // eslint-disable-line id-blacklist
 | ||||||
| }; | }; | ||||||
| /** | /** | ||||||
|  * Question data with parsed data. |  * Question data with parsed data. | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user