diff --git a/src/app/system/manage-surveys/edit-survey/edit-survey.component.html b/src/app/system/manage-surveys/edit-survey/edit-survey.component.html new file mode 100644 index 000000000..28b903bdb --- /dev/null +++ b/src/app/system/manage-surveys/edit-survey/edit-survey.component.html @@ -0,0 +1,162 @@ +
+ +
+ +
+ + + + + +
+ + + Key + + + Key is required + + + + + Name + + + Name is required + + + + + Country Code + + + Country Code is required + + + Country Code must consist of 2 alphabetic characters + + + + + Description + + + +
+ +
+ +
+ +
+ + + + + +
+ +
+

Question {{ questionIndex + 1 }}

+ +
+ + + Key + + + Key is required + + + + + Text + + + Text is required + + + + + Description + + + + + +
+

Options

+ +
+ +
+ +
+ +
+ + + Text + + + Text is required + + + + + Value + + + Value is required + + + Value must be an integer between -9999 and 9999 + + + +
+
+ +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ + + + + + + +
+ +
+ +
+ +
+ +
+ +
\ No newline at end of file diff --git a/src/app/system/manage-surveys/edit-survey/edit-survey.component.scss b/src/app/system/manage-surveys/edit-survey/edit-survey.component.scss new file mode 100644 index 000000000..a2d0ee067 --- /dev/null +++ b/src/app/system/manage-surveys/edit-survey/edit-survey.component.scss @@ -0,0 +1,21 @@ +.delete-wrapper { + padding: 17.5px 0 0 0; +} + +h2 { + font-weight: 500; + margin: 0; +} + +h4 { + font-weight: 500; + margin: 0; +} + +.mat-card .mat-divider-horizontal.mat-divider-inset { + margin: 1em 0 2em 0; +} + +.cdk-drag-placeholder { + opacity: 0; +} \ No newline at end of file diff --git a/src/app/system/manage-surveys/edit-survey/edit-survey.component.spec.ts b/src/app/system/manage-surveys/edit-survey/edit-survey.component.spec.ts new file mode 100644 index 000000000..5330e1414 --- /dev/null +++ b/src/app/system/manage-surveys/edit-survey/edit-survey.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EditSurveyComponent } from './edit-survey.component'; + +describe('EditSurveyComponent', () => { + let component: EditSurveyComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ EditSurveyComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(EditSurveyComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/system/manage-surveys/edit-survey/edit-survey.component.ts b/src/app/system/manage-surveys/edit-survey/edit-survey.component.ts new file mode 100644 index 000000000..a738f555a --- /dev/null +++ b/src/app/system/manage-surveys/edit-survey/edit-survey.component.ts @@ -0,0 +1,242 @@ +/** Angular Imports */ +import { Component, OnInit } from '@angular/core'; +import { FormGroup, FormBuilder, FormArray, Validators, FormControl } from '@angular/forms'; +import { Router, ActivatedRoute } from '@angular/router'; +import { MatDialog } from '@angular/material/dialog'; +import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; + +/** Custom Services */ +import { SystemService } from '../../system.service'; + +/** Custom Components */ +import { CancelDialogComponent } from '../../../shared/cancel-dialog/cancel-dialog.component'; + +/** Survey Models */ +import { Survey, QuestionData, ResponseData } from './../survey.model'; + +/** + * Edit survey component. + */ +@Component({ + selector: 'mifosx-edit-survey', + templateUrl: './edit-survey.component.html', + styleUrls: ['./edit-survey.component.scss'] +}) +export class EditSurveyComponent implements OnInit { + + /** Survey form. */ + surveyForm: FormGroup; + + /** + * @param {FormBuilder} formBuilder Form Builder. + * @param {SystemService} systemService System Service. + * @param {ActivatedRoute} route Activated Route. + * @param {Router} router Router for navigation. + * @param {MatDialog} dialog Dialog reference. + */ + constructor(private formBuilder: FormBuilder, + private systemService: SystemService, + private route: ActivatedRoute, + private router: Router, + public dialog: MatDialog) { + this.createSurveyForm(); + this.route.data.subscribe((data: { survey: any }) => { + this.prepareSurveyForm(data.survey); + }); + } + + /** + * Fills the survey form. + */ + ngOnInit() { + } + + /** + * Takes an object of type Survey + * and prepares the survey form. + */ + prepareSurveyForm(survey: Survey) { + this.surveyForm.get('key').setValue(survey.key); + this.surveyForm.get('name').setValue(survey.name); + this.surveyForm.get('countryCode').setValue(survey.countryCode); + this.surveyForm.get('description').setValue(survey.description); + this.prepareQuestionDatas(this.questionDatas, survey.questionDatas); + } + + /** + * Fills all the question forms. + */ + prepareQuestionDatas(questionForms: FormArray, questionDatas: Array) { + questionDatas.forEach((questionData, idx) => { + this.addQuestion(); + const questionForm: FormGroup = questionForms.at(idx); + questionForm.get('key').setValue(questionData.key); + questionForm.get('text').setValue(questionData.text); + questionForm.get('description').setValue(questionData.description); + // questionForm.get('responseDatas').setValue([]); + this.prepareResponseDatas((questionForm.get('responseDatas')), questionData.responseDatas, idx); + }); + } + + /** + * Fills all the response forms. + */ + prepareResponseDatas(responseForms: FormArray, responseDatas: Array, questionIdx: number) { + responseDatas.forEach((responseData, idx) => { + if (idx) { + this.addResponse(questionIdx); + } + + const responseForm = responseForms.at(idx); + responseForm.get('text').setValue(responseData.text); + responseForm.get('value').setValue(responseData.value); + }); + } + + /** + * Creates the survey form. + */ + createSurveyForm() { + this.surveyForm = this.formBuilder.group({ + 'key': ['', Validators.required], + 'name': ['', Validators.required], + 'countryCode': ['', [Validators.required, Validators.pattern('^\\s*([A-Za-z]{2})?\\s*$')]], + 'description': [''], + 'questionDatas': this.formBuilder.array([]) + }); + } + + /** + * Gets the questions form array. + * @returns {FormArray} Questions form array. + */ + get questionDatas(): FormArray { + return this.surveyForm.get('questionDatas') as FormArray; + } + + /** + * Gets the responses form array. + * @param {number} questionIndex Index of question to retrieve responses from. + * @returns {FormArray} Responses form array. + */ + getResponseDatas(questionIndex: number): FormArray { + return this.surveyForm.get(['questionDatas', questionIndex, 'responseDatas']) as FormArray; + } + + /** + * Creates a question form group + * @returns {FormGroup} Question form group. + */ + createQuestionForm(): FormGroup { + return this.formBuilder.group({ + 'key': ['', Validators.required], + 'text': ['', Validators.required], + 'description': [''], + 'responseDatas': this.formBuilder.array([this.createResponseForm()]), + 'sequenceNo': [''] + }); + } + + /** + * Adds a question to the questions form array + */ + addQuestion() { + this.questionDatas.push(this.createQuestionForm()); + this.updateSequenceNumber(); + } + + /** + * Removes the particular question form from the questions form array at given index. + * @param {number} index Array index from where question form needs to be removed. + */ + removeQuestion(index: number) { + this.questionDatas.removeAt(index); + this.updateSequenceNumber(); + } + + /** + * Creates a response form group + * @returns {FormGroup} Response form group. + */ + createResponseForm(): FormGroup { + return this.formBuilder.group({ + 'text': ['', Validators.required], + 'value': ['', [Validators.required, Validators.pattern('^\\s*[-]?\\d{0,4}\\s*$')]], + 'sequenceNo': [''] + }); + } + + /** + * Adds a response to the responses form array of the question with the given Index + * @param {number} questionIndex Index of question to add response to. + */ + addResponse(questionIndex: number) { + this.getResponseDatas(questionIndex).push(this.createResponseForm()); + this.updateSequenceNumber(); + } + + /** + * Removes the particular response form from the given responses form array at given index. + * @param {FormArray} responseFormArray Given responses form array. + * @param {number} index Array index from where response form needs to be removed. + */ + removeResponse(responseFormArray: FormArray, index: number) { + responseFormArray.removeAt(index); + this.updateSequenceNumber(); + } + + /** + * Updates the sequence numbers of questions and responses + */ + updateSequenceNumber() { + for (let questionIndex = 0; questionIndex < this.questionDatas.length; questionIndex++) { + this.questionDatas.at(questionIndex).get('sequenceNo').setValue(questionIndex + 1); + console.log(this.questionDatas); + for (let responseIndex = 0; responseIndex < this.getResponseDatas(questionIndex).length; responseIndex++) { + this.getResponseDatas(questionIndex).at(responseIndex).get('sequenceNo').setValue(responseIndex + 1); + } + } + } + + /** + * Cancels the survey and redirects to surveys. + */ + cancelSurvey() { + const cancelSurveyDialogRef = this.dialog.open(CancelDialogComponent); + cancelSurveyDialogRef.afterClosed().subscribe((response: any) => { + if (response.cancel) { + this.router.navigate(['../'], { relativeTo: this.route }); + } + }); + } + + /** + * Reorders the question order according to the user drop + */ + dropQuestion(event: CdkDragDrop) { + moveItemInArray(this.questionDatas.controls, event.previousIndex, event.currentIndex); + this.updateSequenceNumber(); + } + + /** + * Reorders the response order according to the user drop + */ + dropResponse(event: CdkDragDrop, questionIndex: number) { + moveItemInArray(this.getResponseDatas(questionIndex).controls, event.previousIndex, event.currentIndex); + this.updateSequenceNumber(); + } + + /** + * Submits the survey form and creates survey, + * if successful redirects to surveys. + */ + submit() { + this.surveyForm.patchValue({ + countryCode: this.surveyForm.value.countryCode.toUpperCase() + }); + this.systemService.editSurvey(this.route.snapshot.paramMap.get('id'), this.surveyForm.value).subscribe((response: any) => { + this.router.navigate(['../'], { relativeTo: this.route }); + }); + } + +} diff --git a/src/app/system/manage-surveys/survey.model.ts b/src/app/system/manage-surveys/survey.model.ts new file mode 100644 index 000000000..daba3104d --- /dev/null +++ b/src/app/system/manage-surveys/survey.model.ts @@ -0,0 +1,24 @@ +export class Survey { + id: number; + key: string; + name: string; + countryCode: string; + description: string; + questionDatas: Array; +} + +export class QuestionData { + id: number; + key: string; + sequenceNo: number; + text: string; + description: string; + responseDatas: Array; +} + +export class ResponseData { + id: number; + sequenceNo: number; + text: string; + value: number; +} diff --git a/src/app/system/manage-surveys/view-survey/view-survey.component.html b/src/app/system/manage-surveys/view-survey/view-survey.component.html index 86412e880..961013e2a 100644 --- a/src/app/system/manage-surveys/view-survey/view-survey.component.html +++ b/src/app/system/manage-surveys/view-survey/view-survey.component.html @@ -1,5 +1,5 @@
- diff --git a/src/app/system/manage-surveys/view-survey/view-survey.component.ts b/src/app/system/manage-surveys/view-survey/view-survey.component.ts index e7b779256..2ff942db5 100644 --- a/src/app/system/manage-surveys/view-survey/view-survey.component.ts +++ b/src/app/system/manage-surveys/view-survey/view-survey.component.ts @@ -40,4 +40,9 @@ export class ViewSurveyComponent implements OnInit { ngOnInit(): void { } + + /** Go to edit survey page. */ + onEdit() { + this.router.navigate(['./edit'], { relativeTo: this.route }); + } } diff --git a/src/app/system/system-routing.module.ts b/src/app/system/system-routing.module.ts index 59acdc24e..ff590036b 100644 --- a/src/app/system/system-routing.module.ts +++ b/src/app/system/system-routing.module.ts @@ -25,6 +25,7 @@ import { AddRoleComponent } from './roles-and-permissions/add-role/add-role.comp import { ManageSurveysComponent } from './manage-surveys/manage-surveys.component'; import { CreateSurveyComponent } from './manage-surveys/create-survey/create-survey.component'; import { ViewSurveyComponent } from './manage-surveys/view-survey/view-survey.component'; +import { EditSurveyComponent } from './manage-surveys/edit-survey/edit-survey.component'; import { ManageSchedulerJobsComponent } from './manage-scheduler-jobs/manage-scheduler-jobs.component'; import { AmazonS3Component } from './external-services/amazon-s3/amazon-s3.component'; import { EmailComponent } from './external-services/email/email.component'; @@ -400,6 +401,14 @@ const routes: Routes = [ resolve: { survey: SurveyResolver } + }, + { + path: 'edit', + component: EditSurveyComponent, + data: { title: extract('Edit Survey'), breadcrumb: 'Edit', routeParamBreadcrumb: false }, + resolve: { + survey: SurveyResolver + } } ] } diff --git a/src/app/system/system.module.ts b/src/app/system/system.module.ts index acc8e3c3c..0fd35f842 100644 --- a/src/app/system/system.module.ts +++ b/src/app/system/system.module.ts @@ -59,6 +59,7 @@ import { AddEventDialogComponent } from './manage-hooks/add-event-dialog/add-eve import { ViewSchedulerJobComponent } from './manage-scheduler-jobs/view-scheduler-job/view-scheduler-job.component'; import { EditSchedulerJobComponent } from './manage-scheduler-jobs/edit-scheduler-job/edit-scheduler-job.component'; import { ConfigureMakerCheckerTasksComponent } from './configure-maker-checker-tasks/configure-maker-checker-tasks.component'; +import { EditSurveyComponent } from './manage-surveys/edit-survey/edit-survey.component'; import { BusinessDateTabComponent } from './configurations/business-date-tab/business-date-tab.component'; import { ConfigurationsComponent } from './configurations/configurations.component'; import { GlobalConfigurationsTabComponent } from './configurations/global-configurations-tab/global-configurations-tab.component'; @@ -121,6 +122,7 @@ import { GlobalConfigurationsTabComponent } from './configurations/global-config EditSchedulerJobComponent, ViewHistorySchedulerJobComponent, ViewSurveyComponent, + EditSurveyComponent, BusinessDateTabComponent, ConfigurationsComponent, GlobalConfigurationsTabComponent diff --git a/src/app/system/system.service.ts b/src/app/system/system.service.ts index 5f76ce6d8..dff1f1734 100644 --- a/src/app/system/system.service.ts +++ b/src/app/system/system.service.ts @@ -230,6 +230,15 @@ export class SystemService { return this.http.get(`/surveys/${surveyId}?template=true`); } + /** + * @param {string} surveyId Survey ID. + * @param {any} survey Survey Data. + * @returns {Observable} + */ + editSurvey(surveyId: string, survey: any): Observable { + return this.http.put(`/surveys/${surveyId}`, survey); + } + /** * @returns {Observable} Fetches Jobs. @@ -272,8 +281,8 @@ export class SystemService { } /** - * @param jobId Job Id to be edited - * @returns {Observable} Fetches Scheduler Job. + * @param {string} jobId Job Id on which jobs to run + * @returns {Observable} */ runSelectedJob(jobId: string): Promise { return this.http.post(`/jobs/${jobId}?command=executeJob`, this.emptyPayload).toPromise();