UNPKG

sl-questionnaire

Version:
978 lines (963 loc) 55.7 kB
import { __decorate, __awaiter } from 'tslib'; import { CommonModule } from '@angular/common'; import { ɵɵdefineInjectable, Injectable, Input, Component, EventEmitter, Output, ɵɵinject, ViewChild, NgModule } from '@angular/core'; import { FormControl, FormArray, Validators, FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { SuiModalService, TemplateModalConfig, SuiModule } from 'ng2-semantic-ui-v9'; import { isEmpty } from 'lodash-es'; let SlTranslateService = class SlTranslateService { }; SlTranslateService.ɵprov = ɵɵdefineInjectable({ factory: function SlTranslateService_Factory() { return new SlTranslateService(); }, token: SlTranslateService, providedIn: "root" }); SlTranslateService = __decorate([ Injectable({ providedIn: 'root', }) ], SlTranslateService); var ResponseType; (function (ResponseType) { ResponseType["TEXT"] = "text"; ResponseType["NUMBER"] = "number"; ResponseType["RADIO"] = "radio"; ResponseType["MULTISELECT"] = "multiselect"; ResponseType["DATE"] = "date"; ResponseType["SLIDER"] = "slider"; ResponseType["PAGEQUESTIONS"] = "pageQuestions"; ResponseType["MATRIX"] = "matrix"; })(ResponseType || (ResponseType = {})); let SlQuestionnaireService = class SlQuestionnaireService { constructor() { this.validate = (data) => { return (control) => { if (typeof data.validation == 'string') { return null; } if (!data.validation.required) { return null; } if (data.validation.regex) { const forbidden = this.testRegex(data.validation.regex, control.value); return forbidden ? null : { err: 'Invalid character found' }; } if (data.validation.IsNumber) { if (!control.value) { return { err: 'Number not entered' }; } const forbidden = !isNaN(control.value); return forbidden ? null : { err: 'Only numbers allowed' }; } if (data.validation.required) { if (!control.value) { return { err: 'Required field' }; } if (data.responseType == ResponseType.MULTISELECT) { return control.value.some((v) => v != '') ? null : { err: 'Select at least one option' }; } if (data.responseType == ResponseType.SLIDER) { let min = data.validation.min; let max = data.validation.max; return min <= control.value && control.value <= max ? null : { err: 'Selected value not within range' }; } } }; }; } testRegex(regexExpression, value) { const regex = new RegExp(regexExpression); return regex.test(value); } setSubmissionId(submissionId) { this._submissionId = submissionId; } getSubmissionId() { return this._submissionId; } mapSubmissionToAssessment(data) { const assessment = data.assessment; for (const evidence of assessment.evidences) { const validSubmission = assessment.submissions[evidence.externalId]; if (validSubmission) { evidence.notApplicable = validSubmission.notApplicable; if (evidence.notApplicable) { continue; } for (const section of evidence.sections) { for (const question of section.questions) { if (question.responseType === 'pageQuestions') { for (const questions of question.pageQuestions) { questions.value = questions.responseType !== 'matrix' ? validSubmission.answers[questions._id].value : this.constructMatrixValue(validSubmission, questions, evidence.externalId); questions.remarks = validSubmission.answers[questions._id] ? validSubmission.answers[questions._id].remarks : ''; questions.fileName = validSubmission.answers[questions._id] ? validSubmission.answers[questions._id].fileName : []; } } else if (validSubmission.answers && validSubmission.answers[question._id]) { question.value = question.responseType !== 'matrix' ? validSubmission.answers[question._id].value : this.constructMatrixValue(validSubmission, question, evidence.externalId); question.remarks = validSubmission.answers[question._id] ? validSubmission.answers[question._id].remarks : ''; question.fileName = validSubmission.answers[question._id] ? validSubmission.answers[question._id].fileName : []; } } } } } this.setSubmissionId(assessment.submissionId); return data; } constructMatrixValue(validSubmission, matrixQuestion, ecmId) { matrixQuestion.value = []; if (validSubmission.answers && validSubmission.answers[matrixQuestion._id] && validSubmission.answers[matrixQuestion._id].value) { for (const answer of validSubmission.answers[matrixQuestion._id].value) { matrixQuestion.value.push(JSON.parse(JSON.stringify(matrixQuestion.instanceQuestions))); } matrixQuestion.value.forEach((instance, index) => { instance.forEach((question, instanceIndex) => { if (validSubmission.answers[matrixQuestion._id] && validSubmission.answers[matrixQuestion._id].value[index][question._id]) { question.value = validSubmission.answers[matrixQuestion._id].value[index][question._id].value; question.remarks = validSubmission.answers[matrixQuestion._id].value[index][question._id].remarks; question.fileName = validSubmission.answers[matrixQuestion._id].value[index][question._id].fileName; } }); }); return matrixQuestion.value; } else { return []; } } getEvidenceData(evidence, formValues) { let sections = evidence.sections; let answers = this.getSectionData(sections, formValues); let payloadData = { externalId: evidence.externalId, answers: answers, startTime: evidence.startTime, endTime: Date.now(), }; return payloadData; } getSectionData(sections, formValues) { let answers = {}; for (let index = 0; index < sections.length; index++) { answers = Object.assign(Object.assign({}, answers), this.createpayload(sections[index].questions, formValues)); } return answers; } createpayload(questions, formValues) { let answers = {}; for (let index = 0; index < questions.length; index++) { let currentQuestion = questions[index]; if (currentQuestion.responseType == 'pageQuestions') { answers = Object.assign(Object.assign({}, answers), this.createpayload(currentQuestion.pageQuestions, formValues)); continue; } if (currentQuestion.responseType == 'matrix') { for (let index = 0; index < currentQuestion.value.length; index++) { formValues[currentQuestion._id][index] = this.createpayload(currentQuestion.value[index], formValues[currentQuestion._id][index]); } } let perQuestionData = this.formatToPayload(currentQuestion, formValues); answers[currentQuestion._id] = perQuestionData; } return answers; } formatToPayload(currentQuestion, formValues) { let value = currentQuestion.responseType != 'matrix' ? currentQuestion.value : formValues[currentQuestion._id]; return { qid: currentQuestion._id, value: value, remarks: currentQuestion.remarks, fileName: currentQuestion.fileName, gpsLocation: '', payload: { question: currentQuestion.question, labels: formValues[currentQuestion._id], responseType: currentQuestion.responseType, filesNotUploaded: [], }, startTime: currentQuestion.startTime, endTime: currentQuestion.endTime, criteriaId: currentQuestion.payload.criteriaId, responseType: currentQuestion.responseType, evidenceMethod: currentQuestion.evidenceMethod, rubricLevel: '', }; } }; SlQuestionnaireService.ɵprov = ɵɵdefineInjectable({ factory: function SlQuestionnaireService_Factory() { return new SlQuestionnaireService(); }, token: SlQuestionnaireService, providedIn: "root" }); SlQuestionnaireService = __decorate([ Injectable({ providedIn: 'root', }) ], SlQuestionnaireService); let TextInputComponent = class TextInputComponent { constructor(qService, translate) { this.qService = qService; this.translate = translate; } ngOnInit() { this.placeholder = this.translate['frmelmnts'].lbl.enterResponse; setTimeout(() => { this.questionnaireForm.addControl(this.question._id, new FormControl(this.question.value || null, [ this.qService.validate(this.question), ])); this.question.startTime = this.question.startTime ? this.question.startTime : Date.now(); }); } get isValid() { return this.questionnaireForm.controls[this.question._id].valid; } get isTouched() { return this.questionnaireForm.controls[this.question._id].touched; } onChange(e) { let value = e.target.value; this.question.value = value; this.question.endTime = Date.now(); } }; TextInputComponent.ctorParameters = () => [ { type: SlQuestionnaireService }, { type: SlTranslateService } ]; __decorate([ Input() ], TextInputComponent.prototype, "questionnaireForm", void 0); __decorate([ Input() ], TextInputComponent.prototype, "question", void 0); TextInputComponent = __decorate([ Component({ selector: 'sl-text-input', template: "<div\n [formGroup]=\"questionnaireForm\"\n *ngIf=\"questionnaireForm?.contains(question._id)\"\n>\n <input\n type=\"text\"\n [formControlName]=\"question?._id\"\n [ngClass]=\"!isValid && isTouched ? 'is-invalid ' : 'is-valid'\"\n class=\"sb-form-control\"\n [placeholder]=\"placeholder\"\n (change)=\"onChange($event)\"\n [value]=\"question.value\"\n />\n</div>\n", styles: [""] }) ], TextInputComponent); let DateInputComponent = class DateInputComponent { constructor(qService, translate) { this.qService = qService; this.translate = translate; } ngOnInit() { var _a; this.autoCaptureText = (_a = this.translate['frmelmnts'].btn) === null || _a === void 0 ? void 0 : _a.autoCapture; setTimeout(() => { this.questionnaireForm.addControl(this.question._id, new FormControl(this.question.value ? new Date(this.question.value) : null, [this.qService.validate(this.question)])); this.question.startTime = this.question.startTime ? this.question.startTime : Date.now(); }); this.min = this.question.validation.min ? new Date(this.question.validation.min) : null; this.max = this.question.validation.max ? new Date(this.question.validation.max) : null; } onChange(e) { let value = e; this.question.value = value; this.question.endTime = Date.now(); } autoCapture() { this.questionnaireForm.controls[this.question._id].patchValue(new Date(Date.now())); } }; DateInputComponent.ctorParameters = () => [ { type: SlQuestionnaireService }, { type: SlTranslateService } ]; __decorate([ Input() ], DateInputComponent.prototype, "questionnaireForm", void 0); __decorate([ Input() ], DateInputComponent.prototype, "question", void 0); __decorate([ Input() ], DateInputComponent.prototype, "autoCaptureText", void 0); DateInputComponent = __decorate([ Component({ selector: 'sl-date-input', template: "<div\n [formGroup]=\"questionnaireForm\"\n *ngIf=\"questionnaireForm?.contains(question._id)\"\n class=\"d-flex flex-ai-center flex-jc-space-between\"\n>\n <div class=\"ui left icon input\">\n <i class=\"calendar icon\"></i>\n <input\n suiDatepicker\n [pickerMode]=\"'date'\"\n [pickerUseNativeOnMobile]=\"false\"\n [formControlName]=\"question?._id\"\n (pickerSelectedDateChange)=\"onChange($event)\"\n class=\"question-date-input\"\n [pickerMinDate]=\"min\"\n [pickerMaxDate]=\"max\"\n />\n </div>\n <div *ngIf=\"question?.autoCapture && !question?.value\">\n <button class=\"sb-btn sb-btn-normal sb-btn-primary\" (click)=\"autoCapture()\">\n\t\t{{autoCaptureText}}\n </button>\n </div>\n</div>\n", styles: [""] }) ], DateInputComponent); let NumberInputComponent = class NumberInputComponent { constructor(qService, translate) { this.qService = qService; this.translate = translate; } ngOnInit() { var _a, _b; this.placeholder = (_b = (_a = this.translate['frmelmnts']) === null || _a === void 0 ? void 0 : _a.lbl) === null || _b === void 0 ? void 0 : _b.enterResponse; setTimeout(() => { this.questionnaireForm.addControl(this.question._id, new FormControl(this.question.value || null, [ this.qService.validate(this.question), ])); this.question.startTime = this.question.startTime ? this.question.startTime : Date.now(); }); } onChange(e) { let value = e.target.value; this.question.value = value; this.question.endTime = Date.now(); } get isValid() { return this.questionnaireForm.controls[this.question._id].valid; } get isTouched() { return this.questionnaireForm.controls[this.question._id].touched; } }; NumberInputComponent.ctorParameters = () => [ { type: SlQuestionnaireService }, { type: SlTranslateService } ]; __decorate([ Input() ], NumberInputComponent.prototype, "questionnaireForm", void 0); __decorate([ Input() ], NumberInputComponent.prototype, "question", void 0); NumberInputComponent = __decorate([ Component({ selector: 'sl-number-input', template: "<div\n [formGroup]=\"questionnaireForm\"\n *ngIf=\"questionnaireForm?.contains(question._id)\"\n>\n <input\n type=\"number\"\n [formControlName]=\"question?._id\"\n class=\"sb-form-control\"\n [placeholder]=\"placeholder\"\n (change)=\"onChange($event)\"\n [value]=\"question.value\"\n />\n</div>\n", styles: [""] }) ], NumberInputComponent); let RangeInputComponent = class RangeInputComponent { constructor(qService) { this.qService = qService; } ngOnInit() { setTimeout(() => { this.questionnaireForm.addControl(this.question._id, new FormControl(this.question.value || null, [ this.qService.validate(this.question), ])); this.question.startTime = this.question.startTime ? this.question.startTime : Date.now(); }); } onChange(e) { let value = e.target.value; this.question.value = value; this.question.endTime = Date.now(); } get isValid() { return this.questionnaireForm.controls[this.question._id].valid; } get isTouched() { return this.questionnaireForm.controls[this.question._id].touched; } get min() { if (typeof this.question.validation == 'string') { return null; } return this.question.validation.min; } get max() { if (typeof this.question.validation == 'string') { return null; } return this.question.validation.max; } }; RangeInputComponent.ctorParameters = () => [ { type: SlQuestionnaireService } ]; __decorate([ Input() ], RangeInputComponent.prototype, "questionnaireForm", void 0); __decorate([ Input() ], RangeInputComponent.prototype, "question", void 0); RangeInputComponent = __decorate([ Component({ selector: 'sl-range-input', template: "<div\n class=\"\n d-flex\n flex-ai-center flex-dc\n mt-30\n ng-dirty ng-invalid ng-touched\n range-wrap\n \"\n [formGroup]=\"questionnaireForm\"\n *ngIf=\"questionnaireForm?.contains(question._id)\"\n>\n <div class=\"range-value\" id=\"rangeV\">{{ this.question.value }}</div>\n\n <input\n id=\"range\"\n type=\"range\"\n [min]=\"min\"\n [max]=\"max\"\n [ngClass]=\"isValid && isTouched ? 'is-invalid' : 'is-valid'\"\n step=\"1\"\n [formControlName]=\"question?._id\"\n class=\"w-100\"\n (change)=\"onChange($event)\"\n [value]=\"question.value\"\n />\n</div>\n", styles: [".range-value{width:50px;height:50px;line-height:50px;border-radius:50%;font-size:20px;color:#0274fd;text-align:center;background:#e9e8d9;margin-bottom:17px}input[type=range]{height:34px;-webkit-appearance:none;margin:10px 0;width:100%}input[type=range]:focus{outline:0}input[type=range]::-webkit-slider-runnable-track{width:100%;height:11px;cursor:pointer;animate:.2s;box-shadow:1px 1px 1px #000;background:#74a9d8;border-radius:1px;border:0 solid #010101}input[type=range]::-webkit-slider-thumb{box-shadow:1px 1px 1px #000031;border:1px solid #00001e;height:26px;width:26px;border-radius:15px;background:#fff;cursor:pointer;-webkit-appearance:none;margin-top:-8px}input[type=range]:focus::-webkit-slider-runnable-track{background:#74a9d8}input[type=range]::-moz-range-track{width:100%;height:11px;cursor:pointer;animate:.2s;box-shadow:1px 1px 1px #000;background:#74a9d8;border-radius:1px;border:0 solid #010101}input[type=range]::-moz-range-thumb{box-shadow:1px 1px 1px #000031;border:1px solid #00001e;height:26px;width:26px;border-radius:15px;background:#fff;cursor:pointer}input[type=range]::-ms-track{width:100%;height:11px;cursor:pointer;animate:.2s;background:0 0;border-color:transparent;color:transparent}input[type=range]::-ms-fill-lower{background:#74a9d8;border:0 solid #010101;border-radius:2px;box-shadow:1px 1px 1px #000}input[type=range]::-ms-fill-upper{background:#74a9d8;border:0 solid #010101;border-radius:2px;box-shadow:1px 1px 1px #000}input[type=range]::-ms-thumb{margin-top:1px;box-shadow:1px 1px 1px #000031;border:1px solid #00001e;height:26px;width:26px;border-radius:15px;background:#fff;cursor:pointer}input[type=range]:focus::-ms-fill-lower{background:#74a9d8}input[type=range]:focus::-ms-fill-upper{background:#74a9d8}"] }) ], RangeInputComponent); let RadioInputComponent = class RadioInputComponent { constructor(qService, translate) { this.qService = qService; this.translate = translate; this.dependentParent = new EventEmitter(); } ngOnInit() { var _a; this.hintCloseText = (_a = this.translate['frmelmnts'].btn) === null || _a === void 0 ? void 0 : _a.close; setTimeout(() => { this.questionnaireForm.addControl(this.question._id, new FormControl(this.question.value || null, this.qService.validate(this.question))); this.question.startTime = this.question.startTime ? this.question.startTime : Date.now(); if (this.question.value) { if (this.question.children.length) { this.dependentParent.emit(this.question); } } }); } get isValid() { return this.questionnaireForm.controls[this.question._id].valid; } get isTouched() { return this.questionnaireForm.controls[this.question._id].touched; } onChange(value) { this.questionnaireForm.controls[this.question._id].setValue(value); this.question.value = value; this.question.endTime = Date.now(); if (this.question.children.length) { this.dependentParent.emit(this.question); } } }; RadioInputComponent.ctorParameters = () => [ { type: SlQuestionnaireService }, { type: SlTranslateService } ]; __decorate([ Input() ], RadioInputComponent.prototype, "options", void 0); __decorate([ Input() ], RadioInputComponent.prototype, "questionnaireForm", void 0); __decorate([ Input() ], RadioInputComponent.prototype, "question", void 0); __decorate([ Output() ], RadioInputComponent.prototype, "dependentParent", void 0); RadioInputComponent = __decorate([ Component({ selector: 'sl-radio-input', template: "<div *ngIf=\"questionnaireForm?.contains(question._id)\">\n <div\n *ngFor=\"let o of options; let optionIndex = index\"\n [formGroup]=\"questionnaireForm\"\n class=\"\n mb-15\n sb-radio-btn-checkbox sb-radio-btn-primary\n d-flex\n flex-ai-baseline\n \"\n >\n <input\n type=\"radio\"\n (change)=\"onChange(o.value)\"\n [name]=\"question._id\"\n [ngClass]=\"isValid && isTouched ? 'is-invalid' : 'is-valid'\"\n [value]=\"o.value\"\n [formControlName]=\"question._id\"\n />\n <label>{{ o.label }}</label>\n <div *ngIf=\"question?.option && question?.option[optionIndex]?.hint\">\n <i\n class=\"icon large lightbulb\"\n (click)=\"\n isDimmed = !isDimmed; hint = question?.option[optionIndex]?.hint\n \"\n ></i>\n </div>\n </div>\n</div>\n\n<sui-dimmer [(isDimmed)]=\"isDimmed\" [isClickable]=\"true\">\n <h4 class=\"ui inverted header\">{{ hint }}</h4>\n <button\n type=\"button\"\n class=\"sb-btn sb-btn-sm sb-btn-white text-uppercase flex-basis-1\"\n type=\"submit\"\n >\n {{ hintCloseText}}\n </button>\n</sui-dimmer>\n", styles: [""] }) ], RadioInputComponent); let CheckboxInputComponent = class CheckboxInputComponent { constructor(qService, translate) { this.qService = qService; this.translate = translate; this.dependentParent = new EventEmitter(); } ngOnInit() { var _a; this.hintCloseText = (_a = this.translate['frmelmnts'].btn) === null || _a === void 0 ? void 0 : _a.close; setTimeout(() => { const optionControl = this.options.map((v) => { if (this.question.value && this.question.value.find((_v) => _v == v.value)) { return new FormControl(v.value); } return new FormControl(''); }); this.questionnaireForm.addControl(this.question._id, new FormArray(optionControl, this.qService.validate(this.question))); this.question.startTime = this.question.startTime ? this.question.startTime : Date.now(); if (this.question.value.length) { if (this.question.children.length) { this.dependentParent.emit(this.question); } } }); } onChange(oId, isChecked, oIndex) { const formArray = this.questionnaireForm.get(this.question._id); if (isChecked) { formArray.controls[oIndex].patchValue(oId); } this.question.value = this.questionnaireForm.controls[this.question._id].value; this.question.value = this.question.value.filter(Boolean); this.question.endTime = Date.now(); if (this.question.children.length) { this.dependentParent.emit(this.question); } } get isValid() { return this.questionnaireForm.controls[this.question._id].valid; } get isTouched() { return this.questionnaireForm.controls[this.question._id].touched; } }; CheckboxInputComponent.ctorParameters = () => [ { type: SlQuestionnaireService }, { type: SlTranslateService } ]; __decorate([ Input() ], CheckboxInputComponent.prototype, "options", void 0); __decorate([ Input() ], CheckboxInputComponent.prototype, "questionnaireForm", void 0); __decorate([ Input() ], CheckboxInputComponent.prototype, "question", void 0); __decorate([ Output() ], CheckboxInputComponent.prototype, "dependentParent", void 0); CheckboxInputComponent = __decorate([ Component({ selector: 'sl-checkbox-input', template: "<div *ngIf=\"questionnaireForm?.contains(question._id)\">\n <div\n *ngFor=\"let o of options; let i = index\"\n [formGroup]=\"questionnaireForm\"\n class=\"mb-15 sb-checkbox sb-checkbox-secondary d-flex flex-ai-baseline\"\n >\n <div [formArrayName]=\"question._id\">\n <sui-checkbox\n (checkChange)=\"onChange(o.value, $event, i)\"\n [formControlName]=\"i\"\n >\n {{ o.label }}\n </sui-checkbox>\n </div>\n <div *ngIf=\"question?.option && question?.option[i]?.hint\">\n <i\n class=\"icon large lightbulb\"\n (click)=\"isDimmed = !isDimmed; hint = question?.option[i]?.hint\"\n ></i>\n </div>\n </div>\n</div>\n\n<sui-dimmer [(isDimmed)]=\"isDimmed\" [isClickable]=\"true\">\n <h4 class=\"ui inverted header\">{{ hint }}</h4>\n <button\n type=\"button\"\n class=\"sb-btn sb-btn-sm sb-btn-white text-uppercase flex-basis-1\"\n type=\"submit\"\n >\n {{ hintCloseText }}\n </button>\n</sui-dimmer>\n", styles: [""] }) ], CheckboxInputComponent); let QuesRemarksComponent = class QuesRemarksComponent { constructor(translate) { this.translate = translate; this.remark = ''; this.saveClicked = new EventEmitter(); } ngOnInit() { var _a; this.title = (_a = this.translate['frmelmnts'].lbl) === null || _a === void 0 ? void 0 : _a.remark_title; this.remarksAddText = this.translate['frmelmnts'].btn.add; this.remark = this.question.remarks; this.remark ? (this.showRemarks = true) : false; } saveRemark() { this.question.remarks = this.remark; this.saveClicked.emit({ value: this.remark }); } deleteRemark() { this.remark = ''; this.saveRemark(); this.showRemarks = false; } }; QuesRemarksComponent.ctorParameters = () => [ { type: SlTranslateService } ]; __decorate([ Output() ], QuesRemarksComponent.prototype, "saveClicked", void 0); __decorate([ Input() ], QuesRemarksComponent.prototype, "question", void 0); QuesRemarksComponent = __decorate([ Component({ selector: 'sl-ques-remarks', template: "<div class=\"d-flex flex-ai-center flex-jc-space-between my-10\">\n <h5 class=\"my-10\">{{ title }}</h5>\n <button\n class=\"sb-btn sb-btn-normal sb-btn-primary\"\n *ngIf=\"!remark.length\"\n (click)=\"showRemarks = true\"\n >\n {{ remarksAddText }}\n </button>\n <span *ngIf=\"remark.length\" (click)=\"deleteRemark()\"\n ><i class=\"trash large icon\"></i\n ></span>\n</div>\n\n<div class=\"d-flex flex-ai-end\" *ngIf=\"showRemarks\">\n <textarea\n rows=\"3\"\n class=\"w-100\"\n [(ngModel)]=\"remark\"\n (ngModelChange)=\"saveRemark()\"\n >\n </textarea>\n</div>\n", styles: [""] }) ], QuesRemarksComponent); let SlUtilsService = class SlUtilsService { constructor(modalService) { this.modalService = modalService; } /** * @param {AlertMeta} meta: Alert Meta Form Object * @param {String} meta.title Optional ! Display title of alert fields * @param {String} meta.size Provide size of alert.('tiny','mini) * @param {AlertBodyType} meta.bodyType Alert-content type to show in alert body * @param {String} meta.data content to show * @param {String} meta.buttonClass class to apply on button div * @param {String} meta.acceptText text to show in accept button * @param {String} meta.cancelText text to show in accept button * @param {String} meta.type Optional ! To set type of alert * @param {Boolean} meta.closeIcon Optional ! Show top right close icon , default = false */ alert(meta) { const button = []; meta.acceptText && button.push({ type: 'accept', returnValue: true, buttonText: meta.acceptText, }); meta.cancelText && button.push({ type: 'cancel', returnValue: false, buttonText: meta.cancelText, }); let alertMeta = { type: meta.type, size: meta.size, isClosed: meta.closeIcon, content: { title: meta.title, body: { type: meta.bodyType, data: meta.data, }, }, footer: { className: meta.buttonClass, buttons: button, }, }; return this.openAlert(alertMeta); } }; SlUtilsService.ctorParameters = () => [ { type: SuiModalService } ]; SlUtilsService.ɵprov = ɵɵdefineInjectable({ factory: function SlUtilsService_Factory() { return new SlUtilsService(ɵɵinject(SuiModalService)); }, token: SlUtilsService, providedIn: "root" }); SlUtilsService = __decorate([ Injectable({ providedIn: 'root', }) ], SlUtilsService); let AttachmentComponent = class AttachmentComponent { constructor(translate, utils) { this.translate = translate; this.utils = utils; } ngOnInit() { } basicUpload(files) { let sizeMB = +(files[0].size / 1000 / 1000).toFixed(4); if (sizeMB > 20) { this.fileLimitCross(); return; } this.formData = new FormData(); Array.from(files).forEach((f) => this.formData.append('file', f)); this.preSignedUrl(this.getFileNames(this.formData)); } fileLimitCross() { const alertMeta = { size: 'tiny', bodyType: 'text', data: this.translate['frmelmnts'].alert.fileLimitCross20, buttonClass: 'single-btn', acceptText: this.translate['frmelmnts'].btn.ok, cancelText: null, }; this.utils.alert(alertMeta); } getFileNames(formData) { let files = []; formData.forEach((element) => { files.push(element.name); }); return files; } preSignedUrl(files) { let payload = {}; payload['ref'] = 'survey'; payload['request'] = {}; payload['request'][this.data.submissionId] = { files: files, }; this.utils.getPreSingedUrls(payload).subscribe((imageData) => { const presignedUrlData = imageData['result'][this.data.submissionId].files[0]; this.formData.append('url', presignedUrlData.url); this.utils.cloudStorageUpload(this.formData).subscribe((success) => { if (success.status === 200) { const obj = { name: this.getFileNames(this.formData)[0], url: presignedUrlData.url.split('?')[0], }; for (const key of Object.keys(presignedUrlData.payload)) { obj[key] = presignedUrlData['payload'][key]; } this.data.files.push(obj); const alertMeta = { size: 'tiny', bodyType: 'text', data: this.translate['frmelmnts'].alert.evidenceUploaded, buttonClass: 'single-btn', acceptText: this.translate['frmelmnts'].btn.ok, cancelText: null, type: 'uploaded', }; this.utils.alert(alertMeta); } else { this.utils.error(this.translate['frmelmnts'].message.unableToUpload); } }, (error) => { this.utils.error(this.translate['frmelmnts'].message.unableToUpload); }); }, (error) => { console.log(error); }); } extension(name) { return name.split('.').pop(); } openFile(file) { window.open(file.url, '_blank'); } deleteAttachment(fileIndex) { return __awaiter(this, void 0, void 0, function* () { const alertMeta = { size: 'mini', bodyType: 'text', data: this.translate['frmelmnts'].alert.confirmEvidenceDelete, buttonClass: 'double-btn', acceptText: this.translate['frmelmnts'].btn.ok, cancelText: this.translate['frmelmnts'].btn.no, }; const accepted = yield this.utils.alert(alertMeta); if (!accepted) { return; } this.data.files.splice(fileIndex, 1); }); } onAddApproval(file) { return __awaiter(this, void 0, void 0, function* () { let html = ` ${this.translate['frmelmnts'].alert.evidence_content_policy}<a href='/term-of-use.html' target="_blank">${this.translate['frmelmnts'].alert.evidence_content_policy_label}</a> .${this.translate['frmelmnts'].alert.uploadevidencecontent} `; const alertMeta = { size: 'tiny', bodyType: 'checkbox', data: html, buttonClass: 'double-btn', acceptText: this.translate['frmelmnts'].btn.upload, cancelText: this.translate['frmelmnts'].btn.donotupload, }; let returnData = yield this.utils.alert(alertMeta); if (!returnData) { this.notAccepted(); return; } file.click(); }); } notAccepted() { const alertMeta = { size: 'tiny', bodyType: 'text', data: this.translate['frmelmnts'].alert.uploadTermsRejected, buttonClass: 'single-btn', acceptText: this.translate['frmelmnts'].btn.ok, cancelText: null, type: 'notAccepted', }; this.utils.alert(alertMeta); } }; AttachmentComponent.ctorParameters = () => [ { type: SlTranslateService }, { type: SlUtilsService } ]; __decorate([ Input() ], AttachmentComponent.prototype, "data", void 0); AttachmentComponent = __decorate([ Component({ selector: 'sl-attachment', template: "<label for=\"file-upload\" class=\"custom-file-upload\"></label>\n<input\n id=\"file-upload\"\n type=\"file\"\n #file\n (change)=\"basicUpload($event.target.files)\"\n/>\n<div class=\"d-flex\">\n <div class=\"bs-1 p-20\" (click)=\"onAddApproval(file)\">\n <i class=\"plus icon\"></i>\n </div>\n <div\n *ngFor=\"let item of data.files; let i = index\"\n (click)=\"openFile(item)\"\n class=\"area\"\n >\n <a\n class=\"remove-image\"\n (click)=\"$event.stopPropagation(); deleteAttachment(i)\"\n >&#215;</a\n >\n <div *ngIf=\"extension(item.name) == 'png'\" class=\"mx-10\">\n <i class=\"file image outline icon\"></i>\n </div>\n <div *ngIf=\"extension(item.name) == 'jpg'\" class=\"mx-10\">\n <i class=\"file image outline icon\"></i>\n </div>\n <div *ngIf=\"extension(item.name) == 'jpeg'\" class=\"mx-10\">\n <i class=\"file image outline icon\"></i>\n </div>\n <div *ngIf=\"extension(item.name) == 'pdf'\" class=\"mx-10\">\n <i class=\"file pdf outline icon\"></i>\n </div>\n </div>\n</div>\n", styles: ["input[type=file]{display:none}.area{position:relative}.area a{display:inline}.area i{font-size:40px}.remove-image{display:none;position:absolute;top:-10px;right:2px;border-radius:10em;padding:2px 6px 3px;text-decoration:none;background:#555;border:3px solid #fff;color:#fff!important;box-shadow:0 2px 6px rgba(0,0,0,.5),inset 0 2px 4px rgba(0,0,0,.3);text-shadow:0 1px 2px rgba(0,0,0,.5);transition:background .5s}.remove-image:hover{background:#e54e4e;padding:3px 7px 5px;top:-11px;right:2px}.remove-image:active{background:#e54e4e;top:-10px;right:2px}.bs-1{background-color:grey}"] }) ], AttachmentComponent); let InputComponent = class InputComponent { constructor(translate, qService) { this.translate = translate; this.qService = qService; this.dimmerCloseText = this.translate['frmelmnts'].btn.close; } get reponseType() { return ResponseType; } toggleQuestion(parent) { const { children } = parent; this.questions.map((q, i) => { if (children.includes(q._id)) { let child = this.questions[i]; child['canDisplay'] = this.canDisplayChildQ(child, i); if (child['canDisplay'] == false) { child.value = ''; this.questionnaireForm.removeControl(child._id); } } }); } canDisplayChildQ(currentQuestion, currentQuestionIndex) { let display = true; if (typeof currentQuestion.visibleIf == 'string' || null || undefined) { return false; //if condition not present } for (const question of this.questions) { for (const condition of currentQuestion.visibleIf) { if (condition._id === question._id) { let expression = []; if (condition.operator != '===') { if (question.responseType === 'multiselect') { for (const parentValue of question.value) { for (const value of condition.value) { expression.push('(', "'" + parentValue + "'", '===', "'" + value + "'", ')', condition.operator); } } } else { for (const value of condition.value) { expression.push('(', "'" + question.value + "'", '===', "'" + value + "'", ')', condition.operator); } } expression.pop(); } else { if (question.responseType === 'multiselect') { for (const value of question.value) { expression.push('(', "'" + condition.value + "'", '===', "'" + value + "'", ')', '||'); } expression.pop(); } else { expression.push('(', "'" + question.value + "'", condition.operator, "'" + condition.value + "'", ')'); } } if (!eval(expression.join(''))) { this.questions[currentQuestionIndex].isCompleted = true; return false; } else { // this.questions[currentQuestionIndex].isCompleted = // this.utils.isQuestionComplete(currentQuestion); } } } } return display; } }; InputComponent.ctorParameters = () => [ { type: SlTranslateService }, { type: SlQuestionnaireService } ]; __decorate([ Input() ], InputComponent.prototype, "questions", void 0); __decorate([ Input() ], InputComponent.prototype, "questionnaireForm", void 0); InputComponent = __decorate([ Component({ selector: 'sl-input', template: "<div *ngFor=\"let question of questions; let qi = index\">\n <div\n [ngClass]=\"{\n 'ui card question-card sb--card relative9':\n question.responseType != 'pageQuestions'\n }\"\n *ngIf=\"!question.visibleIf.length || question.canDisplay == true\"\n >\n <div [ngClass]=\"{ content: question.responseType != 'pageQuestions' }\">\n <div class=\"d-flex flex-ai-flex-start flex-jc-space-between\">\n <div\n *ngFor=\"let q of question.question; let qai = index\"\n [ngClass]=\"{\n 'mb-20': q.length,\n 'valid-response': questionnaireForm?.controls[question._id]?.valid\n }\"\n >\n <div class=\"sb-h5\">\n {{ qai == 0 ? qi + 1 + \")\" : \"\" }}&nbsp;{{ q }}\n </div>\n </div>\n <div *ngIf=\"question?.hint\">\n <i\n class=\"icon large lightbulb\"\n (click)=\"dimmerIndex = qi; isDimmed = !isDimmed\"\n ></i>\n </div>\n </div>\n <div *ngIf=\"question?.tip\" class=\"mb-10\">\n <small class=\"mb-10\">{{ question?.tip }}</small>\n </div>\n <div class=\"sbt-page-content-questionnaireFormarea'\">\n <sl-text-input\n *ngIf=\"question.responseType == reponseType.TEXT\"\n [questionnaireForm]=\"questionnaireForm\"\n [question]=\"question\"\n ></sl-text-input>\n <sl-date-input\n *ngIf=\"question.responseType == reponseType.DATE\"\n [questionnaireForm]=\"questionnaireForm\"\n [question]=\"question\"\n ></sl-date-input>\n <sl-number-input\n *ngIf=\"question.responseType == reponseType.NUMBER\"\n [questionnaireForm]=\"questionnaireForm\"\n [question]=\"question\"\n ></sl-number-input>\n <sl-range-input\n *ngIf=\"question.responseType == reponseType.SLIDER\"\n [questionnaireForm]=\"questionnaireForm\"\n [question]=\"question\"\n ></sl-range-input>\n <sl-radio-input\n *ngIf=\"question.responseType == reponseType.RADIO\"\n [questionnaireForm]=\"questionnaireForm\"\n [question]=\"question\"\n [options]=\"question.options\"\n (dependentParent)=\"toggleQuestion($event)\"\n ></sl-radio-input>\n <sl-checkbox-input\n *ngIf=\"question.responseType == reponseType.MULTISELECT\"\n [questionnaireForm]=\"questionnaireForm\"\n [question]=\"question\"\n [options]=\"question.options\"\n (dependentParent)=\"toggleQuestion($event)\"\n ></sl-checkbox-input>\n <sl-page-questions\n *ngIf=\"\n question.responseType == reponseType.PAGEQUESTIONS;\n pageQuestions\n \"\n [questionnaireForm]=\"questionnaireForm\"\n [question]=\"question\"\n ></sl-page-questions>\n <sl-matrix-questions\n *ngIf=\"question.responseType == reponseType.MATRIX\"\n [questionnaireForm]=\"questionnaireForm\"\n [question]=\"question\"\n ></sl-matrix-questions>\n <sl-ques-remarks\n [question]=\"question\"\n *ngIf=\"question.showRemarks\"\n ></sl-ques-remarks>\n <sl-attachment\n [data]=\"{\n submissionId: qService.getSubmissionId(),\n files: question.fileName\n }\"\n *ngIf=\"question.file\"\n ></sl-attachment>\n <sui-dimmer\n [(isDimmed)]=\"isDimmed\"\n [isClickable]=\"true\"\n *ngIf=\"dimmerIndex == qi && question?.hint\"\n >\n <div class=\"center\">\n <h4 class=\"ui inverted header\">{{ question?.hint }}</h4>\n <button\n type=\"button\"\n class=\"sb-btn sb-btn-sm sb-btn-white text-uppercase flex-basis-1\"\n type=\"submit\"\n >\n {{ dimmerCloseText }}\n </button>\n </div>\n </sui-dimmer>\n </div>\n </div>\n </div>\n</div>\n", styles: [".question-card{border-radius:28px;padding:20px;width:100%;margin-bottom:20px}.question-card:last-child{margin-bottom:20px}:host .question-card.sb--card,:host .sb-radio-btn-checkbox{width:100%;background-color:var(--sb-card-bg);color:var(--primary-color)}:host label{color:var(--body-color)}:host ::ng-deep .question-card .sb-checkbox label,:host ::ng-deep .question-card .sb-radio-btn-checkbox label{color:var(--body-color);font-weight:400}:host ::ng-deep .question-card input:focus,:host ::ng-deep .question-card input:focus~label{color:var(--body-color)}:host ::ng-deep .question-card #range{background-color:var(--sb-card-bg)}:host ::ng-deep .question-card .student-card{background-color:var(--sb-card-bg)}:host ::ng-deep .question-card .question-date-input,:host ::ng-deep .question-card input:active.question-date-input,:host ::ng-deep .question-card input:focus.question-date-input{background:var(--cc-sbcard-data1-bg);color:var(--sb-prominent-filter-title)}.remarks{margin-top:15px}.valid-response{color:var(--green)}"] }) ], InputComponent); let PageQuestionsComponent = class PageQuestionsComponent { constructor() { } ngOnInit() { } }; __decorate([ Input() ], PageQuestionsComponent.prototype, "questionnaireForm", void 0); __decorate([ Input() ], PageQuestionsComponent.prototype, "question", void 0); PageQuestionsComponent = __decorate([ Component({ selector: 'sl-page-questions', template: "<sl-input\n [questions]=\"question.pageQuestions\"\n [questionnaireForm]=\"questionnaireForm\"\n></sl-input>\n", styles: [""] }) ], PageQuestionsComponent); let MatrixQuestionsComponent = class MatrixQuestionsComponent { constructor(translate, modalService, fb, utils) { this.translate = translate; this.modalService = modalService; this.fb = fb; this.utils = utils; } ngOnInit() { this.addText = this.translate['frmelmnts'].btn.add; this.submitText = this.translate['frmelmnts'].btn.submit; this.cancelText = this.translate['frmelmnts'].btn.cancel; setTimeout(() => { this.matrixForm = this.fb.group({}, Validators.required); this.questionnaireForm.addControl(this.question._id, new FormArray([], [Validators.required])); this.initializeMatrix(); }); } initializeMatrix() { let valid = true; if (this.question.value.length) { this.question.value.map((v) => { let obj = {}; v.forEach((ques) => { if (!ques.value) return; obj[ques._id] = ques.value; }); this.questionnaireForm.controls[this.question._id].push(new FormControl(obj)); if (isEmpty(obj)) { valid = false; } }); } if (!valid) this.questionnaireForm.controls[this.question._id].setErrors({ err: 'Matrix reposne not valid', }); } addInstances() { this.question.value = this.question.value ? this.question.value : []; this.question.value.push(JSON.parse(JSON.stringify(this.question.instanceQuestions))); this.matrixForm.reset(); this.formAsArray.push(new FormControl([], [Validators.required])); } viewInstance(i) { this.matrixForm.reset(); if (this.formAsArray.controls[i].value) { this.matrixForm.patchValue(this.formAsArray.controls[i].value); } const config = new TemplateModalConfig(this.modalTemplate); config.closeResult = 'closed!'; config.context = { questions: this.question.value[i], heading: `${this.question.instanceIdentifier} ${i + 1}`, index: i, }; this.context = config.context; this.showBadgeAssingModel = true; } get formAsArray() { return this.questionnaireForm.controls[this.question._id]; } matrixSubmit(index) { this.showBadgeAssingModel = false; this.formAsArray.at(index).patchValue(this.matrixForm.value); if (this.matrixForm.invalid) { this.formAsArray.at(index).setErrors({ err: 'Matrix reposne not valid' }); } } deleteInstanceAlert(index) { return __awaiter(this, void 0, void 0, function* () { // let metaData = await this.observationUtilService.getAlertMetaData(); // metaData.content.body.data = // this.resourceService.frmelmnts.lbl.deleteSubmission; // metaData.content.body.type =