Skip to content

Commit

Permalink
CSCEXAM-1325 Enhancements for drag/drop of sections and questions
Browse files Browse the repository at this point in the history
  • Loading branch information
lupari committed Aug 12, 2024
1 parent 3a8233c commit 6a79e2f
Show file tree
Hide file tree
Showing 11 changed files with 373 additions and 342 deletions.
241 changes: 131 additions & 110 deletions ui/src/app/exam/editor/sections/section-question.component.html
Original file line number Diff line number Diff line change
@@ -1,44 +1,55 @@
<div class="xm-study-item-container review-view mb-2">
<div class="row align-items-center">
<span class="col-md-6">
<strong class="me-3">#{{ sectionQuestion.question.id }}</strong>
<!-- question points -->
@if (
sectionQuestion.evaluationType === 'Points' ||
sectionQuestion.question.type === 'ClozeTestQuestion' ||
sectionQuestion.question.type === 'MultipleChoiceQuestion'
) {
<span> 0 / {{ sectionQuestion.maxScore }} {{ 'i18n_unit_points' | translate }} </span>
}
@if (sectionQuestion.evaluationType === 'Selection') {
<span>
{{ 'i18n_evaluation_select' | translate }}
</span>
}
@if (sectionQuestion.question.type === 'WeightedMultipleChoiceQuestion') {
<span> 0 / {{ calculateWeightedMaxPoints() }} {{ 'i18n_unit_points' | translate }} </span>
}
@if (sectionQuestion.question.type === 'ClaimChoiceQuestion') {
<span>
{{ getMinimumOptionScore() }} / {{ getCorrectClaimChoiceOptionScore() }}
{{ 'i18n_unit_points' | translate }}
</span>
}
@if (sectionQuestion.question.attachment?.id || sectionQuestion.question.attachment?.externalId) {
<span class="ms-3">
<a
class="pointer text-dark"
ngbPopover="{{ sectionQuestion.question.attachment?.fileName }}"
popoverTitle="{{ 'i18n_instructions' | translate }}"
triggers="mouseenter:mouseleave"
(click)="downloadQuestionAttachment()"
>
<i class="bi-paperclip"></i>
</a>
</span>
}
<span cdkDragHandle class="me-3">
<i
class="bi bi-arrows-vertical"
ngbPopover="{{ 'i18n_move_question' | translate }}"
popoverTitle="{{ 'i18n_instructions' | translate }}"
placement="top-left"
triggers="mouseenter:mouseleave"
></i>
</span>
<span (mousedown)="$event.stopPropagation()">
<strong class="me-3">#{{ sectionQuestion.question.id }}</strong>
<!-- question points -->
@if (
sectionQuestion.evaluationType === 'Points' ||
sectionQuestion.question.type === 'ClozeTestQuestion' ||
sectionQuestion.question.type === 'MultipleChoiceQuestion'
) {
<span> 0 / {{ sectionQuestion.maxScore }} {{ 'i18n_unit_points' | translate }} </span>
}
@if (sectionQuestion.evaluationType === 'Selection') {
<span>
{{ 'i18n_evaluation_select' | translate }}
</span>
}
@if (sectionQuestion.question.type === 'WeightedMultipleChoiceQuestion') {
<span> 0 / {{ calculateWeightedMaxPoints() }} {{ 'i18n_unit_points' | translate }} </span>
}
@if (sectionQuestion.question.type === 'ClaimChoiceQuestion') {
<span>
{{ getMinimumOptionScore() }} / {{ getCorrectClaimChoiceOptionScore() }}
{{ 'i18n_unit_points' | translate }}
</span>
}
@if (sectionQuestion.question.attachment?.id || sectionQuestion.question.attachment?.externalId) {
<span class="ms-3">
<a
class="pointer text-dark"
ngbPopover="{{ sectionQuestion.question.attachment?.fileName }}"
popoverTitle="{{ 'i18n_instructions' | translate }}"
triggers="mouseenter:mouseleave"
(click)="downloadQuestionAttachment()"
>
<i class="bi-paperclip"></i>
</a>
</span>
}
</span>
</span>
<div class="col" ngbDropdown>
<div class="col" (mousedown)="$event.stopPropagation()" ngbDropdown>
<button class="btn btn-outline-dark float-end" ngbDropdownToggle>
{{ 'i18n_settings' | translate }}
</button>
Expand All @@ -49,89 +60,99 @@
</div>
</div>
</div>
<div class="row mt-3">
<!-- Question -->
<div class="col-md-12">
<div class="make-inline" [xmMathJax]="sectionQuestion.question.question"></div>
<div (mousedown)="$event.stopPropagation()">
<div class="row mt-3">
<!-- Question -->
<div class="col-md-12">
<div class="make-inline" [xmMathJax]="sectionQuestion.question.question"></div>
</div>
</div>
</div>
<div class="row mt-2">
<div class="col-md-12">
@if (sectionQuestion.answerInstructions || sectionQuestion.options.length > 0) {
<button
(click)="sectionQuestion.expanded = !sectionQuestion.expanded"
class="btn btn-outline-dark"
[attr.aria-expanded]="sectionQuestion.expanded"
>
<span [hidden]="sectionQuestion.expanded">{{ 'i18n_show_more' | translate }}</span>
<span [hidden]="!sectionQuestion.expanded">{{ 'i18n_hide' | translate }}</span>
<i [hidden]="sectionQuestion.expanded" class="bi bi-chevron-right ms-2" alt="hide evaluation"></i>
<i [hidden]="!sectionQuestion.expanded" class="bi bi-chevron-down ms-2" alt="show evaluation"></i>
</button>
}
<div class="row mt-2">
<div class="col-md-12">
@if (sectionQuestion.answerInstructions || sectionQuestion.options.length > 0) {
<button
(click)="sectionQuestion.expanded = !sectionQuestion.expanded"
class="btn btn-outline-dark"
[attr.aria-expanded]="sectionQuestion.expanded"
>
<span [hidden]="sectionQuestion.expanded">{{ 'i18n_show_more' | translate }}</span>
<span [hidden]="!sectionQuestion.expanded">{{ 'i18n_hide' | translate }}</span>
<i
[hidden]="sectionQuestion.expanded"
class="bi bi-chevron-right ms-2"
alt="hide evaluation"
></i>
<i
[hidden]="!sectionQuestion.expanded"
class="bi bi-chevron-down ms-2"
alt="show evaluation"
></i>
</button>
}
</div>
</div>
</div>
<div class="row mt-1" [ngbCollapse]="!sectionQuestion.expanded">
<div class="col-md-12">
@if (sectionQuestion.answerInstructions && sectionQuestion.answerInstructions.length > 0) {
<div class="row my-4 ms-2">
<div class="col-md-12" role="note">
<img src="/assets/images/icon_info.png" alt="" />
{{ sectionQuestion.answerInstructions }}
<div class="row mt-1" [ngbCollapse]="!sectionQuestion.expanded">
<div class="col-md-12">
@if (sectionQuestion.answerInstructions && sectionQuestion.answerInstructions.length > 0) {
<div class="row my-4 ms-2">
<div class="col-md-12" role="note">
<img src="/assets/images/icon_info.png" alt="" />
{{ sectionQuestion.answerInstructions }}
</div>
</div>
</div>
}
@switch (sectionQuestion.question.type) {
@case ('MultipleChoiceQuestion') {
@for (option of sectionQuestion.options; track option) {
<div class="row ms-2 mt-2">
<div class="col-md-12">
@if (option.option.correctOption) {
<img src="/assets/images/icon_correct_answer.png" alt="" />
} @else {
<img src="/assets/images/icon_wrong_answer.png" alt="" />
}
{{ option.option.option }}
}
@switch (sectionQuestion.question.type) {
@case ('MultipleChoiceQuestion') {
@for (option of sectionQuestion.options; track option) {
<div class="row ms-2 mt-2">
<div class="col-md-12">
@if (option.option.correctOption) {
<img src="/assets/images/icon_correct_answer.png" alt="" />
} @else {
<img src="/assets/images/icon_wrong_answer.png" alt="" />
}
{{ option.option.option }}
</div>
</div>
</div>
}
}
}
@case ('WeightedMultipleChoiceQuestion') {
@for (option of sectionQuestion.options; track option) {
<div class="row ms-2 mt-2">
<div class="col-md-12">
@if (option.score >= 0) {
<img src="/assets/images/icon_correct_answer_checkbox.png" alt="" />
}
@if (option.score < 0) {
<img src="/assets/images/icon_wrong_answer_checkbox.png" alt="" />
}
<span class="ps-2">{{ option.option.option }}</span>
<span class="ps-2">{{ option.score }} {{ 'i18n_unit_points' | translate }}</span>
@case ('WeightedMultipleChoiceQuestion') {
@for (option of sectionQuestion.options; track option) {
<div class="row ms-2 mt-2">
<div class="col-md-12">
@if (option.score >= 0) {
<img src="/assets/images/icon_correct_answer_checkbox.png" alt="" />
}
@if (option.score < 0) {
<img src="/assets/images/icon_wrong_answer_checkbox.png" alt="" />
}
<span class="ps-2">{{ option.option.option }}</span>
<span class="ps-2">{{ option.score }} {{ 'i18n_unit_points' | translate }}</span>
</div>
</div>
</div>
}
}
}
@case ('ClaimChoiceQuestion') {
@for (option of sectionQuestion.options | orderBy: 'option.id'; track option) {
<div class="row ms-2 mt-2">
<div class="col-md-12">
@if (determineClaimOptionType(option) === 'CorrectOption') {
<img src="/assets/images/icon_correct_answer_radio.png" alt="" />
}
@if (determineClaimOptionType(option) === 'IncorrectOption') {
<img src="/assets/images/icon_wrong_answer_radio.png" alt="" />
}
@if (determineClaimOptionType(option) === 'SkipOption') {
<img src="/assets/images/icon_wrong_answer.png" alt="" />
}
<span class="ps-2">{{ option.option.option }}</span>
<span class="ps-2">{{ option.score }} {{ 'i18n_unit_points' | translate }}</span>
@case ('ClaimChoiceQuestion') {
@for (option of sectionQuestion.options | orderBy: 'option.id'; track option) {
<div class="row ms-2 mt-2">
<div class="col-md-12">
@if (determineClaimOptionType(option) === 'CorrectOption') {
<img src="/assets/images/icon_correct_answer_radio.png" alt="" />
}
@if (determineClaimOptionType(option) === 'IncorrectOption') {
<img src="/assets/images/icon_wrong_answer_radio.png" alt="" />
}
@if (determineClaimOptionType(option) === 'SkipOption') {
<img src="/assets/images/icon_wrong_answer.png" alt="" />
}
<span class="ps-2">{{ option.option.option }}</span>
<span class="ps-2">{{ option.score }} {{ 'i18n_unit_points' | translate }}</span>
</div>
</div>
</div>
}
}
}
}
</div>
</div>
</div>
</div>
2 changes: 2 additions & 0 deletions ui/src/app/exam/editor/sections/section-question.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* See the Licence for the specific language governing permissions and limitations under the Licence.
*/

import { CdkDragHandle } from '@angular/cdk/drag-drop';
import { HttpClient } from '@angular/common/http';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import {
Expand Down Expand Up @@ -44,6 +45,7 @@ import { OrderByPipe } from 'src/app/shared/sorting/order-by.pipe';
templateUrl: './section-question.component.html',
standalone: true,
imports: [
CdkDragHandle,
NgbPopover,
NgbDropdown,
NgbDropdownToggle,
Expand Down
Loading

0 comments on commit 6a79e2f

Please sign in to comment.