Skip to content

Commit

Permalink
refactor(MultipleChoiceAuthoringComponent): Convert to standalone (#1988
Browse files Browse the repository at this point in the history
)
  • Loading branch information
hirokiterashima authored Nov 13, 2024
1 parent 5e74e65 commit 7f5ad05
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 185 deletions.
2 changes: 1 addition & 1 deletion src/app/teacher/component-authoring.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ import { RequiredErrorLabelComponent } from '../../assets/wise5/authoringTool/no
HtmlAuthoring,
LabelAuthoring,
MatchAuthoring,
MultipleChoiceAuthoring,
OutsideUrlAuthoring,
PeerChatAuthoringComponent,
ShowGroupWorkAuthoringComponent,
Expand All @@ -174,6 +173,7 @@ import { RequiredErrorLabelComponent } from '../../assets/wise5/authoringTool/no
EditComponentConstraintsComponent,
EditComponentPrompt,
EditComponentWidthComponent,
MultipleChoiceAuthoring,
OpenResponseAuthoringComponent,
PeerGroupingAuthoringModule,
RequiredErrorLabelComponent,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<edit-component-prompt
[componentContent]="componentContent"
(promptChangedEvent)="promptChanged($event)"
></edit-component-prompt>
/>
<p>
<label id="selection-type-label">Selection Type:</label>
<mat-radio-group
Expand All @@ -27,98 +27,95 @@
>
<mat-icon>add</mat-icon>
</button>
<div
*ngIf="componentContent.choices == null || componentContent.choices.length === 0"
class="info-block"
i18n
>
There are no choices. Click the "Add Choice" button to add a choice.
</div>
<div
*ngFor="let choice of componentContent.choices; first as isFirst; last as isLast"
class="choice-container"
>
<div fxLayout="row wrap" fxLayoutAlign="start center" fxLayoutGap="8px">
<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
@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.
</div>
}
@for (choice of componentContent.choices; track choice.id; let last = $last; let first = $first) {
<div class="choice-container">
<div fxLayout="row wrap" fxLayoutAlign="start center" fxLayoutGap="8px">
<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>
</div>
</div>
<div fxLayout="row wrap" fxLayoutAlign="start center">
<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"
[(ngModel)]="choice.isCorrect"
(change)="feedbackChanged()"
class="choice-authoring-button"
[disabled]="first"
(click)="moveChoiceUp(choice)"
i18n-matTooltip
matTooltip="Move Up"
matTooltipPosition="above"
i18n-aria-label
aria-label="Is Correct"
i18n
aria-label="Up"
>
Is Correct
</mat-checkbox>
<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"
i18n-aria-label
aria-label="Down"
>
<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"
i18n-aria-label
aria-label="Delete"
>
<mat-icon>delete</mat-icon>
</button>
</div>
</div>
<div fxLayout="row wrap" fxLayoutAlign="start center">
<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]="isFirst"
(click)="moveChoiceUp(choice.id)"
i18n-matTooltip
matTooltip="Move Up"
matTooltipPosition="above"
i18n-aria-label
aria-label="Up"
>
<mat-icon>arrow_upward</mat-icon>
</button>
<button
mat-raised-button
color="primary"
class="choice-authoring-button"
[disabled]="isLast"
(click)="moveChoiceDown(choice.id)"
i18n-matTooltip
matTooltip="Move Down"
matTooltipPosition="above"
i18n-aria-label
aria-label="Down"
>
<mat-icon>arrow_downward</mat-icon>
</button>
<button
mat-raised-button
color="primary"
class="choice-authoring-button"
(click)="deleteChoice(choice.id)"
i18n-matTooltip
matTooltip="Delete"
matTooltipPosition="above"
i18n-aria-label
aria-label="Delete"
>
<mat-icon>delete</mat-icon>
</button>
</div>
</div>
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,54 @@
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatIconModule } from '@angular/material/icon';
import { MatRadioModule } from '@angular/material/radio';
import { MatTooltipModule } from '@angular/material/tooltip';
import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter } from 'rxjs/operators';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
import { ProjectAssetService } from '../../../../../app/services/projectAssetService';
import { AbstractComponentAuthoring } from '../../../authoringTool/components/AbstractComponentAuthoring';
import { generateRandomKey } from '../../../common/string/string';
import { ConfigService } from '../../../services/configService';
import { TeacherProjectService } from '../../../services/teacherProjectService';
import { TeacherNodeService } from '../../../services/teacherNodeService';
import { moveObjectDown, moveObjectUp } from '../../../common/array/array';
import { FlexLayoutModule } from '@angular/flex-layout';
import { EditComponentPrompt } from '../../../../../app/authoring-tool/edit-component-prompt/edit-component-prompt.component';
import { TranslatableAssetChooserComponent } from '../../../authoringTool/components/translatable-asset-chooser/translatable-asset-chooser.component';
import { TranslatableInputComponent } from '../../../authoringTool/components/translatable-input/translatable-input.component';

@Component({
imports: [
FormsModule,
FlexLayoutModule,
MatButtonModule,
MatCheckboxModule,
MatIconModule,
MatRadioModule,
MatTooltipModule,
EditComponentPrompt,
TranslatableAssetChooserComponent,
TranslatableInputComponent
],
selector: 'multiple-choice-authoring',
templateUrl: 'multiple-choice-authoring.component.html',
styleUrls: ['multiple-choice-authoring.component.scss']
standalone: true,
styleUrls: ['multiple-choice-authoring.component.scss'],
templateUrl: 'multiple-choice-authoring.component.html'
})
export class MultipleChoiceAuthoring extends AbstractComponentAuthoring {
allowedConnectedComponentTypes = ['MultipleChoice'];
choiceTextChange: Subject<string> = new Subject<string>();
feedbackTextChange: Subject<string> = new Subject<string>();
protected choiceTextChange: Subject<string> = new Subject<string>();
protected feedbackTextChange: Subject<string> = new Subject<string>();

constructor(
protected ConfigService: ConfigService,
protected NodeService: TeacherNodeService,
protected ProjectAssetService: ProjectAssetService,
protected ProjectService: TeacherProjectService
protected configService: ConfigService,
protected nodeService: TeacherNodeService,
protected projectAssetService: ProjectAssetService,
protected projectService: TeacherProjectService
) {
super(ConfigService, NodeService, ProjectAssetService, ProjectService);
super(configService, nodeService, projectAssetService, projectService);
this.subscriptions.add(
this.choiceTextChange.pipe(debounceTime(1000), distinctUntilChanged()).subscribe(() => {
this.componentChanged();
Expand All @@ -37,7 +61,7 @@ export class MultipleChoiceAuthoring extends AbstractComponentAuthoring {
);
}

feedbackChanged(): void {
protected feedbackChanged(): void {
let show = true;
if (!this.componentHasFeedback()) {
show = false;
Expand All @@ -46,7 +70,7 @@ export class MultipleChoiceAuthoring extends AbstractComponentAuthoring {
this.componentChanged();
}

componentHasFeedback(): boolean {
private componentHasFeedback(): boolean {
for (const choice of this.componentContent.choices) {
if (choice.isCorrect || (choice.feedback != null && choice.feedback !== '')) {
return true;
Expand All @@ -55,7 +79,7 @@ export class MultipleChoiceAuthoring extends AbstractComponentAuthoring {
return false;
}

addChoice(): void {
protected addChoice(): void {
const newChoice = {
id: generateRandomKey(),
text: '',
Expand All @@ -66,50 +90,28 @@ export class MultipleChoiceAuthoring extends AbstractComponentAuthoring {
this.componentChanged();
}

deleteChoice(choiceId: string): void {
protected deleteChoice(choice: any): void {
if (confirm($localize`Are you sure you want to delete this choice?`)) {
const choices = this.componentContent.choices;
for (let c = 0; c < choices.length; c++) {
if (choices[c].id === choiceId) {
choices.splice(c, 1);
break;
}
}
this.componentContent.choices.splice(this.findChoiceIndex(choice), 1);
this.componentChanged();
}
}

moveChoiceUp(choiceId: string): void {
const choices = this.componentContent.choices;
for (let c = 0; c < choices.length; c++) {
const choice = choices[c];
if (choice.id === choiceId) {
if (c !== 0) {
choices.splice(c, 1);
choices.splice(c - 1, 0, choice);
}
break;
}
}
protected moveChoiceUp(choice: any): void {
moveObjectUp(this.componentContent.choices, this.findChoiceIndex(choice));
this.componentChanged();
}

moveChoiceDown(choiceId: string): void {
const choices = this.componentContent.choices;
for (let c = 0; c < choices.length; c++) {
const choice = choices[c];
if (choice.id === choiceId) {
if (c !== choices.length - 1) {
choices.splice(c, 1);
choices.splice(c + 1, 0, choice);
}
break;
}
}
protected moveChoiceDown(choice: any): void {
moveObjectDown(this.componentContent.choices, this.findChoiceIndex(choice));
this.componentChanged();
}

processSelectedAsset(value: string): string {
private findChoiceIndex(searchChoice: any): number {
return this.componentContent.choices.findIndex((choice) => choice === searchChoice);
}

protected processSelectedAsset(value: string): string {
return `<img src="${value}" alt="${value}" />`;
}
}
Loading

0 comments on commit 7f5ad05

Please sign in to comment.