herum-shared 0.1.50 → 0.1.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/atoms/index.d.ts +1 -2
  2. package/environment/index.d.ts +0 -1
  3. package/fesm2022/herum-shared-animations.mjs.map +1 -1
  4. package/fesm2022/herum-shared-atoms.mjs +1 -2
  5. package/fesm2022/herum-shared-atoms.mjs.map +1 -1
  6. package/fesm2022/herum-shared-constants.mjs.map +1 -1
  7. package/fesm2022/herum-shared-decorators.mjs.map +1 -1
  8. package/fesm2022/herum-shared-dialogs.mjs.map +1 -1
  9. package/fesm2022/herum-shared-directives.mjs.map +1 -1
  10. package/fesm2022/herum-shared-environment.mjs.map +1 -1
  11. package/fesm2022/herum-shared-errors.mjs.map +1 -1
  12. package/fesm2022/herum-shared-fetched-message.mjs.map +1 -1
  13. package/fesm2022/herum-shared-molecules.mjs.map +1 -1
  14. package/fesm2022/herum-shared-mongo.mjs.map +1 -1
  15. package/fesm2022/herum-shared-objectsExample.mjs.map +1 -1
  16. package/fesm2022/herum-shared-pipes.mjs.map +1 -1
  17. package/fesm2022/herum-shared-services.mjs +1 -2
  18. package/fesm2022/herum-shared-services.mjs.map +1 -1
  19. package/fesm2022/herum-shared-static-services.mjs.map +1 -1
  20. package/fesm2022/herum-shared-table.mjs.map +1 -1
  21. package/fesm2022/herum-shared-testsObjects.mjs +1 -2
  22. package/fesm2022/herum-shared-testsObjects.mjs.map +1 -1
  23. package/fesm2022/herum-shared-tokens.mjs.map +1 -1
  24. package/fesm2022/herum-shared-utils.mjs +9 -1
  25. package/fesm2022/herum-shared-utils.mjs.map +1 -1
  26. package/fesm2022/herum-shared-validators.mjs.map +1 -1
  27. package/fesm2022/herum-shared.mjs +87 -127
  28. package/fesm2022/herum-shared.mjs.map +1 -1
  29. package/index.d.ts +9 -16
  30. package/molecules/index.d.ts +1 -1
  31. package/package.json +1 -1
  32. package/utils/index.d.ts +2 -1
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { EventEmitter, ViewChild, Output, Input, Component, Pipe, HostListener, Inject, forwardRef, ViewChildren, Optional, Self, Injectable, Directive, ViewEncapsulation, HostBinding, NgModule, InjectionToken } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { formatDate, CommonModule, DatePipe, DOCUMENT } from '@angular/common';
5
- import { Subject, BehaviorSubject, forkJoin, of, EMPTY, throwError, takeUntil as takeUntil$1 } from 'rxjs';
5
+ import { Subject, takeUntil as takeUntil$1, BehaviorSubject, forkJoin, of, EMPTY, throwError } from 'rxjs';
6
6
  import { takeUntil, debounceTime, tap, shareReplay, map, catchError, switchMap } from 'rxjs/operators';
7
7
  import { keyboardAsciiCodes as keyboardAsciiCodes$1, regexExpressions as regexExpressions$1, svgsStrings as svgsStrings$1, system as system$1, radioButtonTypes as radioButtonTypes$1, defaultGrade as defaultGrade$1, checkboxTypes as checkboxTypes$1, defaultPlaceholder as defaultPlaceholder$2, types as types$1, formStatuses as formStatuses$1, structHierarchyTreeMaxHeight as structHierarchyTreeMaxHeight$1, startEndDateError as startEndDateError$1, minDateError as minDateError$1, formatError as formatError$1, timestampError as timestampError$1, timePattern as timePattern$1, dayInMilliSeconds as dayInMilliSeconds$1, dateRangeTimeRangePlaceHolder as dateRangeTimeRangePlaceHolder$1, dateRangeTimeRangeWithoutSecondsPlaceHolder as dateRangeTimeRangeWithoutSecondsPlaceHolder$1, dateRangePlaceHolder as dateRangePlaceHolder$1, dateTimePlaceHolder as dateTimePlaceHolder$1, dateTimeWithoutSecondsPlaceHolder as dateTimeWithoutSecondsPlaceHolder$1, datePlaceHolder as datePlaceHolder$1, timePlaceHolder as timePlaceHolder$1, timeWithoutSecondsPlaceHolder as timeWithoutSecondsPlaceHolder$1, calendarActiveColorCssVariable as calendarActiveColorCssVariable$1, calendarHoverColorCssVariable as calendarHoverColorCssVariable$1, calendarLibrarySelector as calendarLibrarySelector$1, calendarLibraryBodyCellSelector as calendarLibraryBodyCellSelector$1, timerActiveColorCssVariable as timerActiveColorCssVariable$1, timerHoverColorCssVariable as timerHoverColorCssVariable$1, timerItemSizeColorCssVariable as timerItemSizeColorCssVariable$1, resourcesFilesSuffixes as resourcesFilesSuffixes$1, anySubFileTypeWildCard as anySubFileTypeWildCard$1, maleAvatarPath as maleAvatarPath$1, femaleAvatarPath as femaleAvatarPath$1, signUpFormKeys as signUpFormKeys$1, maxImageHeight as maxImageHeight$1, maxImageWidth as maxImageWidth$1, filesSuffixes as filesSuffixes$1, uploadsProgressMetadataTypes as uploadsProgressMetadataTypes$1, tableRowHeights as tableRowHeights$1, generalKeys as generalKeys$1, attributes as attributes$1, defaultAuthorizationObject as defaultAuthorizationObject$1, resourceIdPlaceholder as resourceIdPlaceholder$1, getPublishAuthorization as getPublishAuthorization$1, toastsTemplates as toastsTemplates$1, toastContext as toastContext$1, toastStatuses as toastStatuses$1, toastStates as toastStates$1, defaultUserId as defaultUserId$1, assignmentMetadata as assignmentMetadata$1, validatorsNames as validatorsNames$1, formsErrorMessages as formsErrorMessages$1, getSignUpMethod as getSignUpMethod$1, globalErrorHandlingHeader as globalErrorHandlingHeader$1, dialogsDescriptions as dialogsDescriptions$1, dialogsTitles as dialogsTitles$1, uploadsManagerKeys as uploadsManagerKeys$1, uploadStatuses as uploadStatuses$1, skipToastHeader as skipToastHeader$1 } from 'herum-shared/constants';
8
8
  import * as i2$1 from 'herum-shared/services';
@@ -75,7 +75,6 @@ class HerumSliderComponent {
75
75
  maxSliderValue;
76
76
  currentSliderValue;
77
77
  initSlider;
78
- l;
79
78
  isDraggingEmitter = new EventEmitter();
80
79
  updatedSliderValue = new EventEmitter();
81
80
  slider;
@@ -1083,7 +1082,7 @@ class HerumRadioButtonComponent {
1083
1082
  }
1084
1083
  this.selectedOptionId = value.id;
1085
1084
  this.type = value.type;
1086
- this.isBlocked = value.hasOwnProperty('isBlocked') ? !!value.isBlocked : false;
1085
+ this.isBlocked = value.isBlocked ?? this.isBlocked;
1087
1086
  }
1088
1087
  registerOnChange(fn) {
1089
1088
  this.onChange = fn;
@@ -1133,83 +1132,66 @@ class QuizOneAnswerQuestionComponent {
1133
1132
  onAnswersChange = new EventEmitter();
1134
1133
  convertedOptions;
1135
1134
  selectedAnswer = new FormControl({ type: '', id: '' }, Validators.required);
1135
+ destroySubject$ = new Subject();
1136
1136
  answerNotes = [];
1137
1137
  correctAnswer;
1138
1138
  constructor(changeDetectorRef) {
1139
1139
  this.changeDetectorRef = changeDetectorRef;
1140
1140
  }
1141
1141
  ngOnChanges(changes) {
1142
- const shouldUpdateViewState = !!(changes['question'] ||
1143
- changes['userAnswers'] ||
1144
- changes['quizData'] ||
1145
- changes['areAnswersRevealed'] ||
1146
- changes['isCheckingMode'] ||
1147
- changes['areAnswersBlocked']);
1148
- if (!shouldUpdateViewState || !this.question)
1149
- return;
1150
- this.answerNotes = this.getAnswerNotes(this.question);
1151
- this.convertedOptions = this.convertToOptions();
1152
- this.correctAnswer = undefined;
1153
- this.changeDetectorRef.detectChanges();
1154
- const chosenAnswerId = this.getChosenAnswerId();
1155
- if (!chosenAnswerId) {
1156
- this.selectedAnswer.setValue({ id: '', type: '', isBlocked: this.isRadioBlocked }, { emitEvent: false });
1157
- return;
1158
- }
1159
- const isResultMode = !!(this.quizData?.isSubmitted || this.areAnswersRevealed || this.isCheckingMode);
1160
- if (!isResultMode) {
1161
- this.selectedAnswer.setValue({ id: chosenAnswerId, type: radioButtonTypes$1.checked, isBlocked: this.isRadioBlocked }, { emitEvent: false });
1162
- return;
1163
- }
1164
- const type = this.isCheckedAnswerCorrect(chosenAnswerId, this.quizData) ? radioButtonTypes$1.checked : radioButtonTypes$1.error;
1165
- if (type === radioButtonTypes$1.error && (this.areAnswersRevealed || this.isCheckingMode)) {
1166
- const correctAnswer = this.questionAnswers.find(answer => answer.isCorrect);
1167
- if (correctAnswer)
1168
- this.correctAnswer = { id: correctAnswer.id, name: correctAnswer.content };
1142
+ if (changes['question']?.currentValue) {
1143
+ this.answerNotes = this.getAnswerNotes(this.question);
1144
+ this.convertedOptions = this.convertToOptions();
1145
+ this.changeDetectorRef.detectChanges();
1146
+ const chosenAnswer = this.userAnswers.find(userAnswer => userAnswer.isChosen);
1147
+ if (chosenAnswer && !this.quizData.isSubmitted)
1148
+ this.selectedAnswer.setValue({ id: chosenAnswer.id, type: radioButtonTypes$1.checked }, { emitEvent: false });
1149
+ if (this.quizData.isSubmitted || this.areAnswersRevealed || this.isCheckingMode) {
1150
+ const userAnswers = this.quizData.userAnswers.find((userAnswer) => userAnswer.id === this.question.id);
1151
+ const chosenAnswerId = userAnswers.userAnswers.find((answer) => answer.isChosen)?.id;
1152
+ const type = this.isCheckedAnswerCorrect(chosenAnswerId, this.quizData) ? radioButtonTypes$1.checked : radioButtonTypes$1.error;
1153
+ if (type === radioButtonTypes$1.error && (this.areAnswersRevealed || this.isCheckingMode)) {
1154
+ const correctAnswer = this.question.closedContent?.answers.find(answer => answer.isCorrect);
1155
+ if (correctAnswer)
1156
+ this.correctAnswer = { id: correctAnswer.id, name: correctAnswer.content };
1157
+ }
1158
+ this.selectedAnswer.setValue({ id: chosenAnswerId, type, isBlocked: true }, { emitEvent: false });
1159
+ }
1169
1160
  }
1170
- this.selectedAnswer.setValue({ id: chosenAnswerId, type, isBlocked: true }, { emitEvent: false });
1171
- }
1172
- get isRadioBlocked() {
1173
- return this.areAnswersBlocked || this.areAnswersRevealed || this.isCheckingMode;
1174
1161
  }
1175
1162
  getAnswerNotes(question) {
1176
- return (question.closedContent?.answers ?? []).map(answer => {
1163
+ return question.closedContent?.answers.map(answer => {
1177
1164
  if (answer.note)
1178
1165
  return answer.note;
1179
1166
  });
1180
1167
  }
1181
1168
  convertToOptions() {
1182
- return this.questionAnswers.map(answer => ({ id: answer.id, name: answer.content }));
1183
- }
1184
- getChosenAnswerId() {
1185
- const selectedAnswerByInput = (this.userAnswers ?? []).find(userAnswer => userAnswer?.isChosen !== false);
1186
- if (selectedAnswerByInput?.id)
1187
- return selectedAnswerByInput.id;
1188
- const selectedAnswerByQuizData = this.quizData?.userAnswers?.find((userAnswer) => userAnswer.id === this.question.id)
1189
- ?.userAnswers?.find(answer => answer?.isChosen !== false);
1190
- return selectedAnswerByQuizData?.id;
1169
+ return this.question.closedContent?.answers.map(answer => ({ id: answer.id, name: answer.content }));
1191
1170
  }
1192
1171
  isCheckedAnswerCorrect(answerId, quizData) {
1193
1172
  return quizData.questions.find((question) => question.closedContent?.answers?.find((answer) => answer.id === answerId)?.isCorrect);
1194
1173
  }
1195
- _onAnswerSelected(answerId) {
1196
- if (!answerId)
1197
- return;
1198
- this.onAnswersChange.emit([{
1199
- id: answerId,
1200
- index: this.questionAnswers.findIndex(answer => answer.id === answerId),
1201
- isChosen: true
1202
- }]);
1174
+ ngOnInit() {
1175
+ this.selectedAnswer.valueChanges.pipe(takeUntil$1(this.destroySubject$))
1176
+ .subscribe(result => {
1177
+ if (result)
1178
+ this.onAnswersChange.emit([{
1179
+ id: result.id,
1180
+ index: this.question.closedContent?.answers.findIndex(answer => answer.id == result.id),
1181
+ isChosen: true
1182
+ }]);
1183
+ });
1203
1184
  }
1204
- get questionAnswers() {
1205
- return this.question?.closedContent?.answers ?? [];
1185
+ ngOnDestroy() {
1186
+ this.destroySubject$.next(null);
1187
+ this.destroySubject$.complete();
1206
1188
  }
1207
1189
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QuizOneAnswerQuestionComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1208
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: QuizOneAnswerQuestionComponent, isStandalone: false, selector: "quiz-one-answer-question", inputs: { instructionTitle: "instructionTitle", question: "question", userAnswers: "userAnswers", quizData: "quizData", areAnswersRevealed: "areAnswersRevealed", areAnswersBlocked: "areAnswersBlocked", isCheckingMode: "isCheckingMode" }, outputs: { onAnswersChange: "onAnswersChange" }, usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"instructionTitle\" class=\"instruction-title\">{{ instructionTitle }}</div>\r\n\r\n<herum-radio-button [options]=\"convertedOptions\" [secondarySelectedOption]=\"correctAnswer\"\r\n [showAdditionalOptionsText]=\"areAnswersRevealed || isCheckingMode\" [isBlocked]=\"areAnswersBlocked\"\r\n [isVertical]=\"true\" [formControl]=\"selectedAnswer\" (selectOptionEmitter)=\"_onAnswerSelected($event)\"\r\n [ngClass]=\"{'revealed-answers':areAnswersRevealed || isCheckingMode}\" [additionalOptionsText]=\"answerNotes\">\r\n</herum-radio-button>", styles: ["", ".quiz-container{display:flex;flex-direction:column;gap:16px}.quiz-container p,.quiz-container b{font-size:16px;margin-bottom:.25rem}.quiz-container .quiz-title{font-weight:700}.quiz-container .error-message{color:var(--error-color);font-weight:700}.quiz-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container{display:flex;flex-direction:column;gap:16px}.answers-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container .answer-note{background-color:var(--light-text-color);border-radius:var(border-radius);font-size:14px}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: HerumRadioButtonComponent, selector: "herum-radio-button", inputs: ["options", "isValid", "errorMsg", "isVertical", "isBlocked", "type", "selectedOption", "additionalOptionsText", "showAdditionalOptionsText", "secondarySelectedOption"], outputs: ["selectOptionEmitter"] }] });
1190
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: QuizOneAnswerQuestionComponent, isStandalone: false, selector: "quiz-one-answer-question", inputs: { instructionTitle: "instructionTitle", question: "question", userAnswers: "userAnswers", quizData: "quizData", areAnswersRevealed: "areAnswersRevealed", areAnswersBlocked: "areAnswersBlocked", isCheckingMode: "isCheckingMode" }, outputs: { onAnswersChange: "onAnswersChange" }, usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"instructionTitle\" class=\"instruction-title\">{{ instructionTitle }}</div>\r\n\r\n<herum-radio-button [options]=\"convertedOptions\" [secondarySelectedOption]=\"correctAnswer\"\r\n [showAdditionalOptionsText]=\"areAnswersRevealed || isCheckingMode\" [isBlocked]=\"areAnswersBlocked\"\r\n [isVertical]=\"true\" [formControl]=\"selectedAnswer\"\r\n [ngClass]=\"{'revealed-answers':areAnswersRevealed || isCheckingMode}\" [additionalOptionsText]=\"answerNotes\">\r\n</herum-radio-button>", styles: ["", ".quiz-container{display:flex;flex-direction:column;gap:16px}.quiz-container p,.quiz-container b{font-size:16px;margin-bottom:.25rem}.quiz-container .quiz-title{font-weight:700}.quiz-container .error-message{color:var(--error-color);font-weight:700}.quiz-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container{display:flex;flex-direction:column;gap:16px}.answers-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container .answer-note{background-color:var(--light-text-color);border-radius:var(border-radius);font-size:14px}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: HerumRadioButtonComponent, selector: "herum-radio-button", inputs: ["options", "isValid", "errorMsg", "isVertical", "isBlocked", "type", "selectedOption", "additionalOptionsText", "showAdditionalOptionsText", "secondarySelectedOption"], outputs: ["selectOptionEmitter"] }] });
1209
1191
  }
1210
1192
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QuizOneAnswerQuestionComponent, decorators: [{
1211
1193
  type: Component,
1212
- args: [{ standalone: false, selector: 'quiz-one-answer-question', template: "<div *ngIf=\"instructionTitle\" class=\"instruction-title\">{{ instructionTitle }}</div>\r\n\r\n<herum-radio-button [options]=\"convertedOptions\" [secondarySelectedOption]=\"correctAnswer\"\r\n [showAdditionalOptionsText]=\"areAnswersRevealed || isCheckingMode\" [isBlocked]=\"areAnswersBlocked\"\r\n [isVertical]=\"true\" [formControl]=\"selectedAnswer\" (selectOptionEmitter)=\"_onAnswerSelected($event)\"\r\n [ngClass]=\"{'revealed-answers':areAnswersRevealed || isCheckingMode}\" [additionalOptionsText]=\"answerNotes\">\r\n</herum-radio-button>", styles: [".quiz-container{display:flex;flex-direction:column;gap:16px}.quiz-container p,.quiz-container b{font-size:16px;margin-bottom:.25rem}.quiz-container .quiz-title{font-weight:700}.quiz-container .error-message{color:var(--error-color);font-weight:700}.quiz-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container{display:flex;flex-direction:column;gap:16px}.answers-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container .answer-note{background-color:var(--light-text-color);border-radius:var(border-radius);font-size:14px}\n"] }]
1194
+ args: [{ standalone: false, selector: 'quiz-one-answer-question', template: "<div *ngIf=\"instructionTitle\" class=\"instruction-title\">{{ instructionTitle }}</div>\r\n\r\n<herum-radio-button [options]=\"convertedOptions\" [secondarySelectedOption]=\"correctAnswer\"\r\n [showAdditionalOptionsText]=\"areAnswersRevealed || isCheckingMode\" [isBlocked]=\"areAnswersBlocked\"\r\n [isVertical]=\"true\" [formControl]=\"selectedAnswer\"\r\n [ngClass]=\"{'revealed-answers':areAnswersRevealed || isCheckingMode}\" [additionalOptionsText]=\"answerNotes\">\r\n</herum-radio-button>", styles: [".quiz-container{display:flex;flex-direction:column;gap:16px}.quiz-container p,.quiz-container b{font-size:16px;margin-bottom:.25rem}.quiz-container .quiz-title{font-weight:700}.quiz-container .error-message{color:var(--error-color);font-weight:700}.quiz-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container{display:flex;flex-direction:column;gap:16px}.answers-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container .answer-note{background-color:var(--light-text-color);border-radius:var(border-radius);font-size:14px}\n"] }]
1213
1195
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { instructionTitle: [{
1214
1196
  type: Input
1215
1197
  }], question: [{
@@ -1422,37 +1404,30 @@ class QuizMultiAnswerQuestionComponent {
1422
1404
  this.answersForm = this.fb.group({});
1423
1405
  }
1424
1406
  ngOnChanges(changes) {
1425
- if (!this.question)
1426
- return;
1427
- if (changes['question']?.currentValue)
1428
- this.initQuestionFormControls();
1429
- else if (changes['userAnswers'] || changes['quizData'] || changes['areAnswersRevealed'] || changes['isCheckingMode'])
1430
- this.syncQuestionFormControls();
1431
- if (this.areAnswersRevealed || this.isCheckingMode)
1432
- this.setAnswerTypeAttributes();
1433
- else
1434
- this.answerTypeAttributes = [];
1435
- if (this.correctAnswerCount === null || this.correctAnswerCount === undefined)
1436
- this.correctAnswerCount = this.questionAnswers.filter(answer => answer.isCorrect).length;
1437
- }
1438
- initQuestionFormControls() {
1439
- this.answersForm = this.fb.group({});
1440
- this.questionAnswers.forEach((answer, index) => {
1441
- const controlName = `${this.controlNamePrefix}${index}`;
1442
- this.answersForm.addControl(controlName, new FormControl(this.getFormControlValue(index)));
1443
- this.answersForm.get(controlName).valueChanges
1444
- .pipe(takeUntil(this.destroySubject$))
1445
- .subscribe((value) => this._onAnswersChange(this.questionAnswers[index], this.toIsChosen(value)));
1446
- });
1447
- }
1448
- syncQuestionFormControls() {
1449
- this.questionAnswers.forEach((answer, index) => {
1450
- const controlName = `${this.controlNamePrefix}${index}`;
1451
- this.answersForm.get(controlName)?.setValue(this.getFormControlValue(index), { emitEvent: false });
1452
- });
1407
+ if (changes['question'] && this.question) {
1408
+ if (!Object.keys(this.answersForm.controls).length) {
1409
+ this.question.closedContent.answers.forEach((answer, index) => {
1410
+ const controlName = `${this.controlNamePrefix}${index}`;
1411
+ this.answersForm.addControl(controlName, new FormControl(this.getFormControlValue(index)));
1412
+ this.answersForm.get(controlName).valueChanges
1413
+ .pipe(takeUntil(this.destroySubject$))
1414
+ .subscribe((isChosen) => this._onAnswersChange(this.question.closedContent.answers[index], isChosen));
1415
+ });
1416
+ }
1417
+ else {
1418
+ this.question.closedContent.answers.forEach((answer, index) => {
1419
+ const controlName = `${this.controlNamePrefix}${index}`;
1420
+ this.answersForm.controls[controlName].setValue(this.getFormControlValue(index), { emitEvent: false });
1421
+ });
1422
+ }
1423
+ if (this.areAnswersRevealed || this.isCheckingMode)
1424
+ this.setAnswerTypeAttributes();
1425
+ if (this.correctAnswerCount === null || this.correctAnswerCount === undefined)
1426
+ this.correctAnswerCount = this.question.closedContent.answers.filter(answer => answer.isCorrect).length;
1427
+ }
1453
1428
  }
1454
1429
  setAnswerTypeAttributes() {
1455
- this.answerTypeAttributes = this.questionAnswers.map((answer, index) => {
1430
+ this.answerTypeAttributes = this.question.closedContent.answers.map((answer, index) => {
1456
1431
  const answerForm = this.answersForm.value[`${this.controlNamePrefix}` + index];
1457
1432
  return (!answerForm.type && this.iAnswerCorrect(answer.id, this.quizData)) ?
1458
1433
  'correct-not-selected' :
@@ -1464,8 +1439,7 @@ class QuizMultiAnswerQuestionComponent {
1464
1439
  currentCheckbox._onClick();
1465
1440
  }
1466
1441
  _isAnswerChecked(answerId) {
1467
- const answer = this.userAnswers.find(userAnswer => userAnswer.id == answerId);
1468
- return answer ? answer.isChosen !== false : false;
1442
+ return this.userAnswers.find(userAnswer => userAnswer.id == answerId)?.isChosen;
1469
1443
  }
1470
1444
  getTypeCheckbox(answerId) {
1471
1445
  if (!this._isAnswerChecked(answerId))
@@ -1476,36 +1450,27 @@ class QuizMultiAnswerQuestionComponent {
1476
1450
  return this.iAnswerCorrect(answerId, this.quizData) ? checkboxTypes$1.checked : checkboxTypes$1.error;
1477
1451
  }
1478
1452
  iAnswerCorrect(answerId, quizData) {
1479
- return quizData.questions.find((question) => question.closedContent?.answers?.find((answer) => answer.id === answerId)?.isCorrect);
1453
+ return quizData.questions.find((question) => question.closedContent.answers?.find((answer) => answer.id === answerId)?.isCorrect);
1480
1454
  }
1481
1455
  _onAnswersChange(answer, isChosen) {
1482
- const selectedUserAnswers = [...(this.userAnswers ?? [])].filter(userAnswer => userAnswer?.isChosen !== false);
1483
- const userAnswer = selectedUserAnswers.find(currentUserAnswer => currentUserAnswer.id == answer.id);
1484
- if (userAnswer)
1485
- userAnswer.isChosen = isChosen;
1486
- else {
1487
- selectedUserAnswers.push({
1456
+ let userAnswer = this.userAnswers.find(userAnswer => userAnswer.id == answer.id);
1457
+ userAnswer ? (userAnswer.isChosen = isChosen) :
1458
+ this.userAnswers.push({
1488
1459
  id: answer.id,
1489
1460
  index: answer.index,
1490
1461
  isChosen
1491
1462
  });
1492
- }
1493
- const normalizedUserAnswers = selectedUserAnswers.filter(currentUserAnswer => currentUserAnswer?.isChosen !== false);
1494
- this.isValid = normalizedUserAnswers.length == this.correctAnswerCount;
1495
- this.onAnswersChange.emit(normalizedUserAnswers);
1463
+ this.isValid = this.userAnswers.length == this.correctAnswerCount;
1464
+ this.onAnswersChange.emit(this.userAnswers);
1496
1465
  this.onValidationChange.emit(this.isValid);
1497
1466
  }
1498
1467
  getFormControlValue(index) {
1468
+ const id = this.question.closedContent.answers[index].id;
1499
1469
  return {
1500
- type: this.getTypeCheckbox(this.questionAnswers[index].id),
1501
- isChecked: this._isAnswerChecked(this.questionAnswers[index].id)
1470
+ type: this.getTypeCheckbox(id),
1471
+ isChecked: this._isAnswerChecked(id)
1502
1472
  };
1503
1473
  }
1504
- toIsChosen(value) {
1505
- if (typeof value === 'boolean')
1506
- return value;
1507
- return !!value?.isChecked;
1508
- }
1509
1474
  get controlNamePrefix() {
1510
1475
  return 'controlName';
1511
1476
  }
@@ -1513,19 +1478,16 @@ class QuizMultiAnswerQuestionComponent {
1513
1478
  get isBlocked() {
1514
1479
  return this.quizData?.isSubmitted || this.areAnswersBlocked || this.areAnswersRevealed;
1515
1480
  }
1516
- get questionAnswers() {
1517
- return this.question?.closedContent?.answers ?? [];
1518
- }
1519
1481
  ngOnDestroy() {
1520
1482
  this.destroySubject$.next(null);
1521
1483
  this.destroySubject$.complete();
1522
1484
  }
1523
1485
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QuizMultiAnswerQuestionComponent, deps: [{ token: i1$2.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
1524
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: QuizMultiAnswerQuestionComponent, isStandalone: false, selector: "quiz-multi-answer-question", inputs: { question: "question", quizData: "quizData", userAnswers: "userAnswers", isCheckingMode: "isCheckingMode", areAnswersRevealed: "areAnswersRevealed", areAnswersBlocked: "areAnswersBlocked", correctAnswerCount: "correctAnswerCount" }, outputs: { onAnswersChange: "onAnswersChange", onValidationChange: "onValidationChange" }, viewQueries: [{ propertyName: "checkboxes", predicate: HerumCheckboxComponent$1, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"main-container\">\r\n <p class=\"correct-answer-count\">\u05D9\u05E9 \u05DC\u05E1\u05DE\u05DF {{ correctAnswerCount }} \u05EA\u05E9\u05D5\u05D1\u05D5\u05EA</p>\r\n\r\n <form *ngIf=\"questionAnswers.length\" [formGroup]=\"answersForm\" class=\"answers-container\">\r\n <div class=\"answer-item\" *ngFor=\"let answer of questionAnswers;let i=index\">\r\n <div class=\"answer-container\" [ngClass]=\"{'revealed-answers':(areAnswersRevealed || isCheckingMode)}\"\r\n [attr.type]=\"(areAnswersRevealed || isCheckingMode) ? answerTypeAttributes[i] : ''\"\r\n [attr.includes-additional-option-text]=\"(additionalOptionsText && additionalOptionsText[i]) ? 'true' : 'false'\">\r\n <herum-checkbox [isBlocked]=\"isBlocked\" [formControlName]=\"controlNamePrefix + i\"\r\n [id]=\"controlNamePrefix + i\">\r\n </herum-checkbox>\r\n\r\n <p class=\"answer-text cursor-pointer\" [ngClass]=\"{'cursor-pointer':!isBlocked}\"\r\n (click)=\"_onAnswerClicked(i)\">{{ answer.content }}</p>\r\n </div>\r\n\r\n <span *ngIf=\"answer.note && (areAnswersRevealed || isCheckingMode)\" class=\"answer-note\">\r\n {{ answer.note }}\r\n </span>\r\n </div>\r\n </form>\r\n</div>", styles: [".answer-text{line-height:1;font-size:14px;font-weight:700}.correct-answer-count{margin-block-end:0;font-size:14px}.answers-container,.main-container{display:flex;flex-direction:column;gap:8px;width:100%}.answer-container{display:flex;align-items:center;gap:8px}.answer-container,.answer-note{flex:1}\n", ".quiz-container{display:flex;flex-direction:column;gap:16px}.quiz-container p,.quiz-container b{font-size:16px;margin-bottom:.25rem}.quiz-container .quiz-title{font-weight:700}.quiz-container .error-message{color:var(--error-color);font-weight:700}.quiz-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container{display:flex;flex-direction:column;gap:16px}.answers-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container .answer-note{background-color:var(--light-text-color);border-radius:var(border-radius);font-size:14px}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: HerumCheckboxComponent, selector: "herum-checkbox", inputs: ["type", "isChecked", "isBlocked"], outputs: ["checkedEmitter"] }] });
1486
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: QuizMultiAnswerQuestionComponent, isStandalone: false, selector: "quiz-multi-answer-question", inputs: { question: "question", quizData: "quizData", userAnswers: "userAnswers", isCheckingMode: "isCheckingMode", areAnswersRevealed: "areAnswersRevealed", areAnswersBlocked: "areAnswersBlocked", correctAnswerCount: "correctAnswerCount" }, outputs: { onAnswersChange: "onAnswersChange", onValidationChange: "onValidationChange" }, viewQueries: [{ propertyName: "checkboxes", predicate: HerumCheckboxComponent$1, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"main-container\">\r\n <p class=\"correct-answer-count\">\u05D9\u05E9 \u05DC\u05E1\u05DE\u05DF {{ correctAnswerCount }} \u05EA\u05E9\u05D5\u05D1\u05D5\u05EA</p>\r\n\r\n <form *ngIf=\"question.closedContent.answers\" [formGroup]=\"answersForm\" class=\"answers-container\">\r\n <div class=\"answer-item\" *ngFor=\"let answer of question.closedContent.answers;let i=index\">\r\n <div class=\"answer-container\" [ngClass]=\"{'revealed-answers':(areAnswersRevealed || isCheckingMode)}\"\r\n [attr.type]=\"(areAnswersRevealed || isCheckingMode) ? answerTypeAttributes[i] : ''\"\r\n [attr.includes-additional-option-text]=\"(additionalOptionsText && additionalOptionsText[i]) ? 'true' : 'false'\">\r\n <herum-checkbox [isBlocked]=\"isBlocked\" [formControlName]=\"controlNamePrefix + i\"\r\n [id]=\"controlNamePrefix + i\">\r\n </herum-checkbox>\r\n\r\n <p class=\"answer-text cursor-pointer\" [ngClass]=\"{'cursor-pointer':!isBlocked}\"\r\n (click)=\"_onAnswerClicked(i)\">{{ answer.content }}</p>\r\n </div>\r\n\r\n <span *ngIf=\"answer.note && (areAnswersRevealed || isCheckingMode)\" class=\"answer-note\">\r\n {{ answer.note }}\r\n </span>\r\n </div>\r\n </form>\r\n</div>", styles: [".answer-text{line-height:1;font-size:14px;font-weight:700}.correct-answer-count{margin-block-end:0;font-size:14px}.answers-container,.main-container{display:flex;flex-direction:column;gap:8px;width:100%}.answer-container{display:flex;align-items:center;gap:8px}.answer-container,.answer-note{flex:1}\n", ".quiz-container{display:flex;flex-direction:column;gap:16px}.quiz-container p,.quiz-container b{font-size:16px;margin-bottom:.25rem}.quiz-container .quiz-title{font-weight:700}.quiz-container .error-message{color:var(--error-color);font-weight:700}.quiz-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container{display:flex;flex-direction:column;gap:16px}.answers-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container .answer-note{background-color:var(--light-text-color);border-radius:var(border-radius);font-size:14px}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: HerumCheckboxComponent, selector: "herum-checkbox", inputs: ["type", "isChecked", "isBlocked"], outputs: ["checkedEmitter"] }] });
1525
1487
  }
1526
1488
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QuizMultiAnswerQuestionComponent, decorators: [{
1527
1489
  type: Component,
1528
- args: [{ standalone: false, selector: 'quiz-multi-answer-question', template: "<div class=\"main-container\">\r\n <p class=\"correct-answer-count\">\u05D9\u05E9 \u05DC\u05E1\u05DE\u05DF {{ correctAnswerCount }} \u05EA\u05E9\u05D5\u05D1\u05D5\u05EA</p>\r\n\r\n <form *ngIf=\"questionAnswers.length\" [formGroup]=\"answersForm\" class=\"answers-container\">\r\n <div class=\"answer-item\" *ngFor=\"let answer of questionAnswers;let i=index\">\r\n <div class=\"answer-container\" [ngClass]=\"{'revealed-answers':(areAnswersRevealed || isCheckingMode)}\"\r\n [attr.type]=\"(areAnswersRevealed || isCheckingMode) ? answerTypeAttributes[i] : ''\"\r\n [attr.includes-additional-option-text]=\"(additionalOptionsText && additionalOptionsText[i]) ? 'true' : 'false'\">\r\n <herum-checkbox [isBlocked]=\"isBlocked\" [formControlName]=\"controlNamePrefix + i\"\r\n [id]=\"controlNamePrefix + i\">\r\n </herum-checkbox>\r\n\r\n <p class=\"answer-text cursor-pointer\" [ngClass]=\"{'cursor-pointer':!isBlocked}\"\r\n (click)=\"_onAnswerClicked(i)\">{{ answer.content }}</p>\r\n </div>\r\n\r\n <span *ngIf=\"answer.note && (areAnswersRevealed || isCheckingMode)\" class=\"answer-note\">\r\n {{ answer.note }}\r\n </span>\r\n </div>\r\n </form>\r\n</div>", styles: [".answer-text{line-height:1;font-size:14px;font-weight:700}.correct-answer-count{margin-block-end:0;font-size:14px}.answers-container,.main-container{display:flex;flex-direction:column;gap:8px;width:100%}.answer-container{display:flex;align-items:center;gap:8px}.answer-container,.answer-note{flex:1}\n", ".quiz-container{display:flex;flex-direction:column;gap:16px}.quiz-container p,.quiz-container b{font-size:16px;margin-bottom:.25rem}.quiz-container .quiz-title{font-weight:700}.quiz-container .error-message{color:var(--error-color);font-weight:700}.quiz-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container{display:flex;flex-direction:column;gap:16px}.answers-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container .answer-note{background-color:var(--light-text-color);border-radius:var(border-radius);font-size:14px}\n"] }]
1490
+ args: [{ standalone: false, selector: 'quiz-multi-answer-question', template: "<div class=\"main-container\">\r\n <p class=\"correct-answer-count\">\u05D9\u05E9 \u05DC\u05E1\u05DE\u05DF {{ correctAnswerCount }} \u05EA\u05E9\u05D5\u05D1\u05D5\u05EA</p>\r\n\r\n <form *ngIf=\"question.closedContent.answers\" [formGroup]=\"answersForm\" class=\"answers-container\">\r\n <div class=\"answer-item\" *ngFor=\"let answer of question.closedContent.answers;let i=index\">\r\n <div class=\"answer-container\" [ngClass]=\"{'revealed-answers':(areAnswersRevealed || isCheckingMode)}\"\r\n [attr.type]=\"(areAnswersRevealed || isCheckingMode) ? answerTypeAttributes[i] : ''\"\r\n [attr.includes-additional-option-text]=\"(additionalOptionsText && additionalOptionsText[i]) ? 'true' : 'false'\">\r\n <herum-checkbox [isBlocked]=\"isBlocked\" [formControlName]=\"controlNamePrefix + i\"\r\n [id]=\"controlNamePrefix + i\">\r\n </herum-checkbox>\r\n\r\n <p class=\"answer-text cursor-pointer\" [ngClass]=\"{'cursor-pointer':!isBlocked}\"\r\n (click)=\"_onAnswerClicked(i)\">{{ answer.content }}</p>\r\n </div>\r\n\r\n <span *ngIf=\"answer.note && (areAnswersRevealed || isCheckingMode)\" class=\"answer-note\">\r\n {{ answer.note }}\r\n </span>\r\n </div>\r\n </form>\r\n</div>", styles: [".answer-text{line-height:1;font-size:14px;font-weight:700}.correct-answer-count{margin-block-end:0;font-size:14px}.answers-container,.main-container{display:flex;flex-direction:column;gap:8px;width:100%}.answer-container{display:flex;align-items:center;gap:8px}.answer-container,.answer-note{flex:1}\n", ".quiz-container{display:flex;flex-direction:column;gap:16px}.quiz-container p,.quiz-container b{font-size:16px;margin-bottom:.25rem}.quiz-container .quiz-title{font-weight:700}.quiz-container .error-message{color:var(--error-color);font-weight:700}.quiz-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container{display:flex;flex-direction:column;gap:16px}.answers-container .answer-item{display:flex;flex-direction:row;gap:8px}.answers-container .answer-note{background-color:var(--light-text-color);border-radius:var(border-radius);font-size:14px}\n"] }]
1529
1491
  }], ctorParameters: () => [{ type: i1$2.FormBuilder }], propDecorators: { question: [{
1530
1492
  type: Input
1531
1493
  }], quizData: [{
@@ -1587,8 +1549,7 @@ class HerumQuizComponent {
1587
1549
  isCorrect: true,
1588
1550
  index: 1
1589
1551
  }
1590
- ],
1591
- numberOfCorrectAnswers: 1
1552
+ ]
1592
1553
  }
1593
1554
  }
1594
1555
  ]
@@ -1598,7 +1559,7 @@ class HerumQuizComponent {
1598
1559
  constructor(changeDetectorRef) {
1599
1560
  this.changeDetectorRef = changeDetectorRef;
1600
1561
  }
1601
- ngOnChanges(changes) {
1562
+ ngOnChanges() {
1602
1563
  this.mergeQuizUserDataIntoQuizData();
1603
1564
  this.quizData.currentQuestion = this.quizData.isSubmitted ? this.quizData.questions.length + 2 : this.quizData.currentQuestion ? this.quizData.currentQuestion : 0;
1604
1565
  }
@@ -1610,7 +1571,7 @@ class HerumQuizComponent {
1610
1571
  return true;
1611
1572
  if (this.currentQuestionIndex >= this.quizData.questions.length)
1612
1573
  return this.isValidQuiz;
1613
- return this._getUserAnswers(this.quizData.questions[this.currentQuestionIndex]?.id).length === this.getCorrectAnswersCount(this.quizData.questions?.find((userAnswer) => userAnswer.id === this.quizData.questions[this.currentQuestionIndex]?.id));
1574
+ return this._getUserAnswers(this.quizData.questions[this.currentQuestionIndex]?.id).length == this.getCorrectAnswersCount(this.quizData.questions?.find((userAnswer) => userAnswer.id == this.quizData.questions[this.currentQuestionIndex]?.id));
1614
1575
  }
1615
1576
  get nextButtonText() {
1616
1577
  switch (this.quizData.currentQuestion) {
@@ -1640,13 +1601,12 @@ class HerumQuizComponent {
1640
1601
  .filter(userQuestionAnswer => userQuestionAnswer.userAnswers.some(userAnswer => userAnswer.isChosen)).length;
1641
1602
  }
1642
1603
  get isLastQuestion() {
1643
- return this.quizData.currentQuestion === this.quizData.questions.length + 1;
1604
+ return this.quizData.currentQuestion == this.quizData.questions.length + 1;
1644
1605
  }
1645
1606
  getCorrectAnswersCount(question) {
1646
1607
  if (!question?.closedContent?.answers?.length)
1647
1608
  return 0;
1648
- return question.closedContent.numberOfCorrectAnswers ??
1649
- question.closedContent.answers.filter((answer) => answer.isCorrect).length;
1609
+ return question.closedContent.answers.filter((answer) => answer.isCorrect).length;
1650
1610
  }
1651
1611
  _nextQuestion(isSkipped = false) {
1652
1612
  this.isCurrentQuestionValid = false;
@@ -5018,7 +4978,7 @@ class QuizOpenAnswerQuestionComponent {
5018
4978
  selectedTextChange;
5019
4979
  answerChange = new EventEmitter();
5020
4980
  notesChange = new EventEmitter();
5021
- correctAnswerControl = new FormControl('');
4981
+ freeTextControl = new FormControl('');
5022
4982
  notes;
5023
4983
  destroySubject$ = new Subject();
5024
4984
  constructor(answerNotesToTextChangesPipe) {
@@ -5026,13 +4986,13 @@ class QuizOpenAnswerQuestionComponent {
5026
4986
  }
5027
4987
  ngOnChanges(changes) {
5028
4988
  if (changes['userQuestion']?.currentValue) {
5029
- this.correctAnswerControl.setValue(this.userQuestion.freeTextAnswer ?? '', { emitEvent: false });
4989
+ this.freeTextControl.setValue(this.userQuestion.freeTextAnswer ?? '', { emitEvent: false });
5030
4990
  if (this.isCheckingMode || this.areAnswersRevealed)
5031
4991
  this.notes = this.answerNotesToTextChangesPipe.transform(this.userQuestion.answerNotes ?? []);
5032
4992
  }
5033
4993
  }
5034
4994
  ngOnInit() {
5035
- this.correctAnswerControl.valueChanges.pipe(takeUntil(this.destroySubject$))
4995
+ this.freeTextControl.valueChanges.pipe(takeUntil(this.destroySubject$))
5036
4996
  .subscribe(freeText => this.answerChange.emit(freeText));
5037
4997
  }
5038
4998
  _notesChange(notes) {
@@ -5043,11 +5003,11 @@ class QuizOpenAnswerQuestionComponent {
5043
5003
  this.destroySubject$.complete();
5044
5004
  }
5045
5005
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QuizOpenAnswerQuestionComponent, deps: [{ token: i4$1.AnswerNotesToTextChangesPipe }], target: i0.ɵɵFactoryTarget.Component });
5046
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: QuizOpenAnswerQuestionComponent, isStandalone: false, selector: "quiz-open-answer-question", inputs: { previewMode: "previewMode", question: "question", userQuestion: "userQuestion", areAnswersRevealed: "areAnswersRevealed", areAnswersBlocked: "areAnswersBlocked", isCheckingMode: "isCheckingMode", selectedTextChange: "selectedTextChange" }, outputs: { answerChange: "answerChange", notesChange: "notesChange" }, usesOnChanges: true, ngImport: i0, template: "<span class=\"answer-title\">{{ isCheckingMode ? '\u05EA\u05E9\u05D5\u05D1\u05EA \u05D4\u05D7\u05E0\u05D9\u05DA' : '\u05DB\u05EA\u05D5\u05D1 \u05EA\u05E9\u05D5\u05D1\u05EA\u05DA' }}\r\n <span *ngIf=\"!isCheckingMode && question?.freeAnswerContent?.charactersLimit > 0\">\r\n (\u05E2\u05D3 {{ question?.freeAnswerContent?.charactersLimit }} \u05EA\u05D5\u05D5\u05D9\u05DD)\r\n </span>\r\n</span>\r\n\r\n<herum-text-area *ngIf=\"!areAnswersRevealed && !isCheckingMode\" [disabled]=\"previewMode || areAnswersBlocked\"\r\n [maxLength]=\"question?.freeAnswerContent?.charactersLimit\" [formControl]=\"correctAnswerControl\" heightMode=\"max\">\r\n</herum-text-area>\r\n\r\n<track-text-changes *ngIf=\"isCheckingMode || areAnswersRevealed\"\r\n [isReadOnly]=\"areAnswersRevealed && !isCheckingMode || !isCheckingMode\" [fontSize]=\"14\"\r\n [selectedChange]=\"selectedTextChange\" [showComments]=\"false\" [baseContent]=\"correctAnswerControl.value\"\r\n [changes]=\"notes\" (changesEmitter)=\"_notesChange($event)\">\r\n</track-text-changes>", styles: [".answer-title{font-size:14px;margin-block-end:8px}herum-text-area,track-text-changes{height:100%;width:100%}::ng-deep track-text-changes .editor-container{padding:0}::ng-deep track-text-changes .text-editor{min-height:180px;height:100%;width:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: HerumTextAreaComponent, selector: "herum-text-area", inputs: ["placeholder", "disabled", "formControlName", "isValid", "isLoading", "errorMsg", "showErrorMsgGap", "id", "preventMacroKeysPressEvent", "heightMode", "fontSize", "inputValue", "maxLength"], outputs: ["inputValueEmitter"] }, { kind: "component", type: TrackTextChangesComponent, selector: "track-text-changes", inputs: ["changes", "selectedChange", "currentUser", "baseContent", "isReadOnly", "fontSize", "showComments", "allowedActions"], outputs: ["changesEmitter"] }] });
5006
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: QuizOpenAnswerQuestionComponent, isStandalone: false, selector: "quiz-open-answer-question", inputs: { previewMode: "previewMode", question: "question", userQuestion: "userQuestion", areAnswersRevealed: "areAnswersRevealed", areAnswersBlocked: "areAnswersBlocked", isCheckingMode: "isCheckingMode", selectedTextChange: "selectedTextChange" }, outputs: { answerChange: "answerChange", notesChange: "notesChange" }, usesOnChanges: true, ngImport: i0, template: "<span class=\"answer-title\">{{ isCheckingMode ? '\u05EA\u05E9\u05D5\u05D1\u05EA \u05D4\u05D7\u05E0\u05D9\u05DA' : '\u05DB\u05EA\u05D5\u05D1 \u05EA\u05E9\u05D5\u05D1\u05EA\u05DA' }}\r\n <span *ngIf=\"!isCheckingMode && question?.freeAnswerContent?.charactersLimit > 0\">\r\n (\u05E2\u05D3 {{ question?.freeAnswerContent?.charactersLimit }} \u05EA\u05D5\u05D5\u05D9\u05DD)\r\n </span>\r\n</span>\r\n\r\n<herum-text-area *ngIf=\"!areAnswersRevealed && !isCheckingMode\" [disabled]=\"previewMode || areAnswersBlocked\"\r\n [maxLength]=\"question?.freeAnswerContent?.charactersLimit\" [formControl]=\"freeTextControl\" heightMode=\"max\">\r\n</herum-text-area>\r\n\r\n<track-text-changes *ngIf=\"isCheckingMode || areAnswersRevealed\"\r\n [isReadOnly]=\"areAnswersRevealed && !isCheckingMode || !isCheckingMode\" [fontSize]=\"14\"\r\n [selectedChange]=\"selectedTextChange\" [showComments]=\"false\" [baseContent]=\"freeTextControl.value\"\r\n [changes]=\"notes\" (changesEmitter)=\"_notesChange($event)\">\r\n</track-text-changes>", styles: [".answer-title{font-size:14px;margin-block-end:8px}herum-text-area,track-text-changes{height:100%;width:100%}::ng-deep track-text-changes .editor-container{padding:0}::ng-deep track-text-changes .text-editor{min-height:180px;height:100%;width:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: HerumTextAreaComponent, selector: "herum-text-area", inputs: ["placeholder", "disabled", "formControlName", "isValid", "isLoading", "errorMsg", "showErrorMsgGap", "id", "preventMacroKeysPressEvent", "heightMode", "fontSize", "inputValue", "maxLength"], outputs: ["inputValueEmitter"] }, { kind: "component", type: TrackTextChangesComponent, selector: "track-text-changes", inputs: ["changes", "selectedChange", "currentUser", "baseContent", "isReadOnly", "fontSize", "showComments", "allowedActions"], outputs: ["changesEmitter"] }] });
5047
5007
  }
5048
5008
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QuizOpenAnswerQuestionComponent, decorators: [{
5049
5009
  type: Component,
5050
- args: [{ standalone: false, selector: 'quiz-open-answer-question', template: "<span class=\"answer-title\">{{ isCheckingMode ? '\u05EA\u05E9\u05D5\u05D1\u05EA \u05D4\u05D7\u05E0\u05D9\u05DA' : '\u05DB\u05EA\u05D5\u05D1 \u05EA\u05E9\u05D5\u05D1\u05EA\u05DA' }}\r\n <span *ngIf=\"!isCheckingMode && question?.freeAnswerContent?.charactersLimit > 0\">\r\n (\u05E2\u05D3 {{ question?.freeAnswerContent?.charactersLimit }} \u05EA\u05D5\u05D5\u05D9\u05DD)\r\n </span>\r\n</span>\r\n\r\n<herum-text-area *ngIf=\"!areAnswersRevealed && !isCheckingMode\" [disabled]=\"previewMode || areAnswersBlocked\"\r\n [maxLength]=\"question?.freeAnswerContent?.charactersLimit\" [formControl]=\"correctAnswerControl\" heightMode=\"max\">\r\n</herum-text-area>\r\n\r\n<track-text-changes *ngIf=\"isCheckingMode || areAnswersRevealed\"\r\n [isReadOnly]=\"areAnswersRevealed && !isCheckingMode || !isCheckingMode\" [fontSize]=\"14\"\r\n [selectedChange]=\"selectedTextChange\" [showComments]=\"false\" [baseContent]=\"correctAnswerControl.value\"\r\n [changes]=\"notes\" (changesEmitter)=\"_notesChange($event)\">\r\n</track-text-changes>", styles: [".answer-title{font-size:14px;margin-block-end:8px}herum-text-area,track-text-changes{height:100%;width:100%}::ng-deep track-text-changes .editor-container{padding:0}::ng-deep track-text-changes .text-editor{min-height:180px;height:100%;width:100%}\n"] }]
5010
+ args: [{ standalone: false, selector: 'quiz-open-answer-question', template: "<span class=\"answer-title\">{{ isCheckingMode ? '\u05EA\u05E9\u05D5\u05D1\u05EA \u05D4\u05D7\u05E0\u05D9\u05DA' : '\u05DB\u05EA\u05D5\u05D1 \u05EA\u05E9\u05D5\u05D1\u05EA\u05DA' }}\r\n <span *ngIf=\"!isCheckingMode && question?.freeAnswerContent?.charactersLimit > 0\">\r\n (\u05E2\u05D3 {{ question?.freeAnswerContent?.charactersLimit }} \u05EA\u05D5\u05D5\u05D9\u05DD)\r\n </span>\r\n</span>\r\n\r\n<herum-text-area *ngIf=\"!areAnswersRevealed && !isCheckingMode\" [disabled]=\"previewMode || areAnswersBlocked\"\r\n [maxLength]=\"question?.freeAnswerContent?.charactersLimit\" [formControl]=\"freeTextControl\" heightMode=\"max\">\r\n</herum-text-area>\r\n\r\n<track-text-changes *ngIf=\"isCheckingMode || areAnswersRevealed\"\r\n [isReadOnly]=\"areAnswersRevealed && !isCheckingMode || !isCheckingMode\" [fontSize]=\"14\"\r\n [selectedChange]=\"selectedTextChange\" [showComments]=\"false\" [baseContent]=\"freeTextControl.value\"\r\n [changes]=\"notes\" (changesEmitter)=\"_notesChange($event)\">\r\n</track-text-changes>", styles: [".answer-title{font-size:14px;margin-block-end:8px}herum-text-area,track-text-changes{height:100%;width:100%}::ng-deep track-text-changes .editor-container{padding:0}::ng-deep track-text-changes .text-editor{min-height:180px;height:100%;width:100%}\n"] }]
5051
5011
  }], ctorParameters: () => [{ type: i4$1.AnswerNotesToTextChangesPipe }], propDecorators: { previewMode: [{
5052
5012
  type: Input
5053
5013
  }], question: [{
@@ -9674,7 +9634,8 @@ class HerumSharedModule {
9674
9634
  PipesModule,
9675
9635
  ErrorsModule,
9676
9636
  FetchedMessageModule,
9677
- TableModule] });
9637
+ TableModule,
9638
+ AudioSliderComponent] });
9678
9639
  static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: HerumSharedModule, providers: [
9679
9640
  DatePipe,
9680
9641
  { provide: MAT_DATE_LOCALE, useValue: 'he-IL' },
@@ -9774,6 +9735,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
9774
9735
  ErrorsModule,
9775
9736
  FetchedMessageModule,
9776
9737
  TableModule,
9738
+ AudioSliderComponent
9777
9739
  ],
9778
9740
  imports: [
9779
9741
  CommonModule,
@@ -10748,8 +10710,7 @@ class UtilsService {
10748
10710
  if (!fileData?.key || !fileData?.bucket)
10749
10711
  return;
10750
10712
  const fileDataKeyWithoutTrailingSlash = fileData.key.endsWith('/') ? fileData.key.slice(0, -1) : fileData.key;
10751
- const s3ServerPathWithBucketName = this.environmentConfig?.environment?.s3ServerPath.replace(this.environmentConfig?.environment?.bucketPlaceholderKey, fileData.bucket);
10752
- return buildPath([s3ServerPathWithBucketName, fileDataKeyWithoutTrailingSlash]);
10713
+ return buildPath([this.environmentConfig?.environment?.s3ServerPath + fileData.bucket, fileDataKeyWithoutTrailingSlash]);
10753
10714
  }
10754
10715
  fetchFiles(fileId, resourceType, bucket) {
10755
10716
  if (!fileId)
@@ -14276,8 +14237,7 @@ const testEnvironmentConfig = {
14276
14237
  userAction: 'http://hadracha-site-server-augustus.apps.ocp4-prep.d8200.mil/api/Activity',
14277
14238
  lessonSocketBackend: "ws://college-site-server.d8200.mil/lesson",
14278
14239
  keyboardEventsLocalSocketPath: 'ws://localhost:3333',
14279
- systemIdentifier: "hadracha",
14280
- bucketPlaceholderKey: ''
14240
+ systemIdentifier: "hadracha"
14281
14241
  },
14282
14242
  mongoUpdates: {
14283
14243
  CollectionCategories: {