commons-assessment 12.1.0 → 12.1.2-dev.0
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.
- package/README.md +11 -0
- package/bundles/commons-assessment.umd.js +2304 -247
- package/bundles/commons-assessment.umd.js.map +1 -1
- package/esm2015/lib/modules/assessment-maker/assessment-maker.component.js +293 -32
- package/esm2015/lib/modules/assessment-maker/assessment-maker.module.js +10 -5
- package/esm2015/lib/modules/assessment-maker/components/add-edit-section-introduction/add-edit-section-introduction.component.js +1 -1
- package/esm2015/lib/modules/assessment-maker/components/assessment-builder/assessment-builder.component.js +77 -22
- package/esm2015/lib/modules/assessment-maker/components/question-bank-picker/question-bank-picker.component.js +276 -0
- package/esm2015/lib/modules/assessment-maker/components/question-details/question-details.component.js +22 -2
- package/esm2015/lib/modules/assessment-maker/services/assessment-builder.service.js +22 -7
- package/esm2015/lib/modules/assessment-maker/services/assessment-maker.service.js +32 -5
- package/esm2015/lib/modules/assessment-taker/assessment-taker.component.js +365 -42
- package/esm2015/lib/modules/assessment-taker/assessment-taker.module.js +9 -3
- package/esm2015/lib/modules/assessment-taker/components/proctoring-consent/proctoring-consent.component.js +137 -0
- package/esm2015/lib/modules/assessment-taker/components/proctoring-result/proctoring-result.component.js +177 -0
- package/esm2015/lib/modules/assessment-taker/components/question-type-date-picker/question-type-date-picker.component.js +2 -3
- package/esm2015/lib/modules/assessment-taker/components/question-type-editor/question-type-editor.component.js +1 -1
- package/esm2015/lib/modules/assessment-taker/components/question-type-file-upload/question-type-file-upload.component.js +5 -2
- package/esm2015/lib/modules/assessment-taker/components/question-type-long/question-type-long.component.js +1 -1
- package/esm2015/lib/modules/assessment-taker/components/question-type-multiselect/question-type-multiselect.component.js +7 -3
- package/esm2015/lib/modules/assessment-taker/components/question-type-objective/question-type-objective.component.js +7 -3
- package/esm2015/lib/modules/assessment-taker/components/question-type-preference/question-type-preference.component.js +9 -4
- package/esm2015/lib/modules/assessment-taker/components/question-type-short/question-type-short.component.js +78 -8
- package/esm2015/lib/modules/assessment-taker/components/section-instructions/section-instructions.component.js +1 -1
- package/esm2015/lib/modules/assessment-taker/services/assessment-taker.service.js +18 -3
- package/esm2015/lib/modules/assessment-taker/services/proctoring.service.js +125 -0
- package/esm2015/lib/modules/assessment-taker/services/response-builder.service.js +15 -1
- package/esm2015/lib/modules/question-bank/question-bank.component.js +313 -0
- package/esm2015/lib/modules/question-bank/question-bank.module.js +45 -0
- package/esm2015/lib/shared/components/confirmation-dialog/confirmation-dialog.component.js +56 -0
- package/esm2015/lib/shared/components/skill-allocation/skill-allocation.component.js +5 -2
- package/esm2015/lib/shared/controllers.js +18 -4
- package/esm2015/lib/shared/interfaces/assessment.interface.js +1 -1
- package/esm2015/lib/shared/interfaces/proctoring.interface.js +2 -0
- package/esm2015/lib/shared/material-modules.js +1 -16
- package/esm2015/lib/shared/shared.module.js +8 -3
- package/esm2015/lib/shared/utils.js +19 -1
- package/esm2015/public-api.js +4 -1
- package/fesm2015/commons-assessment.js +2071 -152
- package/fesm2015/commons-assessment.js.map +1 -1
- package/lib/modules/assessment-maker/assessment-maker.component.d.ts +40 -2
- package/lib/modules/assessment-maker/assessment-maker.module.d.ts +6 -5
- package/lib/modules/assessment-maker/components/assessment-builder/assessment-builder.component.d.ts +7 -0
- package/lib/modules/assessment-maker/components/question-bank-picker/question-bank-picker.component.d.ts +81 -0
- package/lib/modules/assessment-maker/components/question-details/question-details.component.d.ts +6 -1
- package/lib/modules/assessment-maker/services/assessment-builder.service.d.ts +10 -3
- package/lib/modules/assessment-maker/services/assessment-maker.service.d.ts +15 -11
- package/lib/modules/assessment-taker/assessment-taker.component.d.ts +81 -2
- package/lib/modules/assessment-taker/assessment-taker.module.d.ts +7 -5
- package/lib/modules/assessment-taker/components/proctoring-consent/proctoring-consent.component.d.ts +39 -0
- package/lib/modules/assessment-taker/components/proctoring-result/proctoring-result.component.d.ts +82 -0
- package/lib/modules/assessment-taker/components/question-type-file-upload/question-type-file-upload.component.d.ts +1 -0
- package/lib/modules/assessment-taker/components/question-type-multiselect/question-type-multiselect.component.d.ts +1 -0
- package/lib/modules/assessment-taker/components/question-type-objective/question-type-objective.component.d.ts +1 -0
- package/lib/modules/assessment-taker/components/question-type-preference/question-type-preference.component.d.ts +1 -0
- package/lib/modules/assessment-taker/components/question-type-short/question-type-short.component.d.ts +14 -2
- package/lib/modules/assessment-taker/services/assessment-taker.service.d.ts +5 -0
- package/lib/modules/assessment-taker/services/proctoring.service.d.ts +40 -0
- package/lib/modules/assessment-taker/services/response-builder.service.d.ts +9 -0
- package/lib/modules/question-bank/question-bank.component.d.ts +65 -0
- package/lib/modules/question-bank/question-bank.module.d.ts +12 -0
- package/lib/shared/components/confirmation-dialog/confirmation-dialog.component.d.ts +36 -0
- package/lib/shared/components/skill-allocation/skill-allocation.component.d.ts +1 -0
- package/lib/shared/controllers.d.ts +14 -1
- package/lib/shared/interfaces/assessment.interface.d.ts +8 -0
- package/lib/shared/interfaces/proctoring.interface.d.ts +101 -0
- package/lib/shared/material-modules.d.ts +5 -8
- package/lib/shared/shared.module.d.ts +5 -4
- package/lib/shared/utils.d.ts +4 -0
- package/package.json +1 -1
- package/public-api.d.ts +3 -0
- package/src/lib/assets/images/arrow-down-blue.svg +3 -0
- package/src/lib/assets/images/arrow-up-blue.svg +3 -0
- package/src/lib/assets/images/file-import.svg +11 -0
- package/src/lib/assets/images/plus-white.svg +1 -0
- package/src/lib/assets/images/proctoring.svg +3 -0
- package/src/lib/assets/images/user.svg +3 -0
- package/src/lib/assets/json/imageConfig.json +7 -1
- package/src/lib/assets/json/labelConfig.json +107 -2
- package/src/lib/assets/theme/_theme.global.scss +6 -0
- package/src/lib/assets/theme/_theme.scss +17 -346
- package/src/lib/assets/theme/styles.scss +13 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EventEmitter, OnInit } from '@angular/core';
|
|
2
2
|
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
|
3
3
|
import { MatDialog } from '@angular/material/dialog';
|
|
4
|
-
import { QuestionType, Assessment, RefData, AssessmentContextDTO, AssessmentInstance } from '../../shared/interfaces/assessment.interface';
|
|
4
|
+
import { QuestionType, Assessment, RefData, AssessmentContextDTO, AssessmentInstance, QuestionBankConfig } from '../../shared/interfaces/assessment.interface';
|
|
5
5
|
import { AssessmentQuestionPaper, SectionQuestion, QuestionPaperSection } from '../../shared/interfaces/question-paper.interface';
|
|
6
6
|
import { AssessmentQuestion } from '../../shared/interfaces/question.interface';
|
|
7
7
|
import { AssessmentBuilderService } from './services/assessment-builder.service';
|
|
@@ -27,6 +27,11 @@ export declare class AssessmentMakerComponent implements OnInit {
|
|
|
27
27
|
enableSkillsToQuestionMapping: boolean;
|
|
28
28
|
assessmentContext: AssessmentContextDTO;
|
|
29
29
|
minimumRequiredSections: number;
|
|
30
|
+
checkForResponses: boolean;
|
|
31
|
+
showProctoringToggle: boolean;
|
|
32
|
+
showTimeInput: boolean;
|
|
33
|
+
enableImportFromQuestionBank: boolean;
|
|
34
|
+
questionBankConfig?: QuestionBankConfig;
|
|
30
35
|
assessmentIdChange: EventEmitter<number>;
|
|
31
36
|
assessmentInstanceIdChange: EventEmitter<number>;
|
|
32
37
|
snackbarMessage: EventEmitter<{
|
|
@@ -35,15 +40,28 @@ export declare class AssessmentMakerComponent implements OnInit {
|
|
|
35
40
|
}>;
|
|
36
41
|
showLoader: boolean;
|
|
37
42
|
questionBank: Record<number, AssessmentQuestion>;
|
|
43
|
+
lockedQuestionsMap: Record<number, boolean>;
|
|
38
44
|
assessmentQuestionPaperData: AssessmentQuestionPaper;
|
|
39
45
|
configsLoaded: boolean;
|
|
40
46
|
rules: any;
|
|
41
47
|
isSubmitting: boolean;
|
|
42
48
|
skillsList: RefData[];
|
|
49
|
+
responseCount: number;
|
|
50
|
+
proctoringEnabled: boolean;
|
|
51
|
+
durationMinutes: number | null;
|
|
52
|
+
private readonly PROCTORING_CONFIG_KEY;
|
|
43
53
|
constructor(assessmentMakerService: AssessmentMakerService, assessmentBuilderService: AssessmentBuilderService, dialog: MatDialog);
|
|
44
54
|
ngOnInit(): void;
|
|
55
|
+
private loadResponseCount;
|
|
56
|
+
/**
|
|
57
|
+
* Runs `action`, but first warns the user if the assessment already has responses
|
|
58
|
+
* (only when `checkForResponses` is enabled and the count is greater than 0).
|
|
59
|
+
*/
|
|
60
|
+
private confirmResponsesWarning;
|
|
45
61
|
getConfigsFromJSON(): void;
|
|
46
62
|
loadAssessmentData(): void;
|
|
63
|
+
checkAssessmentQuestionsLocked(): void;
|
|
64
|
+
isQuestionLocked(questionId?: number): boolean;
|
|
47
65
|
generateQuestionBank(): void;
|
|
48
66
|
imageErrorHandler(event: any, filePath: string): void;
|
|
49
67
|
focusSectionInput(sectionIndex: number, event: Event): void;
|
|
@@ -54,8 +72,22 @@ export declare class AssessmentMakerComponent implements OnInit {
|
|
|
54
72
|
deleteParentQuestion(sectionQuestion: SectionQuestion): void;
|
|
55
73
|
deleteSection(section: QuestionPaperSection): void;
|
|
56
74
|
createEditQuestion(sectionDetails?: any, sectionQuestionId?: number, isChild?: boolean): void;
|
|
75
|
+
private openQuestionBuilder;
|
|
57
76
|
duplicateSection(sectionId: number): void;
|
|
58
77
|
duplicateQuestion(section: QuestionPaperSection, sectionQuestion: SectionQuestion): void;
|
|
78
|
+
private readProctoringConfig;
|
|
79
|
+
/** Initializes the minutes input from an existing instance's duration (seconds). */
|
|
80
|
+
private readDuration;
|
|
81
|
+
/** Blocks characters that would enter a negative/exponent value in the duration input. */
|
|
82
|
+
blockNegativeKeys(event: KeyboardEvent): void;
|
|
83
|
+
/** Duration to persist, in SECONDS (the unit the taker's timer uses). 0 means untimed. */
|
|
84
|
+
private get durationSeconds();
|
|
85
|
+
/**
|
|
86
|
+
* Returns the assessment configs with the proctoring flag ('1'/'0') upserted, preserving
|
|
87
|
+
* any other existing configs. Returns undefined when the proctoring toggle is not enabled
|
|
88
|
+
* so the saved payload is unchanged for consumers not using proctoring.
|
|
89
|
+
*/
|
|
90
|
+
private buildProctoringConfigs;
|
|
59
91
|
patchAssessmentAndQuestionPaper(successMessage?: string): void;
|
|
60
92
|
finalSubmit(): void;
|
|
61
93
|
createAssessmentInstance(): void;
|
|
@@ -65,6 +97,12 @@ export declare class AssessmentMakerComponent implements OnInit {
|
|
|
65
97
|
filterInactiveSectionsAndQuestions(): void;
|
|
66
98
|
capitalizeFirst(text: string | undefined): string;
|
|
67
99
|
getSkillsList(): void;
|
|
100
|
+
trackBySectionId(index: number, section: any): string;
|
|
101
|
+
trackBySectionQuestion(index: number, sq: any): string;
|
|
102
|
+
private collectExistingQuestionIds;
|
|
103
|
+
openQuestionBankPicker(section?: QuestionPaperSection): void;
|
|
104
|
+
private importQuestionsToSection;
|
|
105
|
+
private createAssessmentAndQuestionPaperOnImport;
|
|
68
106
|
static ɵfac: i0.ɵɵFactoryDeclaration<AssessmentMakerComponent, never>;
|
|
69
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<AssessmentMakerComponent, "lib-assessment-maker", never, { "labelConfig": "labelConfig"; "imageConfig": "imageConfig"; "questionTypes": "questionTypes"; "showFooter": "showFooter"; "customRules": "customRules"; "assessmentId": "assessmentId"; "assessmentInstanceId": "assessmentInstanceId"; "defaultAssessmentDTO": "defaultAssessmentDTO"; "predefinedAssessmentInstance": "predefinedAssessmentInstance"; "enableSkillsToQuestionMapping": "enableSkillsToQuestionMapping"; "assessmentContext": "assessmentContext"; "minimumRequiredSections": "minimumRequiredSections"; }, { "assessmentIdChange": "assessmentIdChange"; "assessmentInstanceIdChange": "assessmentInstanceIdChange"; "snackbarMessage": "snackbarMessage"; }, never, never>;
|
|
107
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AssessmentMakerComponent, "lib-assessment-maker", never, { "labelConfig": "labelConfig"; "imageConfig": "imageConfig"; "questionTypes": "questionTypes"; "showFooter": "showFooter"; "customRules": "customRules"; "assessmentId": "assessmentId"; "assessmentInstanceId": "assessmentInstanceId"; "defaultAssessmentDTO": "defaultAssessmentDTO"; "predefinedAssessmentInstance": "predefinedAssessmentInstance"; "enableSkillsToQuestionMapping": "enableSkillsToQuestionMapping"; "assessmentContext": "assessmentContext"; "minimumRequiredSections": "minimumRequiredSections"; "checkForResponses": "checkForResponses"; "showProctoringToggle": "showProctoringToggle"; "showTimeInput": "showTimeInput"; "enableImportFromQuestionBank": "enableImportFromQuestionBank"; "questionBankConfig": "questionBankConfig"; }, { "assessmentIdChange": "assessmentIdChange"; "assessmentInstanceIdChange": "assessmentInstanceIdChange"; "snackbarMessage": "snackbarMessage"; }, never, never>;
|
|
70
108
|
}
|
|
@@ -3,12 +3,13 @@ import * as i1 from "./assessment-maker.component";
|
|
|
3
3
|
import * as i2 from "./components/add-edit-section-introduction/add-edit-section-introduction.component";
|
|
4
4
|
import * as i3 from "./components/assessment-builder/assessment-builder.component";
|
|
5
5
|
import * as i4 from "./components/question-details/question-details.component";
|
|
6
|
-
import * as i5 from "
|
|
7
|
-
import * as i6 from "
|
|
8
|
-
import * as i7 from "../../shared/
|
|
9
|
-
import * as i8 from "
|
|
6
|
+
import * as i5 from "./components/question-bank-picker/question-bank-picker.component";
|
|
7
|
+
import * as i6 from "@angular/common";
|
|
8
|
+
import * as i7 from "../../shared/shared.module";
|
|
9
|
+
import * as i8 from "../../shared/material-modules";
|
|
10
|
+
import * as i9 from "@angular/forms";
|
|
10
11
|
export declare class AssessmentMakerModule {
|
|
11
12
|
static ɵfac: i0.ɵɵFactoryDeclaration<AssessmentMakerModule, never>;
|
|
12
|
-
static ɵmod: i0.ɵɵNgModuleDeclaration<AssessmentMakerModule, [typeof i1.AssessmentMakerComponent, typeof i2.AddEditSectionIntroductionComponent, typeof i3.AssessmentBuilderComponent, typeof i4.QuestionDetailsComponent], [typeof
|
|
13
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<AssessmentMakerModule, [typeof i1.AssessmentMakerComponent, typeof i2.AddEditSectionIntroductionComponent, typeof i3.AssessmentBuilderComponent, typeof i4.QuestionDetailsComponent, typeof i5.QuestionBankPickerComponent], [typeof i6.CommonModule, typeof i7.SharedModule, typeof i8.MaterialModules, typeof i9.FormsModule, typeof i9.ReactiveFormsModule], [typeof i1.AssessmentMakerComponent, typeof i3.AssessmentBuilderComponent]>;
|
|
13
14
|
static ɵinj: i0.ɵɵInjectorDeclaration<AssessmentMakerModule>;
|
|
14
15
|
}
|
package/lib/modules/assessment-maker/components/assessment-builder/assessment-builder.component.d.ts
CHANGED
|
@@ -36,6 +36,8 @@ export declare class AssessmentBuilderComponent implements OnInit {
|
|
|
36
36
|
questionBank: Record<number, AssessmentQuestion>;
|
|
37
37
|
isChild: boolean;
|
|
38
38
|
assessmentId: number;
|
|
39
|
+
standaloneMode: boolean;
|
|
40
|
+
isLocked: boolean;
|
|
39
41
|
isSubmitting: boolean;
|
|
40
42
|
skillsList: RefData[];
|
|
41
43
|
constructor(formBuilder: FormBuilder, assessmentBuilderService: AssessmentBuilderService, assessmentMakerService: AssessmentMakerService, dialogRef: MatDialogRef<AssessmentBuilderComponent>, dialogData: any);
|
|
@@ -44,6 +46,7 @@ export declare class AssessmentBuilderComponent implements OnInit {
|
|
|
44
46
|
setupFormGroup(): void;
|
|
45
47
|
populateForm(questionDetails: AssessmentQuestion, buildChildGroups?: boolean): void;
|
|
46
48
|
onSubmit(): Promise<void>;
|
|
49
|
+
private createStandaloneQuestion;
|
|
47
50
|
createQuestion(payload: any): Promise<AssessmentQuestion>;
|
|
48
51
|
updateQuestion(payload: any): Promise<AssessmentQuestion>;
|
|
49
52
|
createOrEditAssessmentAndQuestionPaper(question: AssessmentQuestion): void;
|
|
@@ -68,6 +71,10 @@ export declare class AssessmentBuilderComponent implements OnInit {
|
|
|
68
71
|
goBack(): void;
|
|
69
72
|
private resetAndPopulate;
|
|
70
73
|
private scrollToTop;
|
|
74
|
+
trackByCode(index: number, item: any): string;
|
|
75
|
+
trackByControl(index: number, control: any): any;
|
|
76
|
+
trackByGroupId(index: number, group: any): string;
|
|
77
|
+
trackByQuestionId(index: number, id: any): string;
|
|
71
78
|
static ɵfac: i0.ɵɵFactoryDeclaration<AssessmentBuilderComponent, never>;
|
|
72
79
|
static ɵcmp: i0.ɵɵComponentDeclaration<AssessmentBuilderComponent, "lib-app-assessment-builder", never, {}, {}, never, never>;
|
|
73
80
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { OnDestroy, OnInit } from '@angular/core';
|
|
2
|
+
import { MatDialogRef } from '@angular/material/dialog';
|
|
3
|
+
import { QuestionBankConfig, QuestionType } from '../../../../shared/interfaces/assessment.interface';
|
|
4
|
+
import { AssessmentQuestion } from '../../../../shared/interfaces/question.interface';
|
|
5
|
+
import { AssessmentMakerService } from '../../services/assessment-maker.service';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
export interface QuestionBankPickerDialogData {
|
|
8
|
+
questionBankConfig: QuestionBankConfig;
|
|
9
|
+
existingQuestionIds: Set<number>;
|
|
10
|
+
labelConfig: {
|
|
11
|
+
[key: string]: string;
|
|
12
|
+
};
|
|
13
|
+
imageConfig: {
|
|
14
|
+
[key: string]: string;
|
|
15
|
+
};
|
|
16
|
+
questionTypes: QuestionType[];
|
|
17
|
+
targetSectionName?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare class QuestionBankPickerComponent implements OnInit, OnDestroy {
|
|
20
|
+
private assessmentMakerService;
|
|
21
|
+
dialogRef: MatDialogRef<QuestionBankPickerComponent>;
|
|
22
|
+
dialogData: QuestionBankPickerDialogData;
|
|
23
|
+
labelConfig: {
|
|
24
|
+
[key: string]: string;
|
|
25
|
+
};
|
|
26
|
+
imageConfig: {
|
|
27
|
+
[key: string]: string;
|
|
28
|
+
};
|
|
29
|
+
questionTypes: QuestionType[];
|
|
30
|
+
existingQuestionIds: Set<number>;
|
|
31
|
+
targetSectionName: string;
|
|
32
|
+
allQuestions: AssessmentQuestion[];
|
|
33
|
+
filteredQuestions: AssessmentQuestion[];
|
|
34
|
+
currentPage: number;
|
|
35
|
+
pageSize: number;
|
|
36
|
+
totalElements: number;
|
|
37
|
+
hasNext: boolean;
|
|
38
|
+
isLoading: boolean;
|
|
39
|
+
isInitialLoading: boolean;
|
|
40
|
+
searchTerm: string;
|
|
41
|
+
selectedTypeCode: string;
|
|
42
|
+
selectedQuestions: Map<number, AssessmentQuestion>;
|
|
43
|
+
expandedQuestionIds: Set<number>;
|
|
44
|
+
private questionBankConfig;
|
|
45
|
+
private searchSubject$;
|
|
46
|
+
private destroy$;
|
|
47
|
+
constructor(assessmentMakerService: AssessmentMakerService, dialogRef: MatDialogRef<QuestionBankPickerComponent>, dialogData: QuestionBankPickerDialogData);
|
|
48
|
+
ngOnInit(): void;
|
|
49
|
+
ngOnDestroy(): void;
|
|
50
|
+
loadPage(page: number, append?: boolean): void;
|
|
51
|
+
loadMore(): void;
|
|
52
|
+
onScroll(event: Event): void;
|
|
53
|
+
applyFilters(): void;
|
|
54
|
+
onSearchChange(term: string): void;
|
|
55
|
+
clearSearch(): void;
|
|
56
|
+
onTypeFilterChange(typeCode: string | undefined): void;
|
|
57
|
+
selectQuickTypeFilter(typeCode: string | undefined): void;
|
|
58
|
+
toggleSelection(question: AssessmentQuestion): void;
|
|
59
|
+
isSelected(question: AssessmentQuestion): boolean;
|
|
60
|
+
isAlreadyInAssessment(questionId: number | undefined): boolean;
|
|
61
|
+
get eligibleVisibleQuestions(): AssessmentQuestion[];
|
|
62
|
+
get isAllVisibleSelected(): boolean;
|
|
63
|
+
get isSomeVisibleSelected(): boolean;
|
|
64
|
+
toggleSelectAllVisible(): void;
|
|
65
|
+
clearAllSelection(): void;
|
|
66
|
+
hasOptions(question: AssessmentQuestion): boolean;
|
|
67
|
+
toggleExpandOptions(questionId: number | undefined, event: Event): void;
|
|
68
|
+
isOptionsExpanded(questionId: number | undefined): boolean;
|
|
69
|
+
get selectedCount(): number;
|
|
70
|
+
get totalSelectedMarks(): number;
|
|
71
|
+
getTypeCount(typeCode: string | undefined): number;
|
|
72
|
+
getCategoryClass(question: AssessmentQuestion): string;
|
|
73
|
+
importSelected(): void;
|
|
74
|
+
close(): void;
|
|
75
|
+
capitalizeFirst(text: string | undefined): string;
|
|
76
|
+
getQuestionTypeLabel(question: AssessmentQuestion): string;
|
|
77
|
+
imageErrorHandler(event: any, filePath: string): void;
|
|
78
|
+
trackByQuestionId(index: number, question: AssessmentQuestion): string;
|
|
79
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<QuestionBankPickerComponent, never>;
|
|
80
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<QuestionBankPickerComponent, "lib-question-bank-picker", never, {}, {}, never, never>;
|
|
81
|
+
}
|
package/lib/modules/assessment-maker/components/question-details/question-details.component.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export declare class QuestionDetailsComponent implements AfterViewInit {
|
|
|
13
13
|
[key: string]: string;
|
|
14
14
|
};
|
|
15
15
|
allowDelete: boolean;
|
|
16
|
+
isLocked: boolean;
|
|
16
17
|
editQuestion: EventEmitter<{
|
|
17
18
|
questionId: any;
|
|
18
19
|
isChildQuestion: boolean;
|
|
@@ -29,9 +30,13 @@ export declare class QuestionDetailsComponent implements AfterViewInit {
|
|
|
29
30
|
ngAfterViewInit(): void;
|
|
30
31
|
toggleText(): void;
|
|
31
32
|
checkOverflow(): void;
|
|
33
|
+
onQuestionClick(event: Event, questionId: any, isChild?: boolean): void;
|
|
32
34
|
capitalizeFirst(text: string | undefined): string;
|
|
33
35
|
imageErrorHandler(event: any, filePath: string): void;
|
|
34
36
|
childQuestionPresent(question: AssessmentQuestion): boolean | undefined;
|
|
37
|
+
trackByOptionId(index: number, option: any): string;
|
|
38
|
+
trackByChildId(index: number, id: any): string;
|
|
39
|
+
trackBySkillCode(index: number, skill: any): string;
|
|
35
40
|
static ɵfac: i0.ɵɵFactoryDeclaration<QuestionDetailsComponent, never>;
|
|
36
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<QuestionDetailsComponent, "lib-question-details", never, { "sectionQuestion": "sectionQuestion"; "question": "question"; "questionBank": "questionBank"; "labelConfig": "labelConfig"; "imageConfig": "imageConfig"; "allowDelete": "allowDelete"; }, { "editQuestion": "editQuestion"; "duplicateQuestion": "duplicateQuestion"; "deleteParentQuestion": "deleteParentQuestion"; "deleteChildQuestion": "deleteChildQuestion"; }, never, never>;
|
|
41
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<QuestionDetailsComponent, "lib-question-details", never, { "sectionQuestion": "sectionQuestion"; "question": "question"; "questionBank": "questionBank"; "labelConfig": "labelConfig"; "imageConfig": "imageConfig"; "allowDelete": "allowDelete"; "isLocked": "isLocked"; }, { "editQuestion": "editQuestion"; "duplicateQuestion": "duplicateQuestion"; "deleteParentQuestion": "deleteParentQuestion"; "deleteChildQuestion": "deleteChildQuestion"; }, never, never>;
|
|
37
42
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Assessment, AssessmentInstance } from '../../../shared/interfaces/assessment.interface';
|
|
1
|
+
import { Assessment, AssessmentInstance, Config } from '../../../shared/interfaces/assessment.interface';
|
|
2
2
|
import { QuestionPaperSection, SectionQuestion, AssessmentQuestionPaper } from '../../../shared/interfaces/question-paper.interface';
|
|
3
3
|
import { AssessmentQuestion } from '../../../shared/interfaces/question.interface';
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
@@ -39,8 +39,15 @@ export declare class AssessmentBuilderService {
|
|
|
39
39
|
createNewSection(sequence: number): QuestionPaperSection;
|
|
40
40
|
generateSectionQuestion(question: AssessmentQuestion, sectionQuestion?: SectionQuestion): SectionQuestion;
|
|
41
41
|
generateQuestionPaperDTO(questionPaper: AssessmentQuestionPaper, questionBank: Record<number, AssessmentQuestion>): AssessmentQuestionPaper;
|
|
42
|
-
generateAssessmentDTO(assessmentId: number, questionPaper: AssessmentQuestionPaper): Assessment;
|
|
43
|
-
generateAssessmentInstanceDTO(assessmentId: number, predefinedAssessmentInstance: AssessmentInstance): AssessmentInstance;
|
|
42
|
+
generateAssessmentDTO(assessmentId: number, questionPaper: AssessmentQuestionPaper, assessmentConfigs?: Config[]): Assessment;
|
|
43
|
+
generateAssessmentInstanceDTO(assessmentId: number, predefinedAssessmentInstance: AssessmentInstance, duration?: number): AssessmentInstance;
|
|
44
|
+
/**
|
|
45
|
+
* Patch fragment carrying the duration onto an already-created instance (by id), to bundle into
|
|
46
|
+
* the assessment/question-paper patch. Empty unless the time input is enabled and an instance exists.
|
|
47
|
+
*/
|
|
48
|
+
buildInstancePatch(showTimeInput: boolean, assessmentInstanceId: number, durationSeconds: number): {
|
|
49
|
+
assessmentInstance?: AssessmentInstance;
|
|
50
|
+
};
|
|
44
51
|
static ɵfac: i0.ɵɵFactoryDeclaration<AssessmentBuilderService, never>;
|
|
45
52
|
static ɵprov: i0.ɵɵInjectableDeclaration<AssessmentBuilderService>;
|
|
46
53
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { HttpClient, HttpParams } from '@angular/common/http';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
2
3
|
import * as i0 from "@angular/core";
|
|
3
4
|
export declare class AssessmentMakerService {
|
|
4
5
|
private http;
|
|
@@ -6,19 +7,22 @@ export declare class AssessmentMakerService {
|
|
|
6
7
|
constructor(http: HttpClient);
|
|
7
8
|
private getHeaders;
|
|
8
9
|
createParams(params: any): HttpParams;
|
|
9
|
-
getConfigJSON(fileName: string):
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
getConfigJSON(fileName: string): Observable<Object>;
|
|
11
|
+
getResponseCount(assessmentInstanceId: number): Observable<Object>;
|
|
12
|
+
createAssessmentAndQuestionPaper(payload: any): Observable<Object>;
|
|
13
|
+
patchAssessmentAndQuestionPaper(payload: any): Observable<Object>;
|
|
14
|
+
createQuestion(payload: any): Observable<Object>;
|
|
15
|
+
patchQuestion(payload: any): Observable<Object>;
|
|
14
16
|
getQuestionsByIds(params: {
|
|
15
17
|
questionIds: number[];
|
|
16
|
-
}):
|
|
17
|
-
getAssessmentContext(params: any):
|
|
18
|
-
duplicateSection(questionPaperId: number, sectionId: number):
|
|
19
|
-
duplicateQuestion(sectionId: number, sectionQuestionId: number):
|
|
20
|
-
createAssessmentInstance(payload: any):
|
|
21
|
-
getRefDataByCode(code: string, params: any):
|
|
18
|
+
}): Observable<Object>;
|
|
19
|
+
getAssessmentContext(params: any): Observable<Object>;
|
|
20
|
+
duplicateSection(questionPaperId: number, sectionId: number): Observable<Object>;
|
|
21
|
+
duplicateQuestion(sectionId: number, sectionQuestionId: number): Observable<Object>;
|
|
22
|
+
createAssessmentInstance(payload: any): Observable<Object>;
|
|
23
|
+
getRefDataByCode(code: string, params: any): Observable<Object>;
|
|
24
|
+
getQuestionBankQuestions(params: any): Observable<Object>;
|
|
25
|
+
checkQuestionsLocked(questionIds: (number | string)[], scope?: string): Observable<Record<string, boolean>>;
|
|
22
26
|
static ɵfac: i0.ɵɵFactoryDeclaration<AssessmentMakerService, never>;
|
|
23
27
|
static ɵprov: i0.ɵɵInjectableDeclaration<AssessmentMakerService>;
|
|
24
28
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { EventEmitter, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
2
3
|
import { MatDialog } from '@angular/material/dialog';
|
|
3
4
|
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
|
4
5
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
@@ -7,6 +8,7 @@ import { ResponseBuilderService } from './services/response-builder.service';
|
|
|
7
8
|
import { AssesseeDTO, AssessorDTO, Assessment, AssessmentInstanceAssesseDTO, AssessmentStep, AssessmentContextDTO, SectionScore, SkillScore } from '../../shared/interfaces/assessment.interface';
|
|
8
9
|
import { AssessmentQuestion } from '../../shared/interfaces/question.interface';
|
|
9
10
|
import { AssessmentQuestionPaper, QuestionPaperSection } from '../../shared/interfaces/question-paper.interface';
|
|
11
|
+
import { ProctoringService } from './services/proctoring.service';
|
|
10
12
|
import * as i0 from "@angular/core";
|
|
11
13
|
export declare class AssessmentTakerComponent implements OnInit, OnDestroy {
|
|
12
14
|
private assessmentTakerService;
|
|
@@ -15,6 +17,7 @@ export declare class AssessmentTakerComponent implements OnInit, OnDestroy {
|
|
|
15
17
|
private sanitizer;
|
|
16
18
|
private dialog;
|
|
17
19
|
private cdr;
|
|
20
|
+
private proctoringService;
|
|
18
21
|
labelConfig: {
|
|
19
22
|
[key: string]: string;
|
|
20
23
|
};
|
|
@@ -39,13 +42,20 @@ export declare class AssessmentTakerComponent implements OnInit, OnDestroy {
|
|
|
39
42
|
};
|
|
40
43
|
showOverallRemarks: boolean;
|
|
41
44
|
showCorrectAnswers: boolean;
|
|
45
|
+
resumeTimerAcrossVisits: boolean;
|
|
46
|
+
warnOnLeaveDuringProctoring: boolean;
|
|
47
|
+
proctorLinkLoader?: () => Promise<any>;
|
|
42
48
|
snackbarMessage: EventEmitter<{
|
|
43
49
|
message: string;
|
|
44
50
|
type: 'success' | 'error' | 'info';
|
|
45
51
|
}>;
|
|
46
52
|
submitAssessment: EventEmitter<any>;
|
|
47
53
|
stepChanged: EventEmitter<AssessmentStep>;
|
|
54
|
+
consentToProceed: EventEmitter<boolean>;
|
|
48
55
|
showLoader: boolean;
|
|
56
|
+
introActive: boolean;
|
|
57
|
+
private proctoringSessionStarted;
|
|
58
|
+
private proctoringSessionEnded;
|
|
49
59
|
questionBank: Record<number, AssessmentQuestion>;
|
|
50
60
|
assessmentQuestionPaperData: AssessmentQuestionPaper;
|
|
51
61
|
assessmentData: Assessment;
|
|
@@ -53,6 +63,7 @@ export declare class AssessmentTakerComponent implements OnInit, OnDestroy {
|
|
|
53
63
|
timerInterval: any;
|
|
54
64
|
remainingTime: number;
|
|
55
65
|
displayTime: string;
|
|
66
|
+
timeExpired: boolean;
|
|
56
67
|
isAutoSubmitting: boolean;
|
|
57
68
|
isSubmitting: boolean;
|
|
58
69
|
sectionFormGroups: {
|
|
@@ -62,6 +73,9 @@ export declare class AssessmentTakerComponent implements OnInit, OnDestroy {
|
|
|
62
73
|
overallNotesCtrl: FormControl;
|
|
63
74
|
expandedState: boolean[];
|
|
64
75
|
private youtubeUrlCache;
|
|
76
|
+
private newAssesseeSession;
|
|
77
|
+
private backGuardArmed;
|
|
78
|
+
private allowBackNavigation;
|
|
65
79
|
private _selectedTabIndex;
|
|
66
80
|
get selectedTabIndex(): number;
|
|
67
81
|
set selectedTabIndex(value: number);
|
|
@@ -70,13 +84,72 @@ export declare class AssessmentTakerComponent implements OnInit, OnDestroy {
|
|
|
70
84
|
tooltipState: Record<number, boolean>;
|
|
71
85
|
isMobile: boolean;
|
|
72
86
|
onResize(): void;
|
|
73
|
-
|
|
87
|
+
/**
|
|
88
|
+
* While a proctoring session is running, warn the candidate before they refresh, close the tab, or
|
|
89
|
+
* navigate away. Browsers show their own generic "Leave site?" confirmation here — the message text
|
|
90
|
+
* cannot be customized for security reasons — so this only guarantees a prompt, not our wording.
|
|
91
|
+
*/
|
|
92
|
+
onBeforeUnload(event: BeforeUnloadEvent): void;
|
|
93
|
+
/**
|
|
94
|
+
* In-app Back button (SPA popstate — not caught by beforeunload). While proctoring runs we keep a
|
|
95
|
+
* sentinel history entry; when Back pops it we show a custom warning and either re-arm (stay) or
|
|
96
|
+
* proceed with the navigation (leave).
|
|
97
|
+
*/
|
|
98
|
+
onPopState(): void;
|
|
99
|
+
private isProctoringRunning;
|
|
100
|
+
/** Pushes a sentinel history entry so the next in-app Back press triggers our guard. */
|
|
101
|
+
private armBackGuard;
|
|
102
|
+
private confirmLeaveAssessment;
|
|
103
|
+
constructor(assessmentTakerService: AssessmentTakerService, fb: FormBuilder, responseBuilderService: ResponseBuilderService, sanitizer: DomSanitizer, dialog: MatDialog, cdr: ChangeDetectorRef, proctoringService: ProctoringService);
|
|
74
104
|
ngOnInit(): void;
|
|
75
105
|
ngOnDestroy(): void;
|
|
106
|
+
/**
|
|
107
|
+
* Ends the proctoring session after the assessment is submitted: stops + destroys the ProctorLink
|
|
108
|
+
* SDK and notifies the backend to end the session. Only ends a session that actually started, and
|
|
109
|
+
* is guarded so the backend is called at most once.
|
|
110
|
+
*/
|
|
111
|
+
private endProctoringSession;
|
|
76
112
|
getConfigsFromJSON(): void;
|
|
77
113
|
loadAssessmentData(): void;
|
|
78
114
|
handleResponse(): void;
|
|
79
115
|
formSetup(): void;
|
|
116
|
+
private startAssessment;
|
|
117
|
+
get isProctoringEnabled(): boolean;
|
|
118
|
+
/**
|
|
119
|
+
* The full-screen intro gate is shown when proctoring is enabled, or when a timed assessment tracks
|
|
120
|
+
* elapsed time across visits (so the assessee is created up front to anchor the timer).
|
|
121
|
+
*/
|
|
122
|
+
private requiresStartGate;
|
|
123
|
+
/** A reference image is captured only for proctoring, and only on the first attempt (no assessee id yet). */
|
|
124
|
+
get requireReferenceCapture(): boolean;
|
|
125
|
+
get totalSectionCount(): number;
|
|
126
|
+
get totalQuestionCount(): number;
|
|
127
|
+
get assessmentDurationSeconds(): number;
|
|
128
|
+
startSessionAction: (referenceImageBase64: string) => Observable<any>;
|
|
129
|
+
onIntroProceeded(): void;
|
|
130
|
+
/**
|
|
131
|
+
* Creates the assessee up front when the candidate proceeds from the intro gate.
|
|
132
|
+
* - First attempt (no assessee id): POST creates the assessee — for proctoring the response carries
|
|
133
|
+
* a nested `proctoring` session; otherwise it's a plain assessee DTO (with `createdAt`).
|
|
134
|
+
* - Existing attempt: proctoring refreshes the token (flat ProctoringSession); non-proctoring is a no-op
|
|
135
|
+
* (the assessee was already loaded, so `createdAt` is known).
|
|
136
|
+
* When proctoring is enabled it then starts the ProctorLink SDK and waits for camera permission.
|
|
137
|
+
*/
|
|
138
|
+
private startAssessmentSession;
|
|
139
|
+
/**
|
|
140
|
+
* Re-mints the proctoring token via the refresh API and returns ONLY the new provider JWT
|
|
141
|
+
* (used by the SDK's token-expired flow). The rest of the refresh response is intentionally
|
|
142
|
+
* ignored — the live session must not be re-seeded from it mid-attempt.
|
|
143
|
+
*/
|
|
144
|
+
private refreshProctoringJwt;
|
|
145
|
+
private buildInitAssesseePayload;
|
|
146
|
+
private beginAssessment;
|
|
147
|
+
/**
|
|
148
|
+
* Starts a timer anchored to the assessee's first-visit time. The assessee is already created by the
|
|
149
|
+
* intro gate (so `createdAt` is known); remaining time is `duration - elapsedSinceCreatedAt`.
|
|
150
|
+
* If the time has already run out (candidate left and returned late), shows 00:00 and auto-submits.
|
|
151
|
+
*/
|
|
152
|
+
private beginTrackedTimer;
|
|
80
153
|
updateQuestionConditionalControls(fg: FormGroup, question: AssessmentQuestion): void;
|
|
81
154
|
emitStepDetails(): void;
|
|
82
155
|
addControlForQuestion(group: any, question: AssessmentQuestion, isMandatory?: boolean, isChild?: boolean, parentId?: number, parentOptionId?: number): void;
|
|
@@ -91,6 +164,7 @@ export declare class AssessmentTakerComponent implements OnInit, OnDestroy {
|
|
|
91
164
|
getMaxCharCount(question: AssessmentQuestion): number;
|
|
92
165
|
getRemainingChars(question: AssessmentQuestion, control: any): number;
|
|
93
166
|
goBack(): void;
|
|
167
|
+
get isCheckingLink(): boolean;
|
|
94
168
|
shouldDisableTab(index: number): boolean;
|
|
95
169
|
goNext(saveData?: boolean): void;
|
|
96
170
|
processSubmit(saveData?: boolean): void;
|
|
@@ -102,11 +176,16 @@ export declare class AssessmentTakerComponent implements OnInit, OnDestroy {
|
|
|
102
176
|
openInstructionsDialog(section: QuestionPaperSection): void;
|
|
103
177
|
checkMaxVal(event: any, control: any, maxVal: number | undefined): void;
|
|
104
178
|
preventNegativeInput(event: KeyboardEvent): void;
|
|
179
|
+
openProctoringResult(): void;
|
|
105
180
|
openSkillAllocationDialog(skillList?: SkillScore[]): void;
|
|
106
181
|
startTimer(durationInSeconds: number): void;
|
|
107
182
|
updateDisplayTime(): void;
|
|
108
183
|
autoSubmit(): void;
|
|
109
184
|
disableForm(): void;
|
|
185
|
+
trackBySectionId(index: number, section: any): string;
|
|
186
|
+
trackBySectionQuestion(index: number, sq: any): string;
|
|
187
|
+
trackByOptionId(index: number, option: any): string;
|
|
188
|
+
trackByChildId(index: number, id: any): string;
|
|
110
189
|
static ɵfac: i0.ɵɵFactoryDeclaration<AssessmentTakerComponent, never>;
|
|
111
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<AssessmentTakerComponent, "lib-assessment-taker", never, { "labelConfig": "labelConfig"; "imageConfig": "imageConfig"; "showFooter": "showFooter"; "assessmentId": "assessmentId"; "assessmentInstanceId": "assessmentInstanceId"; "assesseeData": "assesseeData"; "assessorData": "assessorData"; "disabled": "disabled"; "previewMode": "previewMode"; "verticalView": "verticalView"; "enableMarks": "enableMarks"; "hideSectionTabs": "hideSectionTabs"; "assessmentContext": "assessmentContext"; "assesseeResponse": "assesseeResponse"; "markAsCompleted": "markAsCompleted"; "sectionWiseScore": "sectionWiseScore"; "showOverallRemarks": "showOverallRemarks"; "showCorrectAnswers": "showCorrectAnswers"; }, { "snackbarMessage": "snackbarMessage"; "submitAssessment": "submitAssessment"; "stepChanged": "stepChanged"; }, never, never>;
|
|
190
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AssessmentTakerComponent, "lib-assessment-taker", never, { "labelConfig": "labelConfig"; "imageConfig": "imageConfig"; "showFooter": "showFooter"; "assessmentId": "assessmentId"; "assessmentInstanceId": "assessmentInstanceId"; "assesseeData": "assesseeData"; "assessorData": "assessorData"; "disabled": "disabled"; "previewMode": "previewMode"; "verticalView": "verticalView"; "enableMarks": "enableMarks"; "hideSectionTabs": "hideSectionTabs"; "assessmentContext": "assessmentContext"; "assesseeResponse": "assesseeResponse"; "markAsCompleted": "markAsCompleted"; "sectionWiseScore": "sectionWiseScore"; "showOverallRemarks": "showOverallRemarks"; "showCorrectAnswers": "showCorrectAnswers"; "resumeTimerAcrossVisits": "resumeTimerAcrossVisits"; "warnOnLeaveDuringProctoring": "warnOnLeaveDuringProctoring"; "proctorLinkLoader": "proctorLinkLoader"; }, { "snackbarMessage": "snackbarMessage"; "submitAssessment": "submitAssessment"; "stepChanged": "stepChanged"; "consentToProceed": "consentToProceed"; }, never, never>;
|
|
112
191
|
}
|
|
@@ -9,12 +9,14 @@ import * as i7 from "./components/question-type-preference/question-type-prefere
|
|
|
9
9
|
import * as i8 from "./components/question-type-short/question-type-short.component";
|
|
10
10
|
import * as i9 from "./components/section-instructions/section-instructions.component";
|
|
11
11
|
import * as i10 from "./components/question-type-date-picker/question-type-date-picker.component";
|
|
12
|
-
import * as i11 from "
|
|
13
|
-
import * as i12 from "
|
|
14
|
-
import * as i13 from "
|
|
15
|
-
import * as i14 from "
|
|
12
|
+
import * as i11 from "./components/proctoring-result/proctoring-result.component";
|
|
13
|
+
import * as i12 from "./components/proctoring-consent/proctoring-consent.component";
|
|
14
|
+
import * as i13 from "@angular/common";
|
|
15
|
+
import * as i14 from "../../shared/shared.module";
|
|
16
|
+
import * as i15 from "../../shared/material-modules";
|
|
17
|
+
import * as i16 from "@angular/forms";
|
|
16
18
|
export declare class AssessmentTakerModule {
|
|
17
19
|
static ɵfac: i0.ɵɵFactoryDeclaration<AssessmentTakerModule, never>;
|
|
18
|
-
static ɵmod: i0.ɵɵNgModuleDeclaration<AssessmentTakerModule, [typeof i1.AssessmentTakerComponent, typeof i2.QuestionTypeEditorComponent, typeof i3.QuestionTypeFileUploadComponent, typeof i4.QuestionTypeLongComponent, typeof i5.QuestionTypeMultiselectComponent, typeof i6.QuestionTypeObjectiveComponent, typeof i7.QuestionTypePreferenceComponent, typeof i8.QuestionTypeShortComponent, typeof i9.SectionInstructionsComponent, typeof i10.QuestionTypeDatePickerComponent], [typeof
|
|
20
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<AssessmentTakerModule, [typeof i1.AssessmentTakerComponent, typeof i2.QuestionTypeEditorComponent, typeof i3.QuestionTypeFileUploadComponent, typeof i4.QuestionTypeLongComponent, typeof i5.QuestionTypeMultiselectComponent, typeof i6.QuestionTypeObjectiveComponent, typeof i7.QuestionTypePreferenceComponent, typeof i8.QuestionTypeShortComponent, typeof i9.SectionInstructionsComponent, typeof i10.QuestionTypeDatePickerComponent, typeof i11.ProctoringResultComponent, typeof i12.ProctoringConsentComponent], [typeof i13.CommonModule, typeof i14.SharedModule, typeof i15.MaterialModules, typeof i16.FormsModule, typeof i16.ReactiveFormsModule], [typeof i1.AssessmentTakerComponent]>;
|
|
19
21
|
static ɵinj: i0.ɵɵInjectorDeclaration<AssessmentTakerModule>;
|
|
20
22
|
}
|
package/lib/modules/assessment-taker/components/proctoring-consent/proctoring-consent.component.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { AfterViewInit, ElementRef, EventEmitter, OnDestroy } from '@angular/core';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export declare class ProctoringConsentComponent implements AfterViewInit, OnDestroy {
|
|
5
|
+
videoRef: ElementRef<HTMLVideoElement>;
|
|
6
|
+
canvasRef: ElementRef<HTMLCanvasElement>;
|
|
7
|
+
labelConfig: {
|
|
8
|
+
[key: string]: string;
|
|
9
|
+
};
|
|
10
|
+
proctoringEnabled: boolean;
|
|
11
|
+
requireCapture: boolean;
|
|
12
|
+
sectionCount: number;
|
|
13
|
+
questionCount: number;
|
|
14
|
+
durationSeconds: number;
|
|
15
|
+
confirmAction?: (referenceImageBase64: string) => Observable<any>;
|
|
16
|
+
proceeded: EventEmitter<void>;
|
|
17
|
+
cameraReady: boolean;
|
|
18
|
+
cameraError: string;
|
|
19
|
+
captured: boolean;
|
|
20
|
+
capturedUrl: string;
|
|
21
|
+
starting: boolean;
|
|
22
|
+
startError: string;
|
|
23
|
+
private stream?;
|
|
24
|
+
private capturedBase64;
|
|
25
|
+
/** Proceed is allowed once a photo is captured, or immediately when no capture is required. */
|
|
26
|
+
get canProceed(): boolean;
|
|
27
|
+
get durationMinutes(): number;
|
|
28
|
+
ngAfterViewInit(): void;
|
|
29
|
+
ngOnDestroy(): void;
|
|
30
|
+
startCamera(): void;
|
|
31
|
+
/** Grabs a still frame from the live preview into a JPEG (used as the reference image). */
|
|
32
|
+
capture(): void;
|
|
33
|
+
retake(): void;
|
|
34
|
+
/** Enabled only once a photo is captured (when required); runs the session-start action. */
|
|
35
|
+
proceed(): void;
|
|
36
|
+
private stopCamera;
|
|
37
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ProctoringConsentComponent, never>;
|
|
38
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ProctoringConsentComponent, "lib-proctoring-consent", never, { "labelConfig": "labelConfig"; "proctoringEnabled": "proctoringEnabled"; "requireCapture": "requireCapture"; "sectionCount": "sectionCount"; "questionCount": "questionCount"; "durationSeconds": "durationSeconds"; "confirmAction": "confirmAction"; }, { "proceeded": "proceeded"; }, never, never>;
|
|
39
|
+
}
|
package/lib/modules/assessment-taker/components/proctoring-result/proctoring-result.component.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { OnInit } from '@angular/core';
|
|
2
|
+
import { MatDialogRef } from '@angular/material/dialog';
|
|
3
|
+
import { AssessmentTakerService } from '../../services/assessment-taker.service';
|
|
4
|
+
import { ProctoringPayload, ProctoringReport, ProctoringSessionSummary } from '../../../../shared/interfaces/proctoring.interface';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
declare type ReportState = 'loading' | 'loaded' | 'empty' | 'error';
|
|
7
|
+
export declare class ProctoringResultComponent implements OnInit {
|
|
8
|
+
dialogRef: MatDialogRef<ProctoringResultComponent>;
|
|
9
|
+
private assessmentTakerService;
|
|
10
|
+
data: {
|
|
11
|
+
labelConfig?: {
|
|
12
|
+
[key: string]: string;
|
|
13
|
+
};
|
|
14
|
+
imageConfig?: {
|
|
15
|
+
[key: string]: string;
|
|
16
|
+
};
|
|
17
|
+
assesseeId?: number;
|
|
18
|
+
assesseeName?: string;
|
|
19
|
+
};
|
|
20
|
+
labelConfig: {
|
|
21
|
+
[key: string]: string;
|
|
22
|
+
};
|
|
23
|
+
imageConfig: {
|
|
24
|
+
[key: string]: string;
|
|
25
|
+
};
|
|
26
|
+
assesseeId: number;
|
|
27
|
+
assesseeName: string;
|
|
28
|
+
sessions: ProctoringSessionSummary[];
|
|
29
|
+
loading: boolean;
|
|
30
|
+
errored: boolean;
|
|
31
|
+
totalElements: number;
|
|
32
|
+
last: boolean;
|
|
33
|
+
private page;
|
|
34
|
+
private readonly size;
|
|
35
|
+
reportBySession: {
|
|
36
|
+
[sessionId: number]: ProctoringReport;
|
|
37
|
+
};
|
|
38
|
+
reportState: {
|
|
39
|
+
[sessionId: number]: ReportState;
|
|
40
|
+
};
|
|
41
|
+
private parsedCache;
|
|
42
|
+
constructor(dialogRef: MatDialogRef<ProctoringResultComponent>, assessmentTakerService: AssessmentTakerService, data: {
|
|
43
|
+
labelConfig?: {
|
|
44
|
+
[key: string]: string;
|
|
45
|
+
};
|
|
46
|
+
imageConfig?: {
|
|
47
|
+
[key: string]: string;
|
|
48
|
+
};
|
|
49
|
+
assesseeId?: number;
|
|
50
|
+
assesseeName?: string;
|
|
51
|
+
});
|
|
52
|
+
ngOnInit(): void;
|
|
53
|
+
loadSessions(): void;
|
|
54
|
+
loadMore(): void;
|
|
55
|
+
/** Fetches the report for a session the first time its panel is expanded. */
|
|
56
|
+
loadReport(session: ProctoringSessionSummary): void;
|
|
57
|
+
trackBySessionId(_index: number, session: ProctoringSessionSummary): number;
|
|
58
|
+
trackByIndex(index: number): number;
|
|
59
|
+
/** Parses (and caches) the reportPayload JSON. Returns null if absent or not valid JSON. */
|
|
60
|
+
getParsedPayload(report: ProctoringReport): ProctoringPayload | null;
|
|
61
|
+
/** Formats a duration in seconds as `Mm Ss` (or `Ss` under a minute). */
|
|
62
|
+
formatDuration(seconds?: number): string;
|
|
63
|
+
/** Session timestamps are epoch milliseconds already; guard 0/undefined so nothing renders. */
|
|
64
|
+
toMillis(epochMillis?: number): number | null;
|
|
65
|
+
/**
|
|
66
|
+
* Theme badge classes for a session status.
|
|
67
|
+
* ACTIVE = running, VALIDATING = report in progress, VALIDATED = report ready,
|
|
68
|
+
* ENDED = stopped/invalidated, FAILED = errored.
|
|
69
|
+
*/
|
|
70
|
+
statusBadgeClass(status?: string): string;
|
|
71
|
+
/** Maps a raw event code (e.g. `tab.hidden`) to a friendly label, falling back to the raw code. */
|
|
72
|
+
eventTypeLabel(type?: string): string;
|
|
73
|
+
/** Maps a raw reason code (e.g. `browser_activity`) to a friendly label, falling back to the raw code. */
|
|
74
|
+
reasonCodeLabel(code?: string): string;
|
|
75
|
+
/** Highlights integrity-relevant timeline events (tab switches, face issues, session markers). */
|
|
76
|
+
isNoteworthy(type?: string): boolean;
|
|
77
|
+
close(): void;
|
|
78
|
+
imageErrorHandler(event: any, filePath: string): void;
|
|
79
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ProctoringResultComponent, never>;
|
|
80
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ProctoringResultComponent, "lib-proctoring-result", never, {}, {}, never, never>;
|
|
81
|
+
}
|
|
82
|
+
export {};
|
|
@@ -38,6 +38,7 @@ export declare class QuestionTypeFileUploadComponent implements ControlValueAcce
|
|
|
38
38
|
imageErrorHandler(event: any, filePath: string): void;
|
|
39
39
|
getFileIcon(attachment: Attachment): string;
|
|
40
40
|
viewFile(url: string): void;
|
|
41
|
+
trackByFile(index: number, file: Attachment): string;
|
|
41
42
|
static ɵfac: i0.ɵɵFactoryDeclaration<QuestionTypeFileUploadComponent, [{ optional: true; self: true; }, null]>;
|
|
42
43
|
static ɵcmp: i0.ɵɵComponentDeclaration<QuestionTypeFileUploadComponent, "lib-question-type-file-upload", never, { "required": "required"; "assessmentInstanceId": "assessmentInstanceId"; "question": "question"; "labelConfig": "labelConfig"; "imageConfig": "imageConfig"; }, { "snackbarMessage": "snackbarMessage"; }, never, never>;
|
|
43
44
|
}
|
|
@@ -29,6 +29,7 @@ export declare class QuestionTypeMultiselectComponent implements ControlValueAcc
|
|
|
29
29
|
isEvaluationEnabled(): boolean;
|
|
30
30
|
getSelectionStatus(option: any): string | null;
|
|
31
31
|
imageErrorHandler(event: any, filePath: string): void;
|
|
32
|
+
trackByOptionId(index: number, option: any): string;
|
|
32
33
|
static ɵfac: i0.ɵɵFactoryDeclaration<QuestionTypeMultiselectComponent, [{ optional: true; self: true; }]>;
|
|
33
34
|
static ɵcmp: i0.ɵɵComponentDeclaration<QuestionTypeMultiselectComponent, "lib-question-type-multiselect", never, { "required": "required"; "question": "question"; "showCorrectAnswers": "showCorrectAnswers"; "imageConfig": "imageConfig"; "answerObj": "answerObj"; }, { "viewChild": "viewChild"; }, never, never>;
|
|
34
35
|
}
|