Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<button
class="enable-in-translation"
mat-raised-button
mat-icon-button
color="primary"
(click)="chooseAsset()"
[matTooltip]="tooltip"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<div class="flex flex-row justify-end items-center">
<mat-divider class="choice-divider" [ngClass]="{ active: focus }" />
<button
mat-icon-button
color="primary"
(click)="newChoiceEvent.emit()"
(mouseover)="focus = true"
(mouseleave)="focus = false"
(focusin)="focus = true"
(focusout)="focus = false"
i18n-matTooltip
matTooltip="Add choice"
matTooltipPosition="above"
>
<mat-icon>add_circle</mat-icon>
</button>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.choice-divider {
width: 100%;
position: relative;

&:after {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
border-bottom-style: solid;
content: "";
border-bottom-width: var(--mdc-filled-text-field-focus-active-indicator-height);
border-bottom-color: var(--mdc-filled-text-field-focus-active-indicator-color);
transform: scaleX(0);
transform-origin: 100%;
transition: transform 360ms cubic-bezier(0.4, 0, 0.2, 1),opacity 360ms cubic-bezier(0.4, 0, 0.2, 1);
opacity: 0;
}

&.active {
&:after {
transform: scaleX(1);
opacity: 1;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, Output } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatDividerModule } from '@angular/material/divider';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';

@Component({
imports: [CommonModule, MatButtonModule, MatDividerModule, MatIconModule, MatTooltipModule],
selector: 'add-mc-choice',
styleUrl: 'add-mc-choice.component.scss',
templateUrl: 'add-mc-choice.component.html'
})
export class AddMCChoiceComponent {
protected focus: boolean;
@Output() newChoiceEvent: EventEmitter<void> = new EventEmitter<void>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,101 +13,97 @@
<mat-radio-button color="primary" value="checkbox" i18n>Multiple Answer</mat-radio-button>
</mat-radio-group>
</p>
<span class="choices-label" i18n>Choices</span>
<button
mat-raised-button
color="primary"
class="add-choice-button"
(click)="addChoice()"
i18nMatTooltip
matTooltip="Add Choice"
matTooltipPosition="above"
>
<mat-icon>add</mat-icon>
</button>
<h2 class="mat-headline-6 !mb-0" i18n>Choices</h2>
<add-mc-choice (newChoiceEvent)="addChoice(0)" />
@if (componentContent.choices == null || componentContent.choices.length === 0) {
<div class="info-block" i18n>
There are no choices. Click the "Add Choice" button to add a choice.
There are no choices. Click the "Add choice" button to add a choice.
</div>
}
@for (choice of componentContent.choices; track choice.id; let last = $last; let first = $first) {
<div class="choice-container">
<div class="flex flex-row flex-wrap justify-start gap-2">
<translatable-input
[content]="choice"
key="text"
label="Choice Text"
i18n-label
placeholder="Type text or choose an image"
i18n-placeholder
(defaultLanguageTextChanged)="choiceTextChange.next($event)"
class="choice-text-input-container"
/>
<translatable-asset-chooser
[content]="choice"
key="text"
[processAsset]="processSelectedAsset"
(defaultLanguageTextChanged)="componentChanged()"
/>
<div>
<mat-checkbox
color="primary"
[(ngModel)]="choice.isCorrect"
(change)="feedbackChanged()"
i18n-aria-label
aria-label="Is Correct"
i18n
>
Is Correct
</mat-checkbox>
@for (choice of componentContent.choices; track choice.id; let last = $last; let i = $index) {
<div class="flex">
<div class="choice-container w-full @container">
<div class="flex flex-col @md:flex-row items-start gap-2">
<div class="flex flex-1 gap-2 order-2 @md:order-1 w-full @md:w-auto">
<translatable-input
[content]="choice"
key="text"
label="Choice Text"
i18n-label
placeholder="Type text or choose an image"
i18n-placeholder
(defaultLanguageTextChanged)="choiceTextChange.next($event)"
class="choice-input-container"
/>
<translatable-asset-chooser
[content]="choice"
key="text"
[processAsset]="processSelectedAsset"
(defaultLanguageTextChanged)="componentChanged()"
/>
</div>
<div class="flex items-center justify-between gap-2 order-1 @md:order-2 w-full @md:w-auto">
<mat-checkbox
color="primary"
[(ngModel)]="choice.isCorrect"
(change)="feedbackChanged()"
i18n-aria-label
aria-label="Is Correct"
i18n
>
Is Correct
</mat-checkbox>
<button
mat-icon-button
color="primary"
(click)="deleteChoice(choice)"
i18n-matTooltip
matTooltip="Delete choice"
matTooltipPosition="above"
>
<mat-icon>delete</mat-icon>
</button>
</div>
</div>
<div class="flex flex-row flex-wrap justify-start">
<translatable-input
[content]="choice"
key="feedback"
label="Feedback"
i18n-label
placeholder="Optional"
i18n-placeholder
(defaultLanguageTextChanged)="feedbackTextChange.next($event)"
class="choice-input-container"
/>
</div>
</div>
<div class="flex flex-row flex-wrap justify-start">
<translatable-input
[content]="choice"
key="feedback"
label="Feedback"
i18n-label
placeholder="Optional"
i18n-placeholder
(defaultLanguageTextChanged)="feedbackTextChange.next($event)"
class="choice-feedback-input-container"
/>
<button
mat-raised-button
color="primary"
class="choice-authoring-button"
[disabled]="first"
(click)="moveChoiceUp(choice)"
i18n-matTooltip
matTooltip="Move Up"
matTooltipPosition="above"
>
<mat-icon>arrow_upward</mat-icon>
</button>
<button
mat-raised-button
color="primary"
class="choice-authoring-button"
[disabled]="last"
(click)="moveChoiceDown(choice)"
i18n-matTooltip
matTooltip="Move Down"
matTooltipPosition="above"
>
<mat-icon>arrow_downward</mat-icon>
</button>
<button
mat-raised-button
color="primary"
class="choice-authoring-button"
(click)="deleteChoice(choice)"
i18n-matTooltip
matTooltip="Delete"
matTooltipPosition="above"
>
<mat-icon>delete</mat-icon>
</button>
<div class="flex flex-col">
@if (i > 0) {
<button
mat-icon-button
color="primary"
(click)="moveChoiceUp(choice)"
i18n-matTooltip
matTooltip="Move up"
matTooltipPosition="above"
>
<mat-icon>arrow_upward</mat-icon>
</button>
}
@if (!last) {
<button
mat-icon-button
color="primary"
(click)="moveChoiceDown(choice)"
i18n-matTooltip
matTooltip="Move down"
matTooltipPosition="above"
>
<mat-icon>arrow_downward</mat-icon>
</button>
}
</div>
</div>
<add-mc-choice (newChoiceEvent)="addChoice(i + 1)" />
}
Original file line number Diff line number Diff line change
@@ -1,56 +1,20 @@
@use 'style/abstracts/variables';

/* TODO(mdc-migration): The following rule targets internal classes of radio that may no longer apply for the MDC version. */
mat-radio-button {
margin-right: 24px;
}

label.mat-radio-label {
display: inline-flex;
}

.choices-label {
margin-right: 10px;
}

.add-choice-button {
margin-top: 20px;
margin-bottom: 20px;
}

.choice-container {
border: 2px solid #dddddd;
border-radius: variables.$card-border-radius;
margin-bottom: 20px;
padding: 20px 20px 10px 20px;
padding: 16px 16px 0;
}

.info-block {
margin-bottom: 20px;
text-align: center;
font-weight: 500;
}

.choice-authoring-button {
margin-left: 10px;
margin-right: 10px;
}

.mat-mdc-checkbox {
margin-left: 5px;
}

.choice-text-input-container, .choice-feedback-input-container {
width: 70%;
.choice-input-container {
flex: 1;

mat-form-field {
width: 100%;
}
}

.reload-preview-container {
margin-bottom: 10px;
}

.mat-icon {
margin: 0px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import { EditComponentPrompt } from '../../../../../app/authoring-tool/edit-comp
import { TranslatableAssetChooserComponent } from '../../../authoringTool/components/translatable-asset-chooser/translatable-asset-chooser.component';
import { TranslatableInputComponent } from '../../../authoringTool/components/translatable-input/translatable-input.component';
import { Choice } from '../Choice';
import { AddMCChoiceComponent } from '../add-mc-choice/add-mc-choice.component';

@Component({
imports: [
AddMCChoiceComponent,
FormsModule,
MatButtonModule,
MatCheckboxModule,
Expand Down Expand Up @@ -67,8 +69,12 @@ export class MultipleChoiceAuthoring extends AbstractComponentAuthoring {
return false;
}

protected addChoice(): void {
this.componentContent.choices.push(new Choice(generateRandomKey(), '', false, ''));
protected addChoice(position: number): void {
this.componentContent.choices.splice(
position,
0,
new Choice(generateRandomKey(), '', false, '')
);
this.componentChanged();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ import { MatRadioButtonHarness } from '@angular/material/radio/testing';

export class MultipleChoiceAuthoringHarness extends ComponentHarness {
static hostSelector = 'multiple-choice-authoring';
getAddChoiceButton = this.locatorFor(MatButtonHarness.with({ selector: '.add-choice-button' }));
getAddChoiceButton = this.locatorFor(
MatButtonHarness.with({ selector: '[mattooltip="Add choice"]' })
);
getChoices = this.locatorForAll('.choice-container');
getDeleteChoiceButtons = this.locatorForAll(
MatButtonHarness.with({ selector: '[mattooltip="Delete"]' })
MatButtonHarness.with({ selector: '[mattooltip="Delete choice"]' })
);
getMoveDownButtons = this.locatorForAll(
MatButtonHarness.with({ selector: '[mattooltip="Move Down"]' })
MatButtonHarness.with({ selector: '[mattooltip="Move down"]' })
);
getMoveUpButtons = this.locatorForAll(
MatButtonHarness.with({ selector: '[mattooltip="Move Up"]' })
MatButtonHarness.with({ selector: '[mattooltip="Move up"]' })
);
getMultipleAnswerRadioChoice = this.locatorFor(
MatRadioButtonHarness.with({ label: 'Multiple Answer' })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ function moveChoice() {
});
describe('move choice up is clicked on the second choice', () => {
it('moves the choice up', async () => {
await (await multipleChoiceAuthoringHarness.getMoveChoiceUpButton(1)).click();
await (await multipleChoiceAuthoringHarness.getMoveChoiceUpButton(0)).click();
expectChoiceOrder(['choice2', 'choice1']);
});
});
Expand Down
Loading