Skip to content

Commit

Permalink
CSCEXAM-000 Take new editor in use everywhere
Browse files Browse the repository at this point in the history
- fix various issues still
  • Loading branch information
lupari committed Nov 25, 2024
1 parent a35bad1 commit c137c6b
Show file tree
Hide file tree
Showing 29 changed files with 214 additions and 180 deletions.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"prepare": "lefthook install",
"check-format": "prettier --check \"ui/src/app/**/*.{ts,html}\" --check \"{app,test}/**/*.java\" --plugin=prettier-plugin-java --print-width=120 --tab-width=4; exit 0",
"check-lint": "ng lint",
"cp:assets": "cp -R node_modules/mathjax ui/src/assets/vendor/mathjax && cp node_modules/@ckeditor/ckeditor5-inspector/build/inspector.js ui/src/assets/vendor"
"cp:assets": "cp -R node_modules/mathjax ui/src/assets/vendor/mathjax"
},
"dependencies": {
"@angular/animations": "^18.1.4",
Expand Down Expand Up @@ -63,7 +63,6 @@
"@angular-eslint/template-parser": "^18.2.0",
"@angular/cli": "^18.1.4",
"@angular/compiler-cli": "^18.1.4",
"@ckeditor/ckeditor5-inspector": "^4.1.0",
"@types/ckeditor": "^4.9.10",
"@types/file-saver-es": "^2.0.1",
"@types/jasmine": "^3.10.0",
Expand Down
7 changes: 2 additions & 5 deletions ui/src/app/administrative/settings/settings.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,9 @@
<label for="editor">{{ 'i18n_user_agreement' | translate }}</label>
<xm-ckeditor
id="editor"
#ck="ngModel"
name="editor"
ck-editor
rows="10"
cols="80"
[(ngModel)]="config.eula"
[data]="config.eula"
(dataChange)="eulaChanged($event)"
></xm-ckeditor>
</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions ui/src/app/administrative/settings/settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ export class SettingsComponent implements OnInit {
updateReservationWindow = () =>
this.Settings.updateReservationWindow$(this.config).subscribe({ next: this.onSuccess, error: this.onError });

eulaChanged = (event: string) => (this.config.eula = event);

private onSuccess = () =>
this.toast.info(this.translate.instant('i18n_settings') + ' ' + this.translate.instant('i18n_updated'));

Expand Down
19 changes: 3 additions & 16 deletions ui/src/app/exam/editor/basic/basic-exam-info.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -252,15 +252,7 @@
</sup>
</div>
<div class="col-md-9">
<xm-ckeditor
rows="4"
cols="150"
[enableClozeTest]="false"
[(ngModel)]="exam.instruction"
(onBlur)="updateExam(false)"
#ck="ngModel"
name="ck"
></xm-ckeditor>
<xm-ckeditor [data]="exam.instruction" (dataChange)="updateExam(false)" />
</div>
</div>
</div>
Expand Down Expand Up @@ -288,13 +280,8 @@
}
<div class="col-md-9">
<xm-ckeditor
rows="4"
cols="150"
[enableClozeTest]="false"
[(ngModel)]="exam.enrollInstruction"
(onBlur)="updateExam(false)"
#ck="ngModel"
name="ck"
[data]="exam.enrollInstruction"
(dataChange)="enrollInstructionsChanged($event)"
></xm-ckeditor>
</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions ui/src/app/exam/editor/basic/basic-exam-info.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ export class BasicExamInfoComponent implements OnInit, OnDestroy {
});
};

enrollInstructionsChanged = (event: string) => (this.exam.enrollInstruction = event);

getExecutionTypeTranslation = () => !this.exam || this.Exam.getExecutionTypeTranslation(this.exam.executionType);

getExaminationTypeName = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export class ExaminationEssayQuestionComponent implements OnInit {
const decodedString = doc.documentElement.innerText;
this.questionTitle = decodedString;
}

answerChanged = (event: string) => (this.sq.essayAnswer.answer = event);
saveAnswer = () => this.Examination.saveTextualAnswer$(this.sq, this.exam?.hash || '', false, false).subscribe();

removeQuestionAnswerAttachment = () => {
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/maturity/maturity.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface LanguageInspection {
modifier: User;
creator: User;
created: Date;
statement: { attachment?: Attachment; comment?: string };
statement: { attachment?: Attachment; comment: string };
}

export interface LanguageInspectionData extends LanguageInspection {
Expand Down
2 changes: 0 additions & 2 deletions ui/src/app/question/question-basic-info.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@ import { CKEditorComponent } from 'src/app/shared/ckeditor/ckeditor.component';
<xm-ckeditor
id="editor"
name="editor"
rows="10"
cols="50"
[enableClozeTest]="question()?.type === 'ClozeTestQuestion'"
[data]="question()?.question || ''"
(dataChange)="textChanged($event)"
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/question/question.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export interface LibraryQuestion extends ReverseQuestion {
export interface EssayAnswer {
id?: number;
evaluatedScore?: number;
answer?: string;
answer: string;
objectVersion?: number;
attachment?: Attachment;
}
Expand Down
9 changes: 4 additions & 5 deletions ui/src/app/review/assessment/feedback/feedback.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,9 @@ import { FileService } from 'src/app/shared/file/file.service';
<div class="col-md-12">
<xm-ckeditor
id="feedback-editor"
[enableClozeTest]="false"
[(ngModel)]="exam.examFeedback.comment"
#ck="ngModel"
[data]="exam.examFeedback.comment"
(dataChange)="commentChanged($event)"
name="ck"
rows="10"
cols="80"
></xm-ckeditor>
</div>
</div>
Expand Down Expand Up @@ -144,6 +141,8 @@ export class FeedbackComponent implements OnInit {
}
};

commentChanged = (event: string) => (this.exam.examFeedback.comment = event);

private _saveFeedback$ = () => this.Assessment.saveFeedback$(this.exam);

private _saveCollaborativeFeedback$ = () =>
Expand Down
9 changes: 4 additions & 5 deletions ui/src/app/review/assessment/feedback/statement.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,9 @@ import { FileService } from 'src/app/shared/file/file.service';
<div class="row mt-2 mb-1">
<div class="col-md-12">
<xm-ckeditor
[enableClozeTest]="false"
[(ngModel)]="exam.languageInspection.statement.comment"
#ck="ngModel"
[data]="exam.languageInspection.statement.comment"
(dataChange)="commentChanged($event)"
name="ck"
rows="10"
cols="80"
></xm-ckeditor>
</div>
</div>
Expand Down Expand Up @@ -93,6 +90,8 @@ export class StatementComponent {
private Assessment: AssessmentService,
) {}

commentChanged = (event: string) => (this.exam.languageInspection.statement.comment = event);

hasGoneThroughLanguageInspection = () => this.exam.languageInspection?.finishedAt;

toggleEditorVisibility = () => (this.hideEditor = !this.hideEditor);
Expand Down
15 changes: 12 additions & 3 deletions ui/src/app/review/assessment/questions/essay-question.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,27 @@ export class EssayQuestionComponent implements OnInit {

set scoreValue(value: number | undefined) {
this._score = value;
const answer = this.sectionQuestion.essayAnswer!.answer;
if (!this.form || this.form.valid) {
this.sectionQuestion.essayAnswer = { ...this.sectionQuestion.essayAnswer, evaluatedScore: value };
this.sectionQuestion.essayAnswer = {
...this.sectionQuestion.essayAnswer,
evaluatedScore: value,
answer: answer,
};
} else {
this.sectionQuestion.essayAnswer = { ...this.sectionQuestion.essayAnswer, evaluatedScore: undefined };
this.sectionQuestion.essayAnswer = {
...this.sectionQuestion.essayAnswer,
evaluatedScore: undefined,
answer: answer,
};
}
}

ngOnInit() {
this.id = this.route.snapshot.params.id;
this.ref = this.route.snapshot.params.ref;
if (!this.sectionQuestion.essayAnswer) {
this.sectionQuestion.essayAnswer = { id: 0 };
this.sectionQuestion.essayAnswer = { answer: '' };
}
this.scoreValue = this.sectionQuestion.essayAnswer.evaluatedScore;
}
Expand Down
7 changes: 4 additions & 3 deletions ui/src/app/review/listing/dialogs/feedback.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ import { CKEditorComponent } from 'src/app/shared/ckeditor/ckeditor.component';
@if (exam.examFeedback !== null) {
<div class="col-md-12 ps-0">
<xm-ckeditor
rows="10"
#ck="ngModel"
[(ngModel)]="exam.examFeedback.comment"
[data]="exam.examFeedback.comment"
(dataChange)="commentChanged($event)"
autofocus
></xm-ckeditor>
</div>
Expand Down Expand Up @@ -56,6 +55,8 @@ export class SpeedReviewFeedbackComponent implements OnInit {
}
}

commentChanged = (event: string) => (this.exam.examFeedback.comment = event);

ok = () => {
if (!this.exam.examFeedback) {
this.exam.examFeedback = { comment: '', feedbackStatus: false };
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/shared/ckeditor/ckeditor.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ export class CKEditorComponent implements AfterViewInit {
const wordCountPlugin = e.plugins.get('WordCount');
const wordCountWrapper = document.getElementById('word-count') as HTMLElement;
wordCountWrapper.appendChild(wordCountPlugin.wordCountContainer);
CKEditorInspector.attach(e);
//CKEditorInspector.attach(e);
}

onChange({ editor }: ChangeEvent) {
Expand Down
21 changes: 8 additions & 13 deletions ui/src/app/shared/ckeditor/ckeditor.styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
*
* SPDX-License-Identifier: EUPL-1.2
*/

.editor-container_classic-editor .editor-container__editor {
min-height: 500px;
max-height: 795px;
}
.ck.ck-word-count {
display: flex;
justify-content: flex-end;
Expand All @@ -21,28 +24,20 @@
padding: var(--ck-spacing-large);
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(5, 1fr);
column-gap: 0px;
row-gap: var(--ck-spacing-standard);
grid-template-rows: repeat(4, 1fr);
}
.ck.ck-cloze-form .ck.ck-labeled-field-view:nth-of-type(1) {
grid-area: 1 / 1 / 2 / 3;
}
.ck.ck-cloze-form .ck.ck-labeled-field-view:nth-of-type(2) {
grid-area: 4 / 1 / 4 / 3;
}
.ck.ck-cloze-form .ck-button:nth-of-type(1) {
grid-area: 2 / 1 / 2 / 3;
}
.ck.ck-cloze-form .ck-button:nth-of-type(2) {
grid-area: 3 / 1 / 3 / 3;
}
.ck.ck-cloze-form .ck.ck-labeled-field-view:nth-of-type(2) {
grid-area: 4 / 1 / 4 / 3;
}
.ck.ck-cloze-form .ck-button:nth-of-type(3) {
grid-area: 5 / 1 / 5 / 2;
}
.ck.ck-cloze-form .ck-button:nth-of-type(4) {
grid-area: 5 / 2 / 5 / 3;
}
.cloze-test-wrapper {
background-color: yellow;
border: 1px solid;
Expand Down
12 changes: 6 additions & 6 deletions ui/src/app/shared/ckeditor/plugins/clozetest/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ export class ClozeCommand extends Command {
if (selection.hasAttribute('ctCaseSensitive')) {
const caseSensitiveValue = selection.getAttribute('ctCaseSensitive');
const precisionValue = selection.getAttribute('ctPrecision');
const numericValue = selection.getAttribute('ctNumeric');
const answerRange = findAttributeRange(
selection.getFirstPosition()!,
'ctCaseSensitive',
caseSensitiveValue,
model,
);
if (firstRange.isCollapsed) {
this.setValue(caseSensitiveValue, precisionValue, answerRange);
this.setValue(caseSensitiveValue, precisionValue, numericValue, answerRange);
} else if (answerRange.containsRange(firstRange, true)) {
this.setValue(caseSensitiveValue, precisionValue, firstRange);
this.setValue(caseSensitiveValue, precisionValue, numericValue, firstRange);
} else {
this.value = null;
}
Expand All @@ -38,11 +39,9 @@ export class ClozeCommand extends Command {

override execute({ text, caseSensitive, numeric, precision }: CommandValue) {
const model = this.editor.model;
const hasId = model.document.selection.hasAttribute('ckId');
console.log(hasId);
model.change((writer) => {
model.insertContent(
writer.createText(text, {
writer.createText(text.trim(), {
ctCaseSensitive: caseSensitive,
ctPrecision: precision || 0,
ctNumeric: numeric,
Expand All @@ -55,11 +54,12 @@ export class ClozeCommand extends Command {
writer.insertText(' ', model.document.selection.getFirstPosition()!);
});
}
private setValue = (caseSensitive: unknown, precision: unknown, range: Range) =>
private setValue = (caseSensitive: unknown, precision: unknown, numeric: unknown, range: Range) =>
(this.value = {
text: getRangeText(range),
caseSensitive: caseSensitive,
precision: precision,
numeric: numeric,
range: range,
});

Expand Down
4 changes: 2 additions & 2 deletions ui/src/app/shared/ckeditor/plugins/clozetest/editing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export class ClozeEditing extends Plugin {
conversion.for('upcast').elementToAttribute({
view: {
name: 'span',
attributes: { id: true },
attributes: { cloze: true },
},
model: {
key: 'ctCloze',
Expand All @@ -75,7 +75,7 @@ export class ClozeEditing extends Plugin {
conversion.for('upcast').elementToAttribute({
view: {
name: 'span',
attributes: { id: true },
attributes: { class: true },
},
model: {
key: 'ctClass',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,27 @@
//
// SPDX-License-Identifier: EUPL-1.2

import { Dictionary } from './model';

// Had to setup our own translation infrastructure like this because
// the preferred .po files aren't caught up by CKE's translation engine.
// Probably because there is no loader for those in Angular so they aren't
// bundled.
const dictionary: Record<string, string> = {
'Cloze Test': 'Embedded Answer',
Answer: 'Correct Answer',
'Case Sensitive': 'Case sensitive (textual answer only)',
Numeric: 'Numeric Answer',
Precision: 'Required answer precision (± of correct numeric answer value)',
Save: 'Save',
Cancel: 'Cancel',
const dictionary: Dictionary = {
toolbarLabel: 'Embedded Answer',
answerLabel: 'Correct Answer',
caseSensitiveLabel: 'Case sensitive',
caseSensitiveTip: 'Case sensitivity (textual answer only)',
numericLabel: 'Numeric Answer',
numericError: 'Answer must be a numeric value',
precisionLabel: 'Required answer precision',
precisionTip: '(± of correct numeric answer value)',
save: 'Save',
cancel: 'Cancel',
usage: `Use vertical bar ( | ) to separate correct answer options from each other.
Use asterisk ( * ) as a wildcard to match any series of characters. For example
'*ship|boat|ferry' would match answers "ship", "flagship", "boat" and "ferry".
If you really do want to match an asterisk or a vertical pipe then use a backslash
like this: ( \\ )`,
};
export default dictionary;
Loading

0 comments on commit c137c6b

Please sign in to comment.