diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d21207a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +FROM nginx:1.13.0-alpine + +# install console and node +RUN apk add --no-cache bash=4.3.46-r5 &&\ + apk add --no-cache libressl-dev qt-dev &&\ + apk add --no-cache nodejs &&\ + apk add --no-cache git + +# install npm ( in separate dir due to docker cache) +ADD package.json /tmp/npm_inst/package.json +RUN cd /tmp/npm_inst &&\ + npm install &&\ + mkdir -p /tmp/app &&\ + mv /tmp/npm_inst/node_modules /tmp/app/ + +# build and publish application +ADD . /tmp/app +RUN cd /tmp/app &&\ + npm run build &&\ + mv ./dist/* /usr/share/nginx/html/ + +# clean +RUN rm -Rf /tmp/npm_inst &&\ + rm -Rf /tmp/app &&\ + rm -Rf /root/.npm &&\ + apk del nodejs + +# this is for virtual host purposes +EXPOSE 80 diff --git a/package.json b/package.json index 6da621e..5b433f7 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "license": "MIT", "scripts": { "ng": "ng", - "start": "npm run updateBuild && ng serve", + "start": "npm run updateBuild && ng serve -H 0.0.0.0", "build": "ng build && npm run updateBuild", "test": "ng test", "lint": "ng lint", @@ -31,9 +31,10 @@ "hammerjs": "^2.0.8", "mkdirp": "^0.5.1", "moment": "2.18.0", + "ng-drag-drop": "^4.0.0", "ng2-ace-editor": "^0.2.3", "ng2-bootstrap-modal": "^1.0.1", - "ng2-openmrs-formentry": "git+https://github.com/enyachoke/ng2-opemmrs-formentry.git#2.4.10", + "ng2-openmrs-formentry": "git+https://github.com/AMPATH/ng2-opemmrs-formentry.git#2.6.0-beta", "ngx-bootstrap": "^1.9.3", "ngx-clipboard": "^8.0.4", "ngx-cookie": "^1.0.0", diff --git a/src/app/Services/fetch-all-forms.service.ts b/src/app/Services/fetch-all-forms.service.ts index 4e27c30..2170c15 100644 --- a/src/app/Services/fetch-all-forms.service.ts +++ b/src/app/Services/fetch-all-forms.service.ts @@ -8,6 +8,8 @@ import { SessionStorageService } from './session-storage.service'; import { FetchFormDetailService } from './fetch-form-detail.service'; import { LocalStorageService } from './local-storage.service'; import { Subject, Observable, BehaviorSubject} from 'rxjs'; +import { FormListService } from './form-list.service'; + @Injectable() export class FetchAllFormsService { @@ -23,7 +25,11 @@ constructor(private http: Http, private ls: LocalStorageService, private router: Router, private auth: AuthenticationService, + private fd: FetchFormDetailService, + private formListService: FormListService) { + private fd: FetchFormDetailService) { + this.allPOCFormsSchemas = new BehaviorSubject(ls.getObject('POC_FORM_SCHEMAS')); auth.getBaseUrl().subscribe((baseUrl) => this.baseUrl = baseUrl); auth.getCredentialsSubject().subscribe((credentials) => { @@ -35,7 +41,8 @@ constructor(private http: Http, fetchAllPOCForms() { - const v = 'custom:(uuid,name,encounterType:(uuid,name),version,published,resources:(uuid,name,dataType,valueReference))'; + + const v = 'custom:(uuid,name,encounterType:(uuid,name),version,published,retired,resources:(uuid,name,dataType,valueReference))'; return this.http.get(`${this.baseUrl}/ws/rest/v1/form?q=POC&v=${v}`, {headers: this.headers}).map( data => this.forms = data.json()) .catch((e) => { @@ -81,6 +88,31 @@ constructor(private http: Http, return this.allPOCFormsSchemas; } + getPOCSameFormsDifferentVersions(formMetadata: any): Observable { + const sameFormsDifferentVersion = []; + return this.fetchAllPOCForms().switchMap((POCForms: any) => { + const forms = _.cloneDeep(POCForms.results); // currently only poc forms version 1 + const formName = this.formListService.removeVersionInformation(formMetadata.name); + const formsWithoutVersionedNames = this.formListService.removeVersionInformationFromForms(forms); + formsWithoutVersionedNames.forEach(($form) => { + if ($form.name === formName) { + sameFormsDifferentVersion.push($form); + } + }); + + return Observable.of(sameFormsDifferentVersion); + }); +} + + +getLatestPublishedVersion(sameFormsDifferentVersion: any[], formUuidToBePublished: any) { + let form: any = {}; + if (!_.isEmpty(sameFormsDifferentVersion)) { + sameFormsDifferentVersion.forEach((_form) => { + if (_form.published && _form.uuid !== formUuidToBePublished) { + form = _form; }}); + return form; +}}} // fetchAllPOCFormsSchemas(metadatas:any){ // let promises:Promise[] = [] // // _.each(metadatas,(metadata:any) => { @@ -110,4 +142,4 @@ constructor(private http: Http, // }); // } -} + diff --git a/src/app/Services/fetch-form-detail.service.ts b/src/app/Services/fetch-form-detail.service.ts index cdfbb15..fa428ec 100644 --- a/src/app/Services/fetch-form-detail.service.ts +++ b/src/app/Services/fetch-form-detail.service.ts @@ -14,22 +14,22 @@ import 'rxjs/add/operator/toPromise'; @Injectable() export class FetchFormDetailService { - private schema: Object = {} - private referencedForms: Array < Object >= [] - private _rawSchema: Object = {} - private referencedFormsSchemasSubject: BehaviorSubject < any[] >= new BehaviorSubject([]) - private referencedFormsDetailsSubject: BehaviorSubject < any[] > = new BehaviorSubject < any[] > ([]) //formName,alias,uuid + private schema: Object = {}; + private referencedForms: Array < Object >= []; + private _rawSchema: Object = {}; + private referencedFormsSchemasSubject: BehaviorSubject < any[] >= new BehaviorSubject([]); + private referencedFormsDetailsSubject: BehaviorSubject < any[] > = new BehaviorSubject < any[] > ([]); // formName,alias,uuid private headers: Headers = new Headers(); - private baseUrl: string = '' + private baseUrl= ''; private formEditorLoaded: BehaviorSubject < boolean > = new BehaviorSubject(false); private credentials: string; - constructor(private http: Http, private fsc: FormSchemaCompiler, private router: Router, private ns: NavigatorService, - private sessionStorageService: SessionStorageService,private auth:AuthenticationService) { + constructor(private http: Http, private fsc: FormSchemaCompiler, private router: Router, private ns: NavigatorService, + private sessionStorageService: SessionStorageService ,private auth: AuthenticationService) { this.credentials = sessionStorageService.getItem(Constants.CREDENTIALS_KEY); auth.getBaseUrl().subscribe((baseUrl) => this.baseUrl = baseUrl); - console.warn(this.baseUrl,"BASE URL"); - this.headers.append("Authorization", "Basic " + this.credentials); + console.warn(this.baseUrl, 'BASE URL'); + this.headers.append('Authorization', 'Basic ' + this.credentials); // this.headers.append( 'Content-Type', 'application/json'); } @@ -37,16 +37,15 @@ export class FetchFormDetailService { public fetchFormMetadata(uuid: string, isComponent: boolean) { return this.http.get(`${this.baseUrl}/ws/rest/v1/form/${uuid}?v=full`, {headers: this.headers}) - .map(metadata => {return metadata.json(); }) + .map(metadata => metadata.json() ) .catch(error => { - console.log("Error:" + error) + console.log('Error:' + error); return error; }) - .toPromise() + .toPromise(); } public fetchForm(valueReference: string, isReferenceForm: boolean) { - let arr; return this.http.get(`${this.baseUrl}/ws/rest/v1/clobdata/${valueReference}`, { headers: this.headers }) @@ -57,18 +56,16 @@ export class FetchFormDetailService { this._rawSchema = res.json(); } - if (res.json().referencedForms&&!isReferenceForm) { + if (res.json().referencedForms && !isReferenceForm) { this.setReferencedFormsDetails(res.json().referencedForms); return this.fetchReferencedFormSchemas(res.json().referencedForms).then(referencedForms => { - console.log("setting ref forms") + console.log('setting ref forms'); this.referencedFormsSchemasSubject = new BehaviorSubject(referencedForms); return this.fsc.compileFormSchema(res.json(), referencedForms); }); - } - - else { + } else { return res.json(); } @@ -82,12 +79,12 @@ export class FetchFormDetailService { - fetchReferencedFormSchemas(referencedForms: any[]):Promise { - let apiCalls = []; + fetchReferencedFormSchemas(referencedForms: any[]): Promise { + const apiCalls = []; referencedForms.forEach(form => { - apiCalls.push(this.fetchFormMetadata(form.ref.uuid, true).then(res => this.fetchForm(res.resources[0].valueReference, true))) + apiCalls.push(this.fetchFormMetadata(form.ref.uuid, true).then(res => this.fetchForm(res.resources[0].valueReference, true))); }); - return Promise.all(apiCalls) + return Promise.all(apiCalls); } get rawSchema() { @@ -95,7 +92,7 @@ export class FetchFormDetailService { } setReferencedFormsSchemasArray(array: any[]) { - this.referencedFormsSchemasSubject.next(array) + this.referencedFormsSchemasSubject.next(array); } @@ -108,9 +105,9 @@ export class FetchFormDetailService { } - setReferencedFormsDetails(formDits) { - //formName,alias,uuid - this.referencedFormsDetailsSubject.next(formDits) + setReferencedFormsDetails(formDits) { + // formName,alias,uuid + this.referencedFormsDetailsSubject.next(formDits); } setLoaded(bool: boolean) { @@ -121,14 +118,13 @@ export class FetchFormDetailService { return this.formEditorLoaded.asObservable(); } - restoreReferencedForms(schema){ + restoreReferencedForms(schema) { if (schema.referencedForms) { this.setReferencedFormsDetails(schema.referencedForms); return this.fetchReferencedFormSchemas(schema.referencedForms).then(referencedForms => { - this.referencedFormsSchemasSubject = new BehaviorSubject(referencedForms) + this.referencedFormsSchemasSubject = new BehaviorSubject(referencedForms); }); - - } + } } } diff --git a/src/app/Services/save-form.service.ts b/src/app/Services/save-form.service.ts index eaa5232..fb66e7b 100644 --- a/src/app/Services/save-form.service.ts +++ b/src/app/Services/save-form.service.ts @@ -125,32 +125,42 @@ export class SaveFormService { /////////////////////////////////////////////////////////////////////// - publish(uuid){ - let body = { published : true }; + publish(uuid) { + const body = { published : true }; return this.http.post(`${this.baseUrl}/ws/rest/v1/form/${uuid}`,body,{headers:this.headers}).map(res => res.json()); } unpublish(uuid){ - let body = { published : false}; + const body = { published : false}; return this.http.post(`${this.baseUrl}/ws/rest/v1/form/${uuid}`,body,{headers:this.headers}).map(res => res.json()); } updateName(name:string,uuid){ - let body = { name : name }; + const body = { name : name }; this.setNewFormName(name); return this.http.post(`${this.baseUrl}/ws/rest/v1/form/${uuid}`,body,{headers:this.headers}).map(res => res.json()); } updateVersion(version:string,uuid){ - let body = { version : version }; + const body = { version : version }; this.setNewVersion(version); return this.http.post(`${this.baseUrl}/ws/rest/v1/form/${uuid}`,body,{headers:this.headers}).map(res => res.json()); } updateDescription(description:string,uuid){ - let body = { description : description }; + const body = { description : description }; this.setNewDescription(description); return this.http.post(`${this.baseUrl}/ws/rest/v1/form/${uuid}`,body,{headers:this.headers}).map(res => res.json()); } + retire(uuid: string) { + // const body = { retired : true, retiredReason : "Retire Reason!" }; + return this.http.delete(`${this.baseUrl}/ws/rest/v1/form/${uuid}?!purge`, {headers: this.headers}).map(res => res.json()); + } + + unretire(uuid: string) { + const body = { retired : false }; + return this.http.post(`${this.baseUrl}/ws/rest/v1/form/${uuid}`, body, {headers: this.headers}).map(res => res.json()); + } + } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 9b90ff1..c37cf23 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -57,8 +57,8 @@ import { UpdateFormsWizardComponent } from './modals/update-forms-wizard-modal/u Str2Num, SetMembersModalComponent, SnackbarComponent, - BuildVersionFooterComponent, - SaveSnackbarComponent, + BuildVersionFooterComponent, + SaveSnackbarComponent, FormBuilderComponent, UpdateFormsWizardComponent, NotificationComponent @@ -83,7 +83,7 @@ import { UpdateFormsWizardComponent } from './modals/update-forms-wizard-modal/u PromptComponent, AnswersComponent, ConceptsModalComponent, - ReferenceModalComponent, + ReferenceModalComponent, NavigatorModalComponent, InsertReferenceComponent, SchemaModalComponent, diff --git a/src/app/form-editor/element-editor/element-editor.component.ts b/src/app/form-editor/element-editor/element-editor.component.ts index a2ba9b9..552e511 100644 --- a/src/app/form-editor/element-editor/element-editor.component.ts +++ b/src/app/form-editor/element-editor/element-editor.component.ts @@ -1,17 +1,17 @@ -import { Component, OnInit, Input,Output, EventEmitter} from '@angular/core'; -import {PropertyModel} from '.././models/property-model'; -import {FormGroup, FormArray, FormControl} from '@angular/forms'; -import {QuestionControlService} from '../../Services/question-control.service'; -import {NavigatorService} from '../../Services/navigator.service'; -import {QuestionIdService} from '../../Services/question-id.service' -import {FormElementFactory} from '.././form-elements/form-element-factory'; -import {AlertComponent} from '../../modals/alert.component' -import { DialogService } from "ng2-bootstrap-modal"; -import {ElementEditorService} from '../../Services/element-editor.service'; -import {Question} from '../form-elements/Question'; -import {SchemaModalComponent} from '../../modals/schema-editor.modal'; -import { ALL_PROPERTIES } from '../models/properties'; -import * as _ from "lodash"; +import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { PropertyModel } from '.././models/property-model'; +import { FormGroup, FormArray, FormControl } from '@angular/forms'; +import { QuestionControlService } from '../../Services/question-control.service'; +import { NavigatorService } from '../../Services/navigator.service'; +import { QuestionIdService } from '../../Services/question-id.service'; +import { FormElementFactory } from '.././form-elements/form-element-factory'; +import { AlertComponent } from '../../modals/alert.component'; +import { DialogService } from 'ng2-bootstrap-modal'; +import { ElementEditorService } from '../../Services/element-editor.service'; +import { Question } from '../form-elements/Question'; +import { SchemaModalComponent } from '../../modals/schema-editor.modal'; +import { ALL_PROPERTIES } from '../models/properties'; import * as _ from 'lodash'; + @Component({ selector: 'app-element-editor', @@ -19,352 +19,353 @@ import * as _ from "lodash"; styleUrls: ['./element-editor.component.css'] }) export class ElementEditorComponent implements OnInit { - questions:PropertyModel[]; + questions: PropertyModel < any > []; _rawSchema: any; - _schema:any; - _questionSchema:any; + _schema: any; + _questionSchema: any; form: FormGroup; - setMembers:any[] = []; + setMembers: any[] = []; @Input() pageIndex: number; @Input() sectionIndex: number; - @Input() questionIndex:number; //if editMode or addMode obsGroup Question - @Input() parentQuestionIndex:number; - @Input() set rawSchema(rawSchema){this._rawSchema=_.cloneDeep(rawSchema)}; //if edit obsGroup question - @Output() closeComponent:EventEmitter=new EventEmitter(); - + @Input() questionIndex: number; // if editMode or addMode obsGroup Question + @Input() parentQuestionIndex: number; + @Input() set rawSchema(rawSchema) { + this._rawSchema = _.cloneDeep(rawSchema); + } // if edit obsGroup question + @Output() closeComponent: EventEmitter < boolean >= new EventEmitter(); + pageStr: string; sectionStr: string; questionStr: string; - allPossibleproperties:Array; - addMode:boolean = false; - editMode:boolean = false; - id:number; //ID to the current edited question + allPossibleproperties: Array < any > ; + addMode = false; + editMode = false; + id: number; // ID to the current edited question + answers: Object; - answers:Object; + constructor(private qcs: QuestionControlService, + private formElementFactory: FormElementFactory, + private qis: QuestionIdService, + private ns: NavigatorService, + private dialogService: DialogService, + private el: ElementEditorService) {} - constructor(private qcs: QuestionControlService, private formElementFactory:FormElementFactory, - private qis:QuestionIdService,private ns:NavigatorService,private dialogService:DialogService, private el:ElementEditorService) { - - - } - - - @Input() set schema(schema){ + @Input() set schema(schema) { this._schema = _.clone(schema); } - - @Input() set _questions(questions){ + + @Input() set _questions(questions) { console.log(questions); - this.questions = questions + this.questions = questions; this.form = this.qcs.toFormGroup(this.questions); - this.setMode(this.form) + this.setMode(this.form); this.breadcrumbsSetup(); - + } - @Input() set questionSchema(schema:any){ + @Input() set questionSchema(schema: any) { this._questionSchema = schema; - if(this._questionSchema) - if(this._questionSchema.questions) this.setMembers = this._questionSchema.questions; + if (this._questionSchema) { + if (this._questionSchema.questions) { + this.setMembers = this._questionSchema.questions; + } + } } ngOnInit() { console.log(this.qis.getIDs(this._schema)); - this.form = this.qcs.toFormGroup(this.questions); - this.setMode(this.form); - this.allPossibleproperties = ALL_PROPERTIES; - this.breadcrumbsSetup(); - this.el.getSetMembers().subscribe((setMembers) => { - this.setMembers=[]; - setMembers.forEach((setMember) =>{ - let rendering="text"; - if(setMember.answers.length>0) {rendering="select"} - let question:Question = { - label: setMember.label, - type:'obs', - id:'', - questionOptions:{ - rendering:rendering, - } - - } - question.questionOptions['concept']=setMember.concept; - if(!_.isEmpty(setMember.answers)) question.questionOptions['answers']=setMember.answers; - this.form.controls['type'].setValue('obsGroup'); - this.form.controls['questionOptions.rendering'].setValue('group'); - this.setMembers.push(question); - }); - + this.form = this.qcs.toFormGroup(this.questions); + this.setMode(this.form); + this.allPossibleproperties = ALL_PROPERTIES; + this.breadcrumbsSetup(); + this.el.getSetMembers().subscribe((setMembers) => { + console.log(setMembers); + this.setMembers = []; + setMembers.forEach((setMember) => { + let rendering = 'text'; + if (setMember.answers.length > 0) { + rendering = 'select'; + } + let question: Question = new Question(); + console.log(question); + question.label = setMember.label; + question.type = 'obs'; + question.id = '', + question.questionOptions.rendering = rendering; + + question.questionOptions['concept'] = setMember.concept; + if (!_.isEmpty(setMember.answers)) { + question.questionOptions['answers'] = setMember.answers; + } + this.form.controls['type'].setValue('obsGroup'); + this.form.controls['questionOptions.rendering'].setValue('group'); + this.setMembers.push(question); }); + + }); } - addProperty(prop){ - - if(this.form.contains(prop)) {this.showAlert("Property already added!"); return;} - - let obj = {}; - obj[prop] = ""; - let newField = this.qcs.toPropertyModelArray(obj); //TODO: do not depend on qcs to create new property model. fix this! prop is already a propertymodel. + addProperty(prop) { + if (this.form.contains(prop)) { + this.showAlert('Property already added!'); + return; + } + + const obj = {}; + obj[prop] = ''; + const newField = this.qcs.toPropertyModelArray(obj); + // TODO: do not depend on qcs to create new property model. fix this! prop is already a propertymodel. - if(newField.length > 0){ - this.form.addControl(prop,new FormControl("")) - this.questions.push(newField[0]) + if (newField.length > 0) { + this.form.addControl(prop, new FormControl('')); + this.questions.push(newField[0]); } } - - onSubmit(){ - if(!this.form.contains('label')||!this.form.contains('questionOptions.rendering')||!this.form.contains('type')) - { this.showAlert("Some mandatory question properties are missing! \n A question must include: type,label,redering and id") } - if(this.form.contains('id')){ - if(!this.checkId(this.form.get('id').value)) return; + onSubmit() { + if (!this.form.contains('label') || !this.form.contains('questionOptions.rendering') || !this.form.contains('type')) { + this.showAlert('Some mandatory question properties are missing! \n A question must include: type,label,redering and id'); + } + + if (this.form.contains('id')) { + if (!this.checkId(this.form.get('id').value)) { + return; + } } - - let question = this.qcs.unflatten(this.form.value); + const question = this.qcs.unflatten(this.form.value); - if(question['type']=="obsGroup"){ - question['questions']=this.setMembers; + if (question['type'] === 'obsGroup') { + question['questions'] = this.setMembers; } - if(question['validators']){ - question['validators']=this.parse(this.form.controls['validators'].value); + if (question['validators']) { + question['validators'] = this.parse(this.form.controls['validators'].value); } - if(question['alert']){ - question['alert']=this.parse(this.form.controls['alert'].value); + if (question['alert']) { + question['alert'] = this.parse(this.form.controls['alert'].value); } - if(question['hide']){ - question['hide']=this.parse(this.form.controls['hide'].value); + if (question['hide']) { + question['hide'] = this.parse(this.form.controls['hide'].value); } - if(question.questionOptions['answers']){ - question.questionOptions['answers']=this.parse(this.form.controls['questionOptions.answers'].value); + if (question.questionOptions['answers']) { + question.questionOptions['answers'] = this.parse(this.form.controls['questionOptions.answers'].value); } // if(question.questionOptions['answers']&&question['type']=="testOrder"){ // question.questionOptions['selectableOrders'] = _.cloneDeep(question.questionOptions['answers']); // delete question.questionOptions['answers']; // } - console.log(question) + console.log(question); - if(this.addMode){ - this.addQuestion(question,this.pageIndex,this.sectionIndex,this.questionIndex) + if (this.addMode) { + this.addQuestion(question, this.pageIndex, this.sectionIndex, this.questionIndex); } - if(this.editMode){ - this.editQuestion(question,this.pageIndex,this.sectionIndex,this.questionIndex,this.parentQuestionIndex) + if (this.editMode) { + this.editQuestion(question, this.pageIndex, this.sectionIndex, this.questionIndex, this.parentQuestionIndex); } - - - } - breadcrumbsSetup(){ + breadcrumbsSetup() { this.pageStr = this._schema.pages[this.pageIndex].label; this.sectionStr = this._schema.pages[this.pageIndex].sections[this.sectionIndex].label; - if(this.editMode&&this.questionIndex!=-1) this.questionStr = this._schema.pages[this.pageIndex].sections[this.sectionIndex].questions[this.questionIndex].label - else this.questionStr = ''; - } + if (this.editMode && this.questionIndex !== -1) { + this.questionStr = this._schema.pages[this.pageIndex].sections[this.sectionIndex].questions[this.questionIndex].label; + } else { + this.questionStr = ''; + } + } - parse(str){ + parse(str) { return JSON.parse(str); } - delete(i){ - this.form.removeControl(this.questions[i].key) - this.questions.splice(i,1); + delete(i) { + this.form.removeControl(this.questions[i].key); + this.questions.splice(i, 1); console.log(this.questions); } - setMode(form:FormGroup){ - if(this.form.get('label').value=="") { - console.log("addMode"); - this.editMode=false; - this.addMode=true; - } - else { - this.editMode=true; - this.addMode=false; - this.id=this.form.get('id').value - console.log("editMode") + setMode(form: FormGroup) { + if (this.form.get('label').value === '') { + console.log('addMode'); + this.editMode = false; + this.addMode = true; + } else { + this.editMode = true; + this.addMode = false; + this.id = this.form.get('id').value; + console.log('editMode'); } } - checkId(id):boolean{ - if(this.form.contains('id')){ - let _id = this.form.get('id').value; - let ids = this.qis.getIDs(this._rawSchema); + checkId(id): boolean { + if (this.form.contains('id')) { + const _id = this.form.get('id').value; + const ids = this.qis.getIDs(this._rawSchema); let count = 0; - for(var id of ids) if(id==_id) count++; - if(this.editMode&&this.id!==_id&&count>0) { - this.showAlert("ID exists \n Try using a different ID"); - return false;} - else if(this.addMode&&count>0){ - this.showAlert("ID exists \n Try using a different ID"); - return false;} - else {return true;} + for (let $id of ids) { + if ($id === _id) { count++; } + } + if (this.editMode && this.id !== _id && count > 0) { + this.showAlert('ID exists \n Try using a different ID'); + return false; + } else if (this.addMode && count > 0) { + this.showAlert('ID exists \n Try using a different ID'); + return false; + } else { + return true; + } } } - showAlert(message:string){ - this.dialogService.addDialog(AlertComponent, {message:message}); + showAlert(message: string) { + this.dialogService.addDialog(AlertComponent, { + message: message + }); } - setAnswers(answers){ - console.log(answers,"Element Editor!"); - this.answers = answers; //selectedAnswers - if(answers.length>0){ - if(this.form.contains('questionOptions.answers')){ - this.form.controls['questionOptions.answers'].setValue(JSON.stringify(answers,undefined,"\t")); - } - else{ - let field = this.qcs.toPropertyModelArray({"questionOptions.answers":answers}) - this.form.addControl('questionOptions.answers',new FormControl(JSON.stringify(answers,undefined,"\t"))) - this.questions.push(field[0]) + setAnswers(answers) { + console.log(answers, 'Element Editor!'); + this.answers = answers; // selectedAnswers + if (answers.length > 0) { + if (this.form.contains('questionOptions.answers')) { + this.form.controls['questionOptions.answers'].setValue(JSON.stringify(answers, undefined, '\t')); + } else { + const field = this.qcs.toPropertyModelArray({ + 'questionOptions.answers': answers + }); + this.form.addControl('questionOptions.answers', new FormControl(JSON.stringify(answers, undefined, '\t'))); + this.questions.push(field[0]); } - } - - else{ - if(this.form.controls['questionOptions.answers']){ + } else { + if (this.form.controls['questionOptions.answers']) { this.form.removeControl('questionOptions.answers'); this.removeQuestion('questionOptions.answers'); - } - else{ + } else { return; } - + } - - + + } - addQuestion(question:any,pageIndex:number,sectionIndex:number,questionIndex?:number){ + addQuestion(question: any, pageIndex: number, sectionIndex: number, questionIndex ?: number) { - if(questionIndex!==undefined){ //obsGroup question + if (questionIndex !== undefined) { // obsGroup question console.log('has parent!'); - if(this._rawSchema.pages[pageIndex].label ){ - if(this._rawSchema.pages[pageIndex].sections[sectionIndex].label ){ + if (this._rawSchema.pages[pageIndex].label) { + if (this._rawSchema.pages[pageIndex].sections[sectionIndex].label) { this._schema.pages[pageIndex].sections[sectionIndex].questions[questionIndex].questions.push(question); this._rawSchema.pages[pageIndex].sections[sectionIndex].questions[questionIndex].questions.push(question); - } - else{ - this.showAlert("You cannot add a question to a referenced section."); + } else { + this.showAlert('You cannot add a question to a referenced section.'); return; } - - } - else{ - this.showAlert("You cannot add a question to a referenced page."); + + } else { + this.showAlert('You cannot add a question to a referenced page.'); return; } - - } - else{ + } else { + - - if(this._rawSchema.pages[pageIndex].label){ - if(this._rawSchema.pages[pageIndex].sections[sectionIndex].label ){ + if (this._rawSchema.pages[pageIndex].label) { + if (this._rawSchema.pages[pageIndex].sections[sectionIndex].label) { this._rawSchema.pages[pageIndex].sections[sectionIndex].questions.push(question); this._schema.pages[pageIndex].sections[sectionIndex].questions.push(question); - } - else{ - this.showAlert("You cannot add a question to a referenced section."); + } else { + this.showAlert('You cannot add a question to a referenced section.'); return; } - } - - else{ - this.showAlert("You cannot add a question to a referenced page."); + } else { + this.showAlert('You cannot add a question to a referenced page.'); return; } - + } this.ns.setSchema(this._schema); - this.ns.setRawSchema(this._rawSchema) + this.ns.setRawSchema(this._rawSchema); this.form.reset(); this.closeElementEditor(); } - editQuestion(question,pageIndex,sectionIndex,questionIndex,parentQuestionIndex?){ - - if(parentQuestionIndex!==undefined){ + editQuestion(question, pageIndex, sectionIndex, questionIndex, parentQuestionIndex ? ) { - if(this._rawSchema.pages[pageIndex].label){ - if(this._rawSchema.pages[pageIndex].sections[sectionIndex].label ){ - this._schema.pages[pageIndex].sections[sectionIndex].questions[parentQuestionIndex].questions.splice(questionIndex,1,question); - this._rawSchema.pages[pageIndex].sections[sectionIndex].questions[parentQuestionIndex].questions.splice(questionIndex,1,question); - } - else{ - this.showAlert("You cannot edit a question of a referenced section"); + if (parentQuestionIndex !== undefined) { + + if (this._rawSchema.pages[pageIndex].label) { + if (this._rawSchema.pages[pageIndex].sections[sectionIndex].label) { + this._schema.pages[pageIndex].sections[sectionIndex].questions[parentQuestionIndex].questions.splice(questionIndex, 1, question); + this._rawSchema.pages[pageIndex].sections[sectionIndex].questions[parentQuestionIndex] + .questions.splice(questionIndex, 1, question); + } else { + this.showAlert('You cannot edit a question of a referenced section'); return; } - } - - - else{ - this.showAlert("You cannot edit a question of a referenced page"); + } else { + this.showAlert('You cannot edit a question of a referenced page'); return; } - - } - else{ - console.log(questionIndex) - - if(this._rawSchema.pages[pageIndex].label ){ - if(this._rawSchema.pages[pageIndex].sections[sectionIndex].label){ - this._schema.pages[pageIndex].sections[sectionIndex].questions.splice(questionIndex,1,question); - this._rawSchema.pages[pageIndex].sections[sectionIndex].questions.splice(questionIndex,1,question); - } - else{ - this.showAlert("You cannot edit a question of a referenced section."); - return; - } - - } - - else{ - this.showAlert("You cannot edit a question of a referenced page."); + + } else { + console.log(questionIndex); + + if (this._rawSchema.pages[pageIndex].label) { + if (this._rawSchema.pages[pageIndex].sections[sectionIndex].label) { + this._schema.pages[pageIndex].sections[sectionIndex].questions.splice(questionIndex, 1, question); + this._rawSchema.pages[pageIndex].sections[sectionIndex].questions.splice(questionIndex, 1, question); + } else { + this.showAlert('You cannot edit a question of a referenced section.'); + return; + } + + } else { + this.showAlert('You cannot edit a question of a referenced page.'); return; } - + } this.ns.setSchema(this._schema); - this.ns.setRawSchema(this._rawSchema) + this.ns.setRawSchema(this._rawSchema); } - - checkQuestion(question){ - if(question.key=='label' || question.key=='type' || question.key=='questionOptions.rendering'){ + + checkQuestion(question) { + if (question.key === 'label' || question.key === 'type' || question.key === 'questionOptions.rendering') { return false; } return true; } - typeSelected(type:string){ - if(type=='obs'){ - if(!this.form.contains('questionOptions.concept')) this.addProperty('questionOptions.concept'); + typeSelected(type: string) { + if (type === 'obs') { + if (!this.form.contains('questionOptions.concept')) { this.addProperty('questionOptions.concept'); } } } - renderingSelected(rendering:string){ - switch(rendering){ + renderingSelected(rendering: string) { + switch (rendering) { case 'number': this.removePreviousFields(rendering); - if(!this.form.contains('questionOptions.max')&&!this.form.contains('questionOptions.min')){ + if (!this.form.contains('questionOptions.max') && !this.form.contains('questionOptions.min')) { this.addProperty('questionOptions.max'); this.addProperty('questionOptions.min'); this.addProperty('questionOptions.showDate'); @@ -373,54 +374,58 @@ export class ElementEditorComponent implements OnInit { case 'textarea': this.removePreviousFields(rendering); - if(!this.form.contains('questionOptions.rows')){ + if (!this.form.contains('questionOptions.rows')) { this.addProperty('questionOptions.rows'); - } + } break; - + case 'date': - this.removePreviousFields(rendering); - if(!this.form.contains('questionOptions.showWeeks')){ + this.removePreviousFields(rendering); + if (!this.form.contains('questionOptions.showWeeks')) { this.addProperty('questionOptions.showWeeks'); - } + } break; default: - this.removePreviousFields(rendering); - + this.removePreviousFields(rendering); + } } - reselectAnswers(){ - if(this.answers!=undefined) this.el.reShowAnswersDialog(this.answers); - else this.el.reShowAnswersDialog(JSON.parse(this.form.controls['questionOptions.answers'].value)); + reselectAnswers() { + if (this.answers !== undefined) { this.el.reShowAnswersDialog(this.answers); } else { + this.el.reShowAnswersDialog(JSON.parse(this.form.controls['questionOptions.answers'].value)); + } } - closeElementEditor(){ + closeElementEditor() { this.closeComponent.emit(true); } - viewSetMembers(){ - this.dialogService.addDialog(SchemaModalComponent,{schema:JSON.stringify(this.setMembers,null,4),title:"Set Members Schema"}); + viewSetMembers() { + this.dialogService.addDialog(SchemaModalComponent, { + schema: JSON.stringify(this.setMembers, null, 4), + title: 'Set Members Schema' + }); } - reselectSetMembers(){ + reselectSetMembers() { this.el.reShowSetMembersDialog(this.setMembers); } - removePreviousFields(rendering:string){ - switch(rendering){ + removePreviousFields(rendering: string) { + switch (rendering) { case 'number': - this.removeDateRelatedFields(); - this.removeTextAreaRelatedFields(); - break; + this.removeDateRelatedFields(); + this.removeTextAreaRelatedFields(); + break; case 'textarea': - this.removeNumberRelatedFields(); - this.removeDateRelatedFields(); - break; - - + this.removeNumberRelatedFields(); + this.removeDateRelatedFields(); + break; + + case 'date': this.removeNumberRelatedFields(); this.removeTextAreaRelatedFields(); @@ -436,54 +441,55 @@ export class ElementEditorComponent implements OnInit { } } - removeQuestion(qn){ - let i; - this.questions.forEach((question,index) => { - if(question['key']==qn) - i=index; - }) - this.questions.splice(i,1) - + removeQuestion(qn) { + let i; + this.questions.forEach((question, index) => { + if (question['key'] === qn) { + i = index; + } + }); + this.questions.splice(i, 1); + } - showDate($event){ - if($event==true){ - if(!this.form.contains('questionOptions.showDateOptions')) this.addProperty('questionOptions.showDateOptions'); - } - else{ + showDate($event) { + if ($event === true) { + if (!this.form.contains('questionOptions.showDateOptions')) { + this.addProperty('questionOptions.showDateOptions'); + } + } else { this.form.removeControl('questionOptions.showDate'); this.removeQuestion('questionOptions.showDate'); } } - removeTextAreaRelatedFields(){ - if(this.form.contains("questionOptions.rows")) { + removeTextAreaRelatedFields() { + if (this.form.contains('questionOptions.rows')) { this.form.removeControl('questionOptions.rows'); this.removeQuestion('questionOptions.rows'); - } + } } - removeNumberRelatedFields(){ - if(this.form.contains('questionOptions.max')){ + removeNumberRelatedFields() { + if (this.form.contains('questionOptions.max')) { this.removeQuestion('questionOptions.max'); this.form.removeControl('questionOptions.max'); - } - if(this.form.contains('questionOptions.min')) { + } + if (this.form.contains('questionOptions.min')) { this.form.removeControl('questionOptions.min'); this.removeQuestion('questionOptions.min'); - } + } - if(this.form.contains('questionOptions.showDate')){ + if (this.form.contains('questionOptions.showDate')) { this.form.removeControl('questionOptions.showDate'); this.removeQuestion('questionOptions.showDate'); } } - removeDateRelatedFields(){ - if(this.form.contains("questionOptions.showWeeks")) { + removeDateRelatedFields() { + if (this.form.contains('questionOptions.showWeeks')) { this.form.removeControl('questionOptions.showWeeks'); this.removeQuestion('questionOptions.showWeeks'); - } + } } } - \ No newline at end of file diff --git a/src/app/form-editor/form-editor/form-editor.component.ts b/src/app/form-editor/form-editor/form-editor.component.ts index 045c2c6..74a4f3d 100644 --- a/src/app/form-editor/form-editor/form-editor.component.ts +++ b/src/app/form-editor/form-editor/form-editor.component.ts @@ -1,80 +1,27 @@ -import { - Component, - OnInit, - ViewChild, - OnDestroy, - ChangeDetectorRef, - AfterViewChecked -} from '@angular/core'; -import { - SnackbarComponent -} from '../snackbar/snackbar.component'; -import { - FetchFormDetailService -} from '../../Services/fetch-form-detail.service'; -import { - FetchAllFormsService -} from '../../Services/fetch-all-forms.service'; -import { - NavigatorService -} from '../../Services/navigator.service'; -import { - QuestionIdService -} from '../../Services/question-id.service'; -import { - ActivatedRoute, - Router, - ParamMap -} from '@angular/router'; -import { - Subscription -} from 'rxjs/Subscription'; -import { - Observable -} from 'rxjs/Observable'; -import { - MdSnackBar -} from '@angular/material'; -import { - DialogService -} from 'ng2-bootstrap-modal'; -import { - Form -} from '../form-elements/Form'; -import { - LocalStorageService -} from '../../Services/local-storage.service'; -import { - SessionStorageService -} from '../../Services/session-storage.service'; -import { - Constants -} from '../../Services/constants'; -import { - SaveFormsComponent -} from '../../modals/save-form-modal/save-form-modal'; -import { - ConfirmComponent -} from '../../modals/confirm.component'; -import { - AlertComponent -} from '../../modals/alert.component'; -import { - FormListService -} from '../../Services/form-list.service'; -import { - SaveFormService -} from '../../Services/save-form.service'; -import { - EncounterTypeService -} from '../../Services/encounter-type.service'; -import { - ConceptService -} from '../../Services/concept.service'; -import { - NotificationComponent -} from '../snackbar/notification-toast'; -import * as _ from 'lodash'; +import { Component, OnInit, ViewChild, OnDestroy, ChangeDetectorRef, AfterViewChecked, AfterContentInit } from '@angular/core'; +import { SnackbarComponent } from '../snackbar/snackbar.component'; +import { FetchFormDetailService } from '../../Services/fetch-form-detail.service'; +import { FetchAllFormsService } from '../../Services/fetch-all-forms.service'; +import { NavigatorService } from '../../Services/navigator.service'; +import { QuestionIdService } from '../../Services/question-id.service'; +import { ActivatedRoute, Router, ParamMap } from '@angular/router'; +import { Subscription } from 'rxjs/Subscription'; import { Observable } from 'rxjs/Observable'; +import { MdSnackBar } from '@angular/material'; +import { DialogService } from 'ng2-bootstrap-modal'; +import { Form } from '../form-elements/Form'; +import { LocalStorageService } from '../../Services/local-storage.service'; +import { SessionStorageService } from '../../Services/session-storage.service'; +import { Constants } from '../../Services/constants'; +import { SaveFormsComponent } from '../../modals/save-form-modal/save-form-modal'; +import { ConfirmComponent } from '../../modals/confirm.component'; +import { AlertComponent } from '../../modals/alert.component'; +import { FormListService } from '../../Services/form-list.service'; +import { SaveFormService } from '../../Services/save-form.service'; +import { EncounterTypeService } from '../../Services/encounter-type.service'; +import { ConceptService } from '../../Services/concept.service'; +import { NotificationComponent } from '../snackbar/notification-toast'; import * as _ from 'lodash'; +import { Question, QuestionOptions } from '../form-elements/Question'; + interface FormMetadata { @@ -96,7 +43,9 @@ interface FormMetadata { styleUrls: ['./form-editor.component.css'] }) -export class FormEditorComponent implements OnInit, OnDestroy, AfterViewChecked { + +export class FormEditorComponent implements OnInit, OnDestroy, AfterViewChecked, AfterContentInit { + schema: any; selectedSchema: any; rawSelectedSchema: any; @@ -135,7 +84,10 @@ export class FormEditorComponent implements OnInit, OnDestroy, AfterViewChecked private saveFormService: SaveFormService, private encounterTypeService: EncounterTypeService, private sessionStorageService: SessionStorageService, - private conceptService: ConceptService) {} + + private conceptService: ConceptService) { + this.loading = true; + } closeElementEditor() { this.questions = undefined; @@ -147,15 +99,16 @@ export class FormEditorComponent implements OnInit, OnDestroy, AfterViewChecked openNavigator() { this.myNav.open(); - } ngAfterViewChecked() { this.cdRef.detectChanges(); } + ngAfterContentInit() { + this.loading = true; + } ngOnInit() { - this.loading = true; this.viewMode = 'singleView'; // default view mode this.user = this.sessionStorageService.getObject('user').username; this.url = this.sessionStorageService.getItem('url'); @@ -435,6 +388,37 @@ export class FormEditorComponent implements OnInit, OnDestroy, AfterViewChecked this.saveFormMetadata(this.formMetadata); if (!silently) { this.showSaveSnackbar(); } +git + showSuccessToast(message: string) { + this.snackbar.openFromComponent(SnackbarComponent, { + duration: 1500, + data: message + }); + } + showNotificationMessage(message: string) { + this.snackbar.open(message, '', { + duration: 1200 + }); + + } + setFormEditor(schema, rawSchema, formMetadata ? ) { + console.log(schema, 'SCHEMA'); + this.selectedSchema = schema; + this.schema = schema; + this.strSchema = JSON.stringify(schema, null, '\t'); + this.rawSchema = rawSchema; + this.ns.setRawSchema(this.rawSchema); + this.strRawSchema = JSON.stringify(this.rawSchema, null, '\t'); + if (formMetadata) { this.formMetadata = formMetadata; } // if form is being restored from local storage, retrieve metadata. + } + + saveLocally(silently ?: boolean) { + + this.saveDraft(this.schema); + this.saveRawDraft(this.rawSchema); + this.saveFormMetadata(this.formMetadata); + if (!silently) { this.showSaveSnackbar(); } + } saveRemotely() { @@ -527,6 +511,7 @@ export class FormEditorComponent implements OnInit, OnDestroy, AfterViewChecked }); } + saveDraft(schema: any) { this.ls.setObject(Constants.SCHEMA, schema); @@ -546,63 +531,30 @@ export class FormEditorComponent implements OnInit, OnDestroy, AfterViewChecked this.ls.setObject(Constants.FORM_METADATA, formMetadata); } - publish(form, index) { - let forms = []; - const sameFormsDifferentVersion = []; - this.subscription = this.fectAllFormsService.fetchAllPOCForms().subscribe((POCForms: any) => { - forms = _.cloneDeep(POCForms.results); // currently only poc forms version 1 - const formName = this.formListService.removeVersionInformation(this.formMetadata.name); - forms.splice(index, 1); - const formsWithoutVersionedNames = this.formListService.removeVersionInformationFromForms(forms); - - - formsWithoutVersionedNames.forEach(($form) => { - if ($form.name === formName) { - sameFormsDifferentVersion.push($form); - } - }); - - if (!_.isEmpty(sameFormsDifferentVersion)) { - sameFormsDifferentVersion.forEach((_form) => { - if (_form.published) { - POCForms.results.forEach((pocform) => { - if (pocform.uuid === _form.uuid) { - this.dialogService.addDialog(ConfirmComponent, { - title: 'Confirm publish', - message: 'There is already a version of this form published.' + - 'Would you like to unpublish that version and publish this one?', - buttonText: 'Publish' - }, { - backdropColor: 'rgba(0,0,0,0.5)' - }) - .subscribe((isConfirmed) => { - if (isConfirmed) { - this.saveFormService.unpublish(pocform.uuid) - .subscribe((res) => this.saveFormService.publish(this.formMetadata.uuid).subscribe( (ress) => { - this.showSuccessToast('Form Successfully Published!'); - this.formMetadata.published = true; - })); - } - }); - } - }); - } else { - this.showSuccessToast('Form Successfully Published!'); - this.saveFormService.publish(this.formMetadata.uuid) - .subscribe(res => this.formMetadata.published = true); // if none of the other versions are published. - } - }); - } else { - this.saveFormService.publish(this.formMetadata.uuid).subscribe(res => { - this.showSuccessToast('Form Successfully Published!'); - this.formMetadata.published = true; - }); - } + publish() { - - }); - } + this.subscription = this.fectAllFormsService.getPOCSameFormsDifferentVersions(this.formMetadata) + .subscribe((forms) => { console.log(forms); + const publishedForm = this.fectAllFormsService.getLatestPublishedVersion(forms, this.formMetadata.uuid); + if (!_.isEmpty(publishedForm)) { + this.dialogService.addDialog(ConfirmComponent, { + title: 'Confirm publish', + message: `Version ${publishedForm.version} of this form published. + Would you like to unpublish that version and publish this one?`, + buttonText: 'Publish' + }, { backdropColor: 'rgba(0,0,0,0.5)'}) + .subscribe((isConfirmed) => { + if (isConfirmed) { + this.saveFormService.unpublish(publishedForm.uuid) + .subscribe((res) => this.saveFormService.publish(this.formMetadata.uuid).subscribe( (ress) => { + this.showSuccessToast('Form Successfully Published!'); + this.formMetadata.published = true; + })); + }}); + }}); } + + unpublish() { this.saveFormService.unpublish(this.formMetadata.uuid).subscribe((res) => this.formMetadata.published = false); @@ -624,21 +576,24 @@ export class FormEditorComponent implements OnInit, OnDestroy, AfterViewChecked data: ' Validating Concepts...' }); this.conceptService.validateConcepts(concepts).subscribe((res: any[]) => { + + const undefinedConcepts = res.filter((x) => x !== undefined); + console.log(undefinedConcepts); if (undefinedConcepts.length > 0) { - let undefined_concepts = '\n'; + let undefined_concepts = '\n \n'; _.each(undefinedConcepts, (concept) => { - undefined_concepts = undefined_concepts + '\n' + concept; - }); + undefined_concepts = undefined_concepts + '\n \n' + concept; }); this.dialogService.addDialog(AlertComponent, { - message: `The following concepts are invalid: ${concepts}` + message: `The following concepts are invalid: ${undefined_concepts}` + }); this.snackbar.dismiss(); } else { this.showSuccessToast('All Concept are valid'); - } - }); + }}); + } fetchAllConcepts() { @@ -646,18 +601,30 @@ export class FormEditorComponent implements OnInit, OnDestroy, AfterViewChecked const pages = this.schema.pages; _.each(pages, (page: any) => { _.each(page.sections, (section: any) => { - _.each((section.questions), (question: any) => { + + _.each((section.questions), (question: Question) => { if (question.questionOptions.concept) { concepts.push(question.questionOptions.concept); } + if (question.questionOptions.answers) { + _.each(question.questionOptions.answers, (answer) => { + if (concepts.indexOf(answer.concept) === -1) { concepts.push(answer.concept); }}); + } if (question.questions) { _.each(question.questions, (nestedQuestion: any) => { if (nestedQuestion.questionOptions.concept) { - concepts.push(nestedQuestion.questionOptions.concept); + if (concepts.indexOf(nestedQuestion.questionOptions.concept) === -1) { + concepts.push(nestedQuestion.questionOptions.concept); } } - }); - } - }); + if (nestedQuestion.questionOptions.answers) { + _.each(question.questionOptions.answers, (answer) => { + if (concepts.indexOf(nestedQuestion.questionOptions.answer.concept) === -1) { + concepts.push(answer.concept); + } + }); + }}); + }}); + }); }); return concepts; diff --git a/src/app/form-editor/form-editor/form-editor.module.ts b/src/app/form-editor/form-editor/form-editor.module.ts index b457e9a..60cd21b 100644 --- a/src/app/form-editor/form-editor/form-editor.module.ts +++ b/src/app/form-editor/form-editor/form-editor.module.ts @@ -33,7 +33,7 @@ import { FormEditorComponent } from './form-editor.component'; import { AuditInfoComponent } from '../audit-info/audit-info.component'; import { UpdateFormsComponent } from '../update-forms/update-forms.component'; import { UpdateFormsWizardComponent } from '../update-forms-wizard/update-forms-wizard.component'; - +import { NgDragDropModule } from 'ng-drag-drop'; @NgModule({ imports: [ CommonModule, @@ -42,7 +42,8 @@ import { UpdateFormsWizardComponent } from '../update-forms-wizard/update-forms- FormsModule, ReactiveFormsModule, ClipboardModule, - AppMaterialModule + AppMaterialModule, + NgDragDropModule.forRoot() ], declarations: [ @@ -50,7 +51,7 @@ import { UpdateFormsWizardComponent } from '../update-forms-wizard/update-forms- SchemaEditorComponent, ElementEditorComponent, FormRendererComponent, - DynamicQuestionComponent, + DynamicQuestionComponent, ConceptComponent, FormEditorComponent, ReferenceFormsComponent, diff --git a/src/app/form-editor/form-elements/Form.ts b/src/app/form-editor/form-elements/Form.ts index e6de019..48a80bd 100644 --- a/src/app/form-editor/form-elements/Form.ts +++ b/src/app/form-editor/form-elements/Form.ts @@ -1,16 +1,16 @@ -export class Form{ +export class Form { - name:string; - uuid:string; - processor:string; - referencedForms:any; - pages:any; + name: string; + uuid: string; + processor: string; + referencedForms: any; + pages: any[]; - constructor(options:{}={}){ - this.name = options['name'] - this.pages = options['pages'] - this.processor = options['processor'] - this.uuid = options['uuid'] - this.referencedForms = options['referencedForms'] + constructor(options: {}= {}) { + this.name = options['name']; + this.pages = options['pages']; + this.processor = options['processor']; + this.uuid = options['uuid']; + this.referencedForms = options['referencedForms']; } } \ No newline at end of file diff --git a/src/app/form-editor/form-elements/Question.ts b/src/app/form-editor/form-elements/Question.ts index 7577dc3..04b038a 100644 --- a/src/app/form-editor/form-elements/Question.ts +++ b/src/app/form-editor/form-elements/Question.ts @@ -1,21 +1,21 @@ import {FormElement} from './FormElement'; -interface QuestionOptions{ - rendering:string; - +export class QuestionOptions { + rendering: string; + answers: any; + concept: string; + } -export class Question extends FormElement{ +export class Question extends FormElement { - id:string=''; + id = ''; type: string; - questionOptions:QuestionOptions= - {rendering:'' - }; - + questionOptions: QuestionOptions = new QuestionOptions(); + questions: Question[]; + - constructor(options:{}={}){ - super(options) + constructor(options: {}= {}) { + super(options); this.type = options['type'] || ''; - this.questionOptions.rendering = options['questionOptions.rendering'] || '' - + this.questionOptions.rendering = options['questionOptions.rendering'] || ''; } -} \ No newline at end of file +} diff --git a/src/app/form-editor/navigator/navigator.component.css b/src/app/form-editor/navigator/navigator.component.css index 55be36c..5e7cf5a 100644 --- a/src/app/form-editor/navigator/navigator.component.css +++ b/src/app/form-editor/navigator/navigator.component.css @@ -60,11 +60,10 @@ label{ } -.pages{ +/* .pages{ margin:5px 2px 2px 0px; padding:5px 5px 5px 5px; - border-bottom: 1px solid rgba(211, 211, 211, 0.23); -} +} */ .ref{ margin-left:20px !important; diff --git a/src/app/form-editor/navigator/navigator.component.html b/src/app/form-editor/navigator/navigator.component.html index def0fde..9ed1ea6 100644 --- a/src/app/form-editor/navigator/navigator.component.html +++ b/src/app/form-editor/navigator/navigator.component.html @@ -1,155 +1,211 @@ -
-
-
-
- - - - - + +
+
+ +
+ + + + + +
+
- -
-
-

{{schema.name}}

+
+

+ {{schema.name}}

+ +
+ +
+ - -
-
- -
-

{{schema.name}}

-
+

+ {{schema.name}}

+
+ -
- - - - -
-
-
- -
- - - - - - - -
- -
-
-
-
+
+
-
- +
+ +
-
- -
-
- -
+ + + - + - +
+ + + + + + + + -
- - - + +
+ +
+ +
+
+
+ + + +
+ + +
+ +
+ +
+ +
+ + + + + + + - - + - - -
- + + +
+ +
+
-
-
-
+
-
-
- - Create new question + -
+
- +
+ + + +

{{question.label}}

+ + +
+ + + +
- -

{{question.label}}

+ +
+ + + + + + + + + + + + + +
- -
- -
- -
- - - - -
- - -
- +
+ +
+
+
-
-
\ No newline at end of file + diff --git a/src/app/form-editor/navigator/navigator.component.ts b/src/app/form-editor/navigator/navigator.component.ts index 0a9f30e..b5dea33 100644 --- a/src/app/form-editor/navigator/navigator.component.ts +++ b/src/app/form-editor/navigator/navigator.component.ts @@ -1,946 +1,1025 @@ -import { Component, Input, OnInit,OnDestroy, Output, EventEmitter } from '@angular/core'; +import { Component, Input, OnInit, OnDestroy, Output, EventEmitter } from '@angular/core'; import { ConfirmComponent } from '../../modals/confirm.component'; import { PromptComponent } from '../../modals/prompt.component'; import { AlertComponent } from '../../modals/alert.component'; import { ReferenceModalComponent } from '../../modals/reference-form-modal/reference-form.modal'; import { FormElementFactory } from '../form-elements/form-element-factory'; -import {FormFactory} from '../form-elements/form-factory.service' -import { DialogService } from "ng2-bootstrap-modal"; +import {FormFactory} from '../form-elements/form-factory.service'; +import { Form } from '../form-elements/Form'; +import { DialogService } from 'ng2-bootstrap-modal'; import { NavigatorService } from '../../Services/navigator.service'; import { FetchFormDetailService } from '../../Services/fetch-form-detail.service'; import { QuestionControlService } from '../../Services/question-control.service'; -import { FormControl, FormGroup, FormBuilder,Validators } from '@angular/forms'; +import { FormControl, FormGroup, FormBuilder, Validators } from '@angular/forms'; import { FormSchemaCompiler } from '../../Services/schema-compiler.service'; -import { NavigatorModalComponent } from '../../modals/navigator.modal' +import { NavigatorModalComponent } from '../../modals/navigator.modal'; import * as _ from 'lodash'; -import { Subscription } from 'rxjs'; +import { Subscription } from 'rxjs/Subscription'; @Component({ - selector: 'app-navigator', - templateUrl: './navigator.component.html', - styleUrls: ['./navigator.component.css'] + selector: 'app-navigator', + templateUrl: './navigator.component.html', + styleUrls: ['./navigator.component.css'] }) -export class NavigatorComponent implements OnInit, OnDestroy{ - - schema:any; //recursive schema could represent a question,section,page or form - private _formSchema:any; //represents a FULL form schema - private _count:number=0; - private _refElement:string; - private rawSchema:any; - private formName:string; - private subscription:Subscription; - prechecked:string; - @Input() alias:string; - addForm:FormGroup; - editForm:FormGroup; - editPageMode:boolean=false; - editSectionMode:boolean=false; - propertyModelArray:any; - editMode:boolean; - updateMode:boolean; - selectMode:boolean; - checkedRefElements:any[]=[] //selected elements to be referenced - referencedForms:any[] //an array of referencedForms metadata - referencedFormsSchemas:any[]; - excludedQuestions:string[]=[]; - _componentToHighlight:string; - @Input() mode:string; //can be either select or edit - @Input() pageIndex:number; //aids in collapsing the navigator elements - @Input() sectionIndex:number; //aids in collapsing the navigator elements - @Input() questionIndex:number; - @Input() set referenceElement(refElement){this._refElement = refElement}; //element to be referenced if select mode - @Input() set count(count){this._count=count;}//keeps count of recursive calls - @Input() set _schema(schema:any){ this.schema = schema; } - @Input() set formSchema(fschema:any){ this._formSchema = _.clone(fschema);} - @Input() set componentToHighlight(formName:string){ - this._componentToHighlight = formName; - this.alias = this.getComponentFormAlias(formName); - } - @Output() closeSidebar:EventEmitter = new EventEmitter(); - @Output() checkedRefElementsEmitter:EventEmitter = new EventEmitter(); - @Output() nestedCheckedRefElementEmitter:EventEmitter = new EventEmitter(); - - - constructor(private fb: FormBuilder, private ns: NavigatorService, private qcs: QuestionControlService, - private formElementFactory: FormElementFactory, private dialogService: DialogService, - private fs: FetchFormDetailService, private fsc: FormSchemaCompiler, private formFactory: FormFactory) { - - - } - - - - ngOnInit() { - - this.showSpinner(); - - this.ns.prechecked.subscribe((res) => { - this.prechecked = res; - }) - this.subscription = this.fs.getReferencedFormsSchemasArray().subscribe((res) => { - this.referencedForms = res; - }); - this.subscription = this.ns.getRawSchema().subscribe(res => { - if (!_.isEmpty(res)) { - this.rawSchema = _.cloneDeep(res) - } - }); - - if (this.mode == 'edit') { - this.editMode = true; - this.selectMode = false; - this.updateMode = false; - } else if (this.mode == "update") { - this.selectMode = false; - this.editMode = false; - this.updateMode = true; - - } else { - this.selectMode = true; - this.editMode = false; - this.updateMode = false; - } - this.subscription = this.ns.getExcludedQuestions().subscribe((res) => { - if (res != "") this.excludedQuestions.push(res); - else this.excludedQuestions = []; - }); - - - } - - getComponentFormAlias(uuid: string): string { - let alias: string = ""; - _.each(this._formSchema.referencedForms, (form: any) => { - if (form.uuid == uuid) { - alias = form.alias; - } - }); - return alias; - } - - //when element is clicked in navigator - onClicked(selectedSchema, pageIndex ? : number, sectionIndex ? : number, questionIndex ? : number, parentQuestionIndex ? : number) { - if (this.selectMode) return; - let schemaObj = {} - schemaObj['selectedSchema'] = selectedSchema; - schemaObj['pageIndex'] = pageIndex; - schemaObj['sectionIndex'] = sectionIndex; - schemaObj['questionIndex'] = questionIndex; - this.ns.setClickedElementSchema(schemaObj); - - if (pageIndex != undefined && sectionIndex != undefined && questionIndex != undefined && parentQuestionIndex != undefined) { - if (this.rawSchema.pages[pageIndex].label) { - if (this.rawSchema.pages[pageIndex].sections[sectionIndex].label) { - this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex].sections[sectionIndex].questions[questionIndex].questions[parentQuestionIndex]); - return; - } else { - this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex].sections[sectionIndex]); - return; - } - } else { - this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex]); - } - - } else if (pageIndex != undefined && sectionIndex != undefined && questionIndex != undefined) { - if (this.rawSchema.pages[pageIndex].label) { - if (this.rawSchema.pages[pageIndex].sections[sectionIndex].label) { - this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex].sections[sectionIndex].questions[questionIndex]); - return; - } else { - this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex].sections[sectionIndex]); - return; - } - } else { - this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex]); - return; - } - - } else if (pageIndex != undefined && sectionIndex != undefined) { - if (this.rawSchema.pages[pageIndex].label) { - - this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex].sections[sectionIndex]); - return; - } else { - this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex]); - } - - } else if (selectedSchema['name']) { - console.log("tere", this.rawSchema); - this.ns.setClickedElementRawSchema(this.rawSchema); - } else { - console.log(JSON.stringify(this.rawSchema.pages[pageIndex]), pageIndex); - this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex]); - return; - } - - } - - - showEditForm(schema: any, pageIndex: number, sectionIndex ? : number) { - this.propertyModelArray = this.qcs.toPropertyModelArray(schema) - this.editForm = this.qcs.toFormGroup(this.propertyModelArray) - - if (schema.sections) { //page - this.showEditDialog(this.propertyModelArray, this.editForm, pageIndex) - } else { //section - this.showEditDialog(this.propertyModelArray, this.editForm, pageIndex, sectionIndex) - } - } - - - showAddForm(element: string, pageIndex ? : number) { - if (element == 'page') { - - let newPage = this.formElementFactory.createFormElement(element, { - "label": '' - }); - this.propertyModelArray = this.qcs.toPropertyModelArray(newPage); - this.addForm = this.qcs.toFormGroup(this.propertyModelArray) - this.showAddDialog(this.propertyModelArray, this.addForm) - - } else { - console.log(pageIndex) - let newSection = this.formElementFactory.createFormElement(element, {}) - this.propertyModelArray = this.qcs.toPropertyModelArray(newSection) - this.addForm = this.qcs.toFormGroup(this.propertyModelArray) - this.showAddDialog(this.propertyModelArray, this.addForm, pageIndex) - } - } - - showDeleteDialog(schema: any, element: string, pageIndex: number, sectionIndex ? : number, questionIndex ? : number, parentQuestionIndex ? : number) { - this.subscription = this.dialogService.addDialog(ConfirmComponent, { - title: 'Delete ' + element, - message: 'Are you sure you want to delete ' + schema.label - }, { - backdropColor: 'rgba(0,0, 0, 0.5)' - }) - .subscribe((isConfirmed) => { - if (isConfirmed) { - if (element == 'page') this.deletePage(pageIndex) - else if (element == 'section') this.deleteSection(pageIndex, sectionIndex) - else this.deleteQuestion(pageIndex, sectionIndex, questionIndex, parentQuestionIndex) - } - }); - } - - showEditDialog(propModelArray, form, pageIndex, sectionIndex ? ) { - - if (sectionIndex > -1) - this.subscription = this.dialogService.addDialog(PromptComponent, { - title: 'Edit Section', - questions: propModelArray, - form: form - }) - .subscribe((formValue) => { - if (formValue) this.editSection(formValue, pageIndex, sectionIndex) - }); - - - else - this.subscription = this.dialogService.addDialog(PromptComponent, { - title: "Edit Page", - questions: propModelArray, - form: form - }) - .subscribe((formValue) => { - if (formValue) this.editPage(formValue['label'], pageIndex) - }); - } - - - showAddDialog(propModelArray, form, pageIndex ? ) { - if (pageIndex != undefined && pageIndex > -1) { - - this.subscription = this.dialogService.addDialog(PromptComponent, { - title: 'Create Section', - questions: propModelArray, - form: form - }, { - backdropColor: 'rgba(255, 255, 255, 0.5)' - }) - .subscribe((formValue) => { - if (formValue != undefined) this.addSection(formValue, pageIndex) - }); - - } else - this.subscription = this.dialogService.addDialog(PromptComponent, { - title: 'Create Page', - questions: propModelArray, - form: form - }, { - backdropColor: 'rgba(255, 255, 255, 0.5)' - }) - .subscribe((formValue) => { - if (formValue) this.addPage(formValue['label']) - }); - } - - - editPage(label, pageIndex) { - if (this.rawSchema.pages[pageIndex].label) { - this._formSchema.pages[pageIndex].label = label - this.rawSchema.pages[pageIndex].label = label - this.setSchema(this._formSchema) - this.setRawSchema(this.rawSchema) - } else { - this.showAlertDialog("You cannot edit a referenced page."); - return false; - } - - } - - editSection(value, pageIndex, sectionIndex) { - if (this.rawSchema.pages[pageIndex].label) { - if (this.rawSchema.pages[pageIndex].sections[sectionIndex].label) { - this.schema['sections'][sectionIndex].label = value.label; - this.schema['sections'][sectionIndex].isExpanded = value.isExpanded; - this._formSchema.pages[pageIndex] = this.schema; - this.rawSchema.pages[pageIndex] = this.schema; - this.setSchema(this._formSchema); - this.setRawSchema(this.rawSchema); - } else { - this.showAlertDialog("You cannot edit a referenced section."); - return false; - } - - } else { - this.showAlertDialog("You cannot edit a referenced page."); - return false; - } - - } - - editQuestion(question: any, pageIndex: number, sectionIndex: number, questionIndex: number, parentQuestionIndex ? : number) { - let schemaObj = {} - schemaObj['selectedSchema'] = question; - schemaObj['pageIndex'] = pageIndex; - schemaObj['sectionIndex'] = sectionIndex; - schemaObj['questionIndex'] = questionIndex; - schemaObj['parentQuestionIndex'] = parentQuestionIndex; - this.ns.setClickedElementSchema(schemaObj); // set the current edited question in the schema editor - - this.propertyModelArray = this.qcs.toPropertyModelArray(question); - if (parentQuestionIndex != undefined && parentQuestionIndex > -1) { // thy art an obsgroup question! - this.ns.newQuestion(this.propertyModelArray, pageIndex, sectionIndex, questionIndex, parentQuestionIndex); - } else { - this.ns.newQuestion(this.propertyModelArray, pageIndex, sectionIndex, questionIndex, undefined, schemaObj['selectedSchema']); - } - - } - - - addPage(label: string) { - - if (!this.doesPageExist(label)) { - let newPage = this.formElementFactory.createFormElement("page", { - "label": label - }); - this.rawSchema.pages.push(newPage); - this._formSchema.pages.push(newPage); - this.ns.setSchema(this._formSchema); - this.ns.setRawSchema(this.rawSchema); - this.onClicked(newPage, this.rawSchema.pages.length - 1); - } else this.showAlertDialog("Page already exists! \n Try creating one with a different label!"); - } - - addSection(value, pageIndex: number) { - let newSection = this.formElementFactory.createFormElement("section", { - "label": value.label, - "isExpanded": value.isExpanded - }); - - if (this.rawSchema.pages[pageIndex].label) { - this.rawSchema.pages[pageIndex].sections.push(newSection); - this._formSchema.pages[pageIndex].sections.push(newSection); - this.setSchema(this._formSchema); - this.setRawSchema(this.rawSchema); - this.onClicked(newSection, pageIndex, this.rawSchema.pages[pageIndex].sections.length - 1); - } else { - this.showAlertDialog("You cannot add a section to a referenced page."); - } - } - - - addQuestion(pageIndex: number, sectionIndex: number, questionIndex ? : number) { - console.log("Page Index", pageIndex, "Section Index", sectionIndex, "questionIndex", questionIndex) - let newQuestion = this.formElementFactory.createFormElement("question", {}); - let propertyModelArray = this.qcs.toPropertyModelArray(newQuestion); - if (questionIndex != undefined) { - this.ns.newQuestion(propertyModelArray, pageIndex, sectionIndex, questionIndex); // obsGroup - this.onClicked(newQuestion, pageIndex, sectionIndex, questionIndex, this.rawSchema.pages[pageIndex].sections[sectionIndex].questions[questionIndex].questions.length - 1); - } else { - this.ns.newQuestion(propertyModelArray, pageIndex, sectionIndex); - this.onClicked(newQuestion, pageIndex, sectionIndex, this.rawSchema.pages[pageIndex].sections[sectionIndex].questions.length - 1); - } - } - - - deletePage(pageIndex) { - this._formSchema.pages.splice(pageIndex, 1); - this.rawSchema.pages.splice(pageIndex, 1); - this.setSchema(this._formSchema); - this.setRawSchema(this.rawSchema); - } - - - deleteSection(pageIndex, sectionIndex) { - this._formSchema.pages[pageIndex].sections.splice(sectionIndex, 1); - this.rawSchema.pages[pageIndex].sections.splice(sectionIndex, 1); - this.setSchema(this._formSchema); - this.setRawSchema(this.rawSchema); - } - - deleteQuestion(pageIndex, sectionIndex, questionIndex, parentQuestionIndex) { - if (parentQuestionIndex !== undefined) { - this._formSchema.pages[pageIndex].sections[sectionIndex].questions[parentQuestionIndex].questions.splice(questionIndex, 1); - this.rawSchema.pages[pageIndex].sections[sectionIndex].questions[parentQuestionIndex].questions.splice(questionIndex, 1); - } else { - this._formSchema.pages[pageIndex].sections[sectionIndex].questions.splice(questionIndex, 1); - this.rawSchema.pages[pageIndex].sections[sectionIndex].questions.splice(questionIndex, 1); - } - - this.setSchema(this._formSchema); - this.setRawSchema(this.rawSchema); - } - - doesPageExist(label: string): boolean { - let result = false; - - this._formSchema.pages.forEach(page => { - - if (Object.is(label.toLowerCase(), page.label.toLowerCase())) { - result = true; - } - }) - return result; - } - - - addReferencePage() { - - if (this.referencedForms.length > 0) - this.subscription = this.dialogService.addDialog(ReferenceModalComponent, { - refElement: 'Page' - }, { - backdropColor: 'rgba(0, 0, 0, 0.5)' - }) - .subscribe((res) => { - if (res != undefined) { - this.createRefPages(JSON.parse(res)); - } - - }); - else this.showAlertDialog("Insert reference form first"); - - } - - - addReferenceSection(pageIndex) { - this.ns.setExcludedQuestions(""); - if (this.referencedForms.length > 0) - this.subscription = this.dialogService.addDialog(ReferenceModalComponent, { - refElement: 'Section' - }, { - backdropColor: 'rgba(0, 0, 0, 0.5)' - }).subscribe(res => { - - if (res != undefined) { - this.createRefSections(JSON.parse(res), pageIndex); - } - }) - - else this.showAlertDialog("Insert reference form first"); - } - - addReferenceQuestion(pageIndex, sectionIndex, questionIndex ? ) { - if (this.referencedForms.length > 0) - this.subscription = this.dialogService.addDialog(ReferenceModalComponent, { - refElement: 'Question' - }, { - backdropColor: 'rgba(0,0,0,0.5)' - }).subscribe(res => { - if (res != undefined) { - //this.createRefQuestions(JSON.parse(res),pageIndex,sectionIndex,questionIndex) - } - }) - } - setCheckedReferenceElement(event, element ? ) { +export class NavigatorComponent implements OnInit, OnDestroy { + + schema: any; // recursive schema could represent a question,section,page or form + private _formSchema: Form; // represents a FULL form schema + private _count= 0; + private _refElement: string; + private rawSchema: Form; + private formName: string; + private subscription: Subscription; + prechecked: string; + @Input() alias: string; + addForm: FormGroup; + editForm: FormGroup; + editPageMode= false; + editSectionMode= false; + propertyModelArray: any; + editMode: boolean; + updateMode: boolean; + selectMode: boolean; + checkedRefElements: any[]= []; // selected elements to be referenced + referencedForms: any[]; // an array of referencedForms metadata + referencedFormsSchemas: any[]; + excludedQuestions: string[]= []; + _componentToHighlight: string; + @Input() mode: string; // can be either select or edit + @Input() pageIndex: number; // aids in collapsing the navigator elements + @Input() sectionIndex: number; // aids in collapsing the navigator elements + @Input() questionIndex: number; + @Input() set referenceElement(refElement){this._refElement = refElement; } // element to be referenced if select mode + @Input() set count(count){this._count = count; }// keeps count of recursive calls + @Input() set _schema(schema: any){ this.schema = schema; } + @Input() set formSchema(fschema: any){ this._formSchema = _.clone(fschema); } + @Input() set componentToHighlight(formName: string) { + this._componentToHighlight = formName; + this.alias = this.getComponentFormAlias(formName); + } + @Output() closeSidebar: EventEmitter = new EventEmitter(); + @Output() checkedRefElementsEmitter: EventEmitter = new EventEmitter(); + @Output() nestedCheckedRefElementEmitter: EventEmitter = new EventEmitter(); + + + constructor(private fb: FormBuilder, private ns: NavigatorService, private qcs: QuestionControlService, + private formElementFactory: FormElementFactory, private dialogService: DialogService, + private fs: FetchFormDetailService, private fsc: FormSchemaCompiler, private formFactory: FormFactory) { + + + } + + + + ngOnInit() { + this.fs.setLoaded(false); + this.showSpinner(); + this.ns.prechecked.subscribe((res) => { + this.prechecked = res; + }); + this.subscription = this.fs.getReferencedFormsSchemasArray().subscribe((res) => { + this.referencedForms = res; + }); + this.subscription = this.ns.getRawSchema().subscribe((res: Form) => { + if (!_.isEmpty(res)) { + this.rawSchema = _.cloneDeep(res); + } + }); + + if (this.mode === 'edit') { + this.editMode = true; + this.selectMode = false; + this.updateMode = false; + } else if (this.mode === 'update') { + this.selectMode = false; + this.editMode = false; + this.updateMode = true; + + } else { + this.selectMode = true; + this.editMode = false; + this.updateMode = false; + } + this.subscription = this.ns.getExcludedQuestions().subscribe((res) => { + if (res !== '') { this.excludedQuestions.push(res); } else { + this.excludedQuestions = []; + } + }); + + } + getComponentFormAlias(uuid: string): string { + let alias = ''; + _.each(this._formSchema.referencedForms, (form: any) => { + if (form.uuid === uuid) { + alias = form.alias; + } + }); + return alias; + } + + // when element is clicked in navigator + onClicked(selectedSchema, pageIndex ?: number, sectionIndex ? : number, questionIndex ? : number, parentQuestionIndex ? : number) { + if (this.selectMode) { return; } + let schemaObj = {}; + schemaObj['selectedSchema'] = selectedSchema; + schemaObj['pageIndex'] = pageIndex; + schemaObj['sectionIndex'] = sectionIndex; + schemaObj['questionIndex'] = questionIndex; + this.ns.setClickedElementSchema(schemaObj); + + if (pageIndex !== undefined && sectionIndex !== undefined && questionIndex !== undefined && parentQuestionIndex !== undefined) { + if (this.rawSchema.pages[pageIndex].label) { + if (this.rawSchema.pages[pageIndex].sections[sectionIndex].label) { + this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex] + .sections[sectionIndex].questions[questionIndex].questions[parentQuestionIndex]); + return; + } else { + this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex].sections[sectionIndex]); + return; + } + } else { + this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex]); + } + + } else if (pageIndex !== undefined && sectionIndex !== undefined && questionIndex !== undefined) { + if (this.rawSchema.pages[pageIndex].label) { + if (this.rawSchema.pages[pageIndex].sections[sectionIndex].label) { + this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex].sections[sectionIndex].questions[questionIndex]); + return; + } else { + this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex].sections[sectionIndex]); + return; + } + } else { + this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex]); + return; + } + + } else if (pageIndex !== undefined && sectionIndex !== undefined) { + if (this.rawSchema.pages[pageIndex].label) { + + this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex].sections[sectionIndex]); + return; + } else { + this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex]); + } + + } else if (selectedSchema['name']) { + console.log('tere', this.rawSchema); + this.ns.setClickedElementRawSchema(this.rawSchema); + } else { + console.log(JSON.stringify(this.rawSchema.pages[pageIndex]), pageIndex); + this.ns.setClickedElementRawSchema(this.rawSchema.pages[pageIndex]); + return; + } + + } + + + showEditForm(schema: any, pageIndex: number, sectionIndex ? : number) { + this.propertyModelArray = this.qcs.toPropertyModelArray(schema); + this.editForm = this.qcs.toFormGroup(this.propertyModelArray); + + if (schema.sections) { // page + this.showEditDialog(this.propertyModelArray, this.editForm, pageIndex); + } else { // section + this.showEditDialog(this.propertyModelArray, this.editForm, pageIndex, sectionIndex); + } + } + + + showAddForm(element: string, pageIndex ? : number) { + if (element === 'page') { + + let newPage = this.formElementFactory.createFormElement(element, { + 'label': '' + }); + this.propertyModelArray = this.qcs.toPropertyModelArray(newPage); + this.addForm = this.qcs.toFormGroup(this.propertyModelArray); + this.showAddDialog(this.propertyModelArray, this.addForm); + + } else { + console.log(pageIndex); + let newSection = this.formElementFactory.createFormElement(element, {}); + this.propertyModelArray = this.qcs.toPropertyModelArray(newSection); + this.addForm = this.qcs.toFormGroup(this.propertyModelArray); + this.showAddDialog(this.propertyModelArray, this.addForm, pageIndex); + } + } + + showDeleteDialog + (schema: any, element: string, pageIndex: number, sectionIndex ? : number, questionIndex ? : number, parentQuestionIndex ? : number) { + this.subscription = this.dialogService.addDialog(ConfirmComponent, { + title: 'Delete ' + element, + message: 'Are you sure you want to delete ' + schema.label + }, { + backdropColor: 'rgba(0,0, 0, 0.5)' + }) + .subscribe((isConfirmed) => { + if (isConfirmed) { + if (element === 'page') { this.deletePage(pageIndex); } else if (element === 'section') { + this.deleteSection(pageIndex, sectionIndex); } else { + this.deleteQuestion(pageIndex, sectionIndex, questionIndex, parentQuestionIndex); } + } + }); + } + + showEditDialog(propModelArray, form, pageIndex, sectionIndex ? ) { + + if (sectionIndex > -1){ + this.subscription = this.dialogService.addDialog(PromptComponent, { + title: 'Edit Section', + questions: propModelArray, + form: form + }) + .subscribe((formValue) => { + if (formValue) { this.editSection(formValue, pageIndex, sectionIndex); } + }); + } else { + this.subscription = this.dialogService.addDialog(PromptComponent, { + title: 'Edit Page', + questions: propModelArray, + form: form + }) + .subscribe((formValue) => { + if (formValue) { this.editPage(formValue['label'], pageIndex);} + }); + } + } + + + showAddDialog(propModelArray, form, pageIndex ? ) { + if (pageIndex !== undefined && pageIndex > -1) { + + this.subscription = this.dialogService.addDialog(PromptComponent, { + title: 'Create Section', + questions: propModelArray, + form: form + }, { + backdropColor: 'rgba(255, 255, 255, 0.5)' + }) + .subscribe((formValue) => { + if (formValue !== undefined) { this.addSection(formValue, pageIndex); } + }); + + } else { + this.subscription = this.dialogService.addDialog(PromptComponent, { + title: 'Create Page', + questions: propModelArray, + form: form + }, { + backdropColor: 'rgba(255, 255, 255, 0.5)' + }) + .subscribe((formValue) => { + if (formValue) { this.addPage(formValue['label']); } + }); + } + } + + + editPage(label, pageIndex) { + if (this.rawSchema.pages[pageIndex].label) { + this._formSchema.pages[pageIndex].label = label; + this.rawSchema.pages[pageIndex].label = label; + this.setSchema(this._formSchema); + this.setRawSchema(this.rawSchema); + } else { + this.showAlertDialog('You cannot edit a referenced page.'); + return false; + } + + } + + editSection(value, pageIndex, sectionIndex) { + if (this.rawSchema.pages[pageIndex].label) { + if (this.rawSchema.pages[pageIndex].sections[sectionIndex].label) { + this.schema['sections'][sectionIndex].label = value.label; + this.schema['sections'][sectionIndex].isExpanded = value.isExpanded; + this._formSchema.pages[pageIndex] = this.schema; + this.rawSchema.pages[pageIndex] = this.schema; + this.setSchema(this._formSchema); + this.setRawSchema(this.rawSchema); + } else { + this.showAlertDialog('You cannot edit a referenced section.'); + return false; + } + + } else { + this.showAlertDialog('You cannot edit a referenced page.'); + return false; + } + + } + + editQuestion(question: any, pageIndex: number, sectionIndex: number, questionIndex: number, parentQuestionIndex ? : number) { + let schemaObj = {}; + schemaObj['selectedSchema'] = question; + schemaObj['pageIndex'] = pageIndex; + schemaObj['sectionIndex'] = sectionIndex; + schemaObj['questionIndex'] = questionIndex; + schemaObj['parentQuestionIndex'] = parentQuestionIndex; + this.ns.setClickedElementSchema(schemaObj); // set the current edited question in the schema editor + + this.propertyModelArray = this.qcs.toPropertyModelArray(question); + if (parentQuestionIndex !== undefined && parentQuestionIndex > -1) { // thy art an obsgroup question! + this.ns.newQuestion(this.propertyModelArray, pageIndex, sectionIndex, questionIndex, parentQuestionIndex); + } else { + this.ns.newQuestion(this.propertyModelArray, pageIndex, sectionIndex, questionIndex, undefined, schemaObj['selectedSchema']); + } + + } + + + addPage(label: string) { + + if (!this.doesPageExist(label)) { + let newPage = this.formElementFactory.createFormElement('page', { + 'label': label + }); + this.rawSchema.pages.push(newPage); + this._formSchema.pages.push(newPage); + this.ns.setSchema(this._formSchema); + this.ns.setRawSchema(this.rawSchema); + this.onClicked(newPage, this.rawSchema.pages.length - 1); + } else { this + .showAlertDialog('Page already exists! \n Try creating one with a different label!'); + }} + + addSection(value, pageIndex: number) { + let newSection = this.formElementFactory.createFormElement('section', { + 'label': value.label, + 'isExpanded': value.isExpanded + }); + + if (this.rawSchema.pages[pageIndex].label) { + this.rawSchema.pages[pageIndex].sections.push(newSection); + this._formSchema.pages[pageIndex].sections.push(newSection); + this.setSchema(this._formSchema); + this.setRawSchema(this.rawSchema); + this.onClicked(newSection, pageIndex, this.rawSchema.pages[pageIndex].sections.length - 1); + } else { + this.showAlertDialog('You cannot add a section to a referenced page.'); + } + } + + + addQuestion(pageIndex: number, sectionIndex: number, questionIndex ? : number) { + console.log('Page Index', pageIndex, 'Section Index', sectionIndex, 'questionIndex', questionIndex); + let newQuestion = this.formElementFactory.createFormElement('question', {}); + let propertyModelArray = this.qcs.toPropertyModelArray(newQuestion); + if (questionIndex !== undefined) { + this.ns.newQuestion(propertyModelArray, pageIndex, sectionIndex, questionIndex); // obsGroup + this + .onClicked(newQuestion, pageIndex, sectionIndex, questionIndex, this.rawSchema.pages[pageIndex].sections[sectionIndex].questions[questionIndex].questions.length - 1); + } else { + this.ns.newQuestion(propertyModelArray, pageIndex, sectionIndex); + this.onClicked(newQuestion, pageIndex, sectionIndex, this.rawSchema.pages[pageIndex].sections[sectionIndex].questions.length - 1); + } + } + + + deletePage(pageIndex) { + this._formSchema.pages.splice(pageIndex, 1); + this.rawSchema.pages.splice(pageIndex, 1); + this.setSchema(this._formSchema); + this.setRawSchema(this.rawSchema); + } + + + deleteSection(pageIndex, sectionIndex) { + this._formSchema.pages[pageIndex].sections.splice(sectionIndex, 1); + this.rawSchema.pages[pageIndex].sections.splice(sectionIndex, 1); + this.setSchema(this._formSchema); + this.setRawSchema(this.rawSchema); + } + + deleteQuestion(pageIndex, sectionIndex, questionIndex, parentQuestionIndex) { + if (parentQuestionIndex !== undefined) { + this._formSchema.pages[pageIndex].sections[sectionIndex].questions[parentQuestionIndex].questions.splice(questionIndex, 1); + this.rawSchema.pages[pageIndex].sections[sectionIndex].questions[parentQuestionIndex].questions.splice(questionIndex, 1); + } else { + this._formSchema.pages[pageIndex].sections[sectionIndex].questions.splice(questionIndex, 1); + this.rawSchema.pages[pageIndex].sections[sectionIndex].questions.splice(questionIndex, 1); + } + + this.setSchema(this._formSchema); + this.setRawSchema(this.rawSchema); + } + + doesPageExist(label: string): boolean { + let result = false; + + this._formSchema.pages.forEach(page => { + + if (Object.is(label.toLowerCase(), page.label.toLowerCase())) { + result = true; + } + }); + return result; + } + + + addReferencePage() { + + if (this.referencedForms.length > 0){ + this.subscription = this.dialogService.addDialog(ReferenceModalComponent, { + refElement: 'Page' + }, { + backdropColor: 'rgba(0, 0, 0, 0.5)' + }) + .subscribe((res) => { + if (res !== undefined) { + this.createRefPages(JSON.parse(res)); + } + + }); + } else { this.showAlertDialog('Insert reference form first');} + + } + + + addReferenceSection(pageIndex) { + this.ns.setExcludedQuestions(''); + if (this.referencedForms.length > 0) + this.subscription = this.dialogService.addDialog(ReferenceModalComponent, { + refElement: 'Section' + }, { + backdropColor: 'rgba(0, 0, 0, 0.5)' + }).subscribe(res => { + + if (res !== undefined) { + this.createRefSections(JSON.parse(res), pageIndex); + } + }); + + else this.showAlertDialog('Insert reference form first'); + } + + addReferenceQuestion(pageIndex, sectionIndex, questionIndex ? ) { + if (this.referencedForms.length > 0) + this.subscription = this.dialogService.addDialog(ReferenceModalComponent, { + refElement: 'Question' + }, { + backdropColor: 'rgba(0,0,0,0.5)' + }).subscribe(res => { + if (res !== undefined) { + // this.createRefQuestions(JSON.parse(res),pageIndex,sectionIndex,questionIndex) + } + }); + } - let ev; - let el; - if (element) { - console.log(element) - ev = event - el = element - } else { - ev = event.event - el = event.element - } - if (ev.target.checked) { - this.checkedRefElements.push(el) - } else { - if (this.checkedRefElements.length > 0) { - this.checkedRefElements.forEach((element, index) => { - if (typeof element != 'object' && element == el) { - this.checkedRefElements.splice(index, 1) - } else if (typeof element == 'object' && JSON.stringify(el) === JSON.stringify(element)) { - this.checkedRefElements.splice(index, 1) + setCheckedReferenceElement(event, element ? ) { - } - }) - } - } + let ev; + let el; + if (element) { + console.log(element); + ev = event; + el = element; + } else { + ev = event.event; + el = event.element; + } - if (this.schema['pages']) - this.checkedRefElementsEmitter.emit(this.checkedRefElements) + if (ev.target.checked) { + this.checkedRefElements.push(el); + } else { + if (this.checkedRefElements.length > 0) { + this.checkedRefElements.forEach((element, index) => { + if (typeof element !== 'object' && element === el) { + this.checkedRefElements.splice(index, 1); + } else if (typeof element === 'object' && JSON.stringify(el) === JSON.stringify(element)) { + this.checkedRefElements.splice(index, 1); - } + } + }); + } + } + if (this.schema['pages']) + this.checkedRefElementsEmitter.emit(this.checkedRefElements); - emitCheckedReferenceElement(event, element) { - let e = {} - e['event'] = event - e['element'] = element - this.nestedCheckedRefElementEmitter.emit(e) - } + } + emitCheckedReferenceElement(event, element) { + let e = {}; + e['event'] = event; + e['element'] = element; + this.nestedCheckedRefElementEmitter.emit(e); + } - closeNav() { - this.closeSidebar.emit(true) - } - - - createRefPages(res) { - let formProps = this.createBasicFormProps(); - let tempSchema: Object; - - - for (var el of JSON.parse(res['Pages'])) { - let obj: any = {} - obj['reference'] = { - "form": res.form, - "page": el - } - formProps['pages'].push(obj) - - obj = JSON.stringify(obj) - - - this.rawSchema.pages.push(JSON.parse(obj)); - - - - - } - - - let mockForm = this.formFactory.createForm(formProps); - let compiledForm = this.fsc.compileFormSchema(mockForm, this.referencedForms) - compiledForm['pages'].forEach(page => { - if (this.doesPageExist(page.label)) { - this.showAlertDialog(page.label + " already exists! \n Try referencing one with a different label"); - } else { - - this._formSchema.pages.push(page) - this.setSchema(this._formSchema); - this.setRawSchema(this.rawSchema); - - - } - }); - - - - } - - createRefSections(res, pageIndex) { - - let formProps = this.createBasicFormProps(pageIndex); - let formAlias = res.form; - for (var el of JSON.parse(res['Sections'])) { - let obj: any = {} - if (this.excludedQuestions.length > 0) { - obj['reference'] = { - "form": res.form, - "page": el.page, - "section": el.section, - "excludeQuestions": this.addExcludedQuestions(res.form, el) - } - - } else { - obj['reference'] = { - "form": res.form, - "page": el.page, - "section": el.section - }; - - } - - formProps['pages'][0]['sections'].push(obj); - obj = JSON.stringify(obj); - - - if (!this.rawSchema.pages) { - this.showAlertDialog("You cannot reference a section in a referenced page! Please create a new page in order to reference this section."); - return false; - } else { - if (!this.sectionExist(pageIndex, JSON.parse(obj).reference.section)) - this.rawSchema.pages[pageIndex].sections.push(JSON.parse(obj)); - } - - } - let mockForm = this.formFactory.createForm(formProps); - let compiledForm = this.fsc.compileFormSchema(mockForm, this.referencedForms); - - compiledForm['pages'][0]['sections'].forEach( - section => { - if (!this.sectionExist(pageIndex, section.label)) - this._formSchema.pages[pageIndex].sections.push(section) - }); - this.setSchema(this._formSchema); - this.setRawSchema(this.rawSchema); - - } - - sectionExist(pageIndex, sectionlabel) { - let exist: boolean = false; - this._formSchema.pages[pageIndex].sections.forEach((section) => { - if (section.label == sectionlabel) { - exist = true; - } - }) - return exist; - } - - // createRefQuestions(res,pageIndex,sectionIndex,questionIndex?){ - // console.log(res) - // let formProps=this.createBasicFormProps(pageIndex,sectionIndex) - // for(var el of JSON.parse(res['Questions'])){ - // let obj = {} - // obj['reference']={"form":res.form, "page":el.page, "section":el.section, "question":el.question} - // formProps['pages'][0]['sections'][0].questions.push(obj) - - // } - // let mockForm = this.formFactory.createForm(formProps) - // let compiledForm = this.fsc.compileFormSchema(mockForm,this.referencedForms) - // console.log(compiledForm) - //console.log(compiledForm) - // compiledForm['pages'][0]['sections'][0]['questions'].forEach( - // question => { - // if(questionIndex!==undefined){ - // this._formSchema.pages[pageIndex].sections[sectionIndex].questions[questionIndex].push(question) - // } - // else{ - // this._formSchema.pages[pageIndex].sections[sectionIndex].questions.push(question) - // } - // } - // ) - - //} - - createBasicFormProps(pageIndex ? , sectionIndex ? ) { - let formProps = {} - formProps['name'] = this.rawSchema.name; - formProps['uuid'] = this.rawSchema.uuid; - formProps['processor'] = this.rawSchema.processor; - formProps['referencedForms'] = this.rawSchema.referencedForms; - formProps['pages'] = [] - - if (pageIndex != undefined && sectionIndex != undefined) { - - formProps['pages'].push(this.formElementFactory.createFormElement('page', { - "label": this._formSchema.pages[pageIndex].label - })); - - formProps['pages'][0].sections.push(this.formElementFactory.createFormElement('section', { - "label": this._formSchema.pages[pageIndex].sections[sectionIndex].label, - "questions": [] - })) - console.log("formProps", formProps) - return formProps; - } - if (pageIndex !== undefined) { - formProps['pages'].push(this.formElementFactory.createFormElement('page', { - "label": this._formSchema.pages[pageIndex].label - })); - return formProps; - } else { - return formProps; - } - - - } - - addExcludedQuestions(res, el) { - let exQ = this.excludedQuestions; - let formAlias = res; - let final = []; - let acceptedQuestionIds = []; - let referencedFormDits = []; - - - this.fs.getReferencedFormsDetails().subscribe((dits) => { - referencedFormDits = _.cloneDeep(dits); - referencedFormDits.forEach((form) => { - if (form.alias = formAlias) { - this.referencedForms.forEach((form$, index) => { - if (form$.name == form.formName) { - form$.pages.forEach((page, pageIndex) => { - if (page.label == el.page) { - form$.pages[pageIndex].sections.forEach((section, sectionIndex) => { - if (section.label == el.section) { - form$.pages[pageIndex].sections[sectionIndex].questions.forEach((question) => { - if (question.id) { - acceptedQuestionIds.push(question.id); - } - }) - } - }) - } - }) - } - }) - } - }) - }) - - acceptedQuestionIds.forEach((questionID) => { - exQ.forEach((excludedQuestionId) => { - if (excludedQuestionId == questionID) { - final.push(excludedQuestionId); - } - }) - - }) - return final; - } - - excludeQuestion(pageIndex, sectionIndex, questionIndex, parentQuestionIndex, questionID) { - - if (parentQuestionIndex != undefined) { - this._formSchema.pages[pageIndex].sections[sectionIndex].questions[parentQuestionIndex].questions.splice(questionIndex, 1) - } else { - this._formSchema.pages[pageIndex].sections[sectionIndex].questions.splice(questionIndex, 1); - } - // this.findAndReplaceReferenceFormByName(this._formSchema.name,this._formSchema); - - this.ns.setExcludedQuestions(questionID); - } - - // excludeSection(pageIndex,sectionIndex){ - // this._formSchema.pages[pageIndex].sections.splice(sectionIndex,1); - // this.findAndReplaceReferenceFormByName(this._formSchema.name,this._formSchema) - // } - - findAndReplaceReferenceFormByName(name: string, schema: Object) { - this.referencedForms.forEach((form, index) => { - if (form.name == name) { - this.referencedForms.splice(index, 1, schema); - } - }) - } - - showAlertDialog(message: string) { - this.dialogService.addDialog(AlertComponent, { - message: message - }); - } - - setRawSchema(obj) { - this.ns.setRawSchema(obj) - } - - setSchema(schema: Object) { - this.ns.setSchema(this._formSchema) - } - ngOnDestroy() { - this.subscription.unsubscribe(); - } - - editFormName(value: any) { - - this._formSchema.name = value.formname; - this.rawSchema.name = value.formname; - this.setSchema(this._formSchema); - this.setRawSchema(this.rawSchema); - } - - showNameEditForm(name: string) { - this.formName = name; - this.schema['name'] = ''; - } - - showSpinner() { - try { - if (!_.isEmpty(this._formSchema.pages)) { - let lastPageIndex: number = this._formSchema.pages.length - 1; - - if (!_.isEmpty(this._formSchema.pages[lastPageIndex].sections)) { - let lastSectionIndex: number = this._formSchema.pages[lastPageIndex].sections.indexOf(this._formSchema.pages[lastPageIndex].sections[this._formSchema.pages[lastPageIndex].sections.length - 1]); - - if (this._formSchema.pages[lastPageIndex].sections[lastSectionIndex]) { - if (this._formSchema.pages[lastPageIndex].sections[lastSectionIndex].questions) { - let lastQuestionIndex: number = this._formSchema.pages[lastPageIndex].sections[lastSectionIndex].questions.indexOf(this._formSchema.pages[lastPageIndex].sections[lastSectionIndex].questions[this._formSchema.pages[lastPageIndex].sections[lastSectionIndex].questions.length - 1]); - if (this._formSchema.pages[lastPageIndex].sections[lastSectionIndex].questions[lastQuestionIndex] == this.schema) { - this.fs.setLoaded(true); - } - } - } else { - this.fs.setLoaded(true); - } - } else { - this.fs.setLoaded(true); - } - - } else { - this.fs.setLoaded(true); - } - - - } catch (e) { - console.error(e); - } - } - - IsPageReferenced(pageIndex) { - let isReferenced: boolean = false; - if (!this.rawSchema.pages[pageIndex].label) { - isReferenced = true; - } - return isReferenced; - } - - IsSectionReferenced(pageIndex, sectionIndex) { - let isReferenced: boolean = false; - if (this.selectMode) { - return false; - } - if (this.rawSchema.pages[pageIndex].label){ - if (!this.rawSchema.pages[pageIndex].sections[sectionIndex].label) { - isReferenced = true; - } - } - else{ - isReferenced = true; - } - - return isReferenced; - } - - IsSectionOnlyReferenced(pageIndex,sectionIndex){ - let result = false; - let section:any = {}; - if(!this.IsPageReferenced(pageIndex)){ - section = this.rawSchema.pages[pageIndex].sections[sectionIndex]; - if(section.reference) - result = true; - else - result = true; - } - return result; - } - - - editReferenceSection(pageIndex, sectionIndex: any) { - let section = this.rawSchema.pages[pageIndex].sections[sectionIndex]; - - this.ns.setPrechecked(section.reference.section); - _.forEach(this.rawSchema.referencedForms, (form: any) => { - if (_.isEqual(section.reference.form, form.alias)) { - this.fs.fetchFormMetadata(form.ref.uuid, true).then((metadata) => { - this.fs.fetchForm(metadata.resources[0].valueReference, true).then((schema) => { - this.subscription = this.dialogService.addDialog(NavigatorModalComponent, { - title: `Edit Referenced Section`, - schema: schema, - referenceElement: "section" - }, { - backdropColor: 'rgba(0, 0, 0, 0.5)' - }) - .subscribe((res) => { - console.log(typeof(res)); - if(res) this.createRefSections({ - form: form.alias, - Sections: res - }, pageIndex)}); - }); - }); - } - }); - - - - - } - - - excludeQuestionFromReferencedSection(pageIndex, sectionIndex, k, questionId) { - this._formSchema.pages[pageIndex].sections[sectionIndex].questions.splice(k, 1); - let section = this.rawSchema.pages[pageIndex].sections[sectionIndex]; - let newSection = ""; - if (this.isSectionCustomized(section)) { - this.rawSchema.pages[pageIndex].sections[sectionIndex].excludeQuestions.push(questionId); - } else { - - section['reference']['excludeQuestions'] = [questionId]; - this.rawSchema.pages[pageIndex].sections[sectionIndex] = section; - } - this.setRawSchema(this.rawSchema); - this.setSchema(this._formSchema); - } - - isSectionCustomized(section) { - let isCustomized: boolean = false; - if (section.excludeQuestions) { - isCustomized = true; - } - return isCustomized; - } - - - - checkMode(pageIndex: number, sections: any[]): boolean { - - let result: boolean = false; - - if (this.editMode || this.selectMode) { - result = true; - } - - if (this.updateMode) { - - if(this.IsPageReferenced(pageIndex)){ - if(this.rawSchema.pages[pageIndex].reference.form == this.alias) - return true; - } - - if (!_.isEmpty(sections)) { - _.each(sections, (section) => { - if (!section.label) { - if (section.reference.form == this.alias) { - result = true; - }}})}} - return result; - } - - IsSectionReferencedFromComponent(pageIndex, sectionIndex): boolean { - - let results: boolean = false; - if (this.editMode || this.selectMode) { - results = true; - } else if (this.IsPageReferenced(pageIndex)) { - return true; - } else if (this.updateMode) { - if (this.IsSectionReferenced(pageIndex, sectionIndex)) { - if (this.rawSchema.pages[pageIndex].sections[sectionIndex].reference.form == this.alias) { - results = true; - } - } - } - - return results; - } - } + + closeNav() { + this.closeSidebar.emit(true); + } + + + createRefPages(res) { + let formProps = this.createBasicFormProps(); + let tempSchema: Object; + + + for (var el of JSON.parse(res['Pages'])) { + let obj: any = {}; + obj['reference'] = { + 'form': res.form, + 'page': el + }; + formProps['pages'].push(obj); + + obj = JSON.stringify(obj); + + + this.rawSchema.pages.push(JSON.parse(obj)); + + + + + } + + + let mockForm = this.formFactory.createForm(formProps); + let compiledForm = this.fsc.compileFormSchema(mockForm, this.referencedForms); + compiledForm['pages'].forEach(page => { + if (this.doesPageExist(page.label)) { + this.showAlertDialog(page.label + ' already exists! \n Try referencing one with a different label'); + } else { + + this._formSchema.pages.push(page); + this.setSchema(this._formSchema); + this.setRawSchema(this.rawSchema); + + + } + }); + + + + } + + createRefSections(res, pageIndex) { + + let formProps = this.createBasicFormProps(pageIndex); + let formAlias = res.form; + for (var el of JSON.parse(res['Sections'])) { + let obj: any = {}; + if (this.excludedQuestions.length > 0) { + obj['reference'] = { + 'form': res.form, + 'page': el.page, + 'section': el.section, + 'excludeQuestions': this.addExcludedQuestions(res.form, el) + }; + + } else { + obj['reference'] = { + 'form': res.form, + 'page': el.page, + 'section': el.section + }; + + } + + formProps['pages'][0]['sections'].push(obj); + obj = JSON.stringify(obj); + + + if (!this.rawSchema.pages) { + this.showAlertDialog('You cannot reference a section in a referenced page! Please create a new page in order to reference this section.'); + return false; + } else { + if (!this.sectionExist(pageIndex, JSON.parse(obj).reference.section)) + this.rawSchema.pages[pageIndex].sections.push(JSON.parse(obj)); + } + + } + let mockForm = this.formFactory.createForm(formProps); + let compiledForm = this.fsc.compileFormSchema(mockForm, this.referencedForms); + + compiledForm['pages'][0]['sections'].forEach( + section => { + if (!this.sectionExist(pageIndex, section.label)) + this._formSchema.pages[pageIndex].sections.push(section); + }); + this.setSchema(this._formSchema); + this.setRawSchema(this.rawSchema); + + } + + sectionExist(pageIndex, sectionlabel) { + let exist: boolean = false; + this._formSchema.pages[pageIndex].sections.forEach((section) => { + if (section.label === sectionlabel) { + exist = true; + } + }); + return exist; + } + + // createRefQuestions(res,pageIndex,sectionIndex,questionIndex?){ + // console.log(res) + // let formProps=this.createBasicFormProps(pageIndex,sectionIndex) + // for(var el of JSON.parse(res['Questions'])){ + // let obj = {} + // obj['reference']={"form":res.form, "page":el.page, "section":el.section, "question":el.question} + // formProps['pages'][0]['sections'][0].questions.push(obj) + + // } + // let mockForm = this.formFactory.createForm(formProps) + // let compiledForm = this.fsc.compileFormSchema(mockForm,this.referencedForms) + // console.log(compiledForm) + // console.log(compiledForm) + // compiledForm['pages'][0]['sections'][0]['questions'].forEach( + // question => { + // if(questionIndex!==undefined){ + // this._formSchema.pages[pageIndex].sections[sectionIndex].questions[questionIndex].push(question) + // } + // else{ + // this._formSchema.pages[pageIndex].sections[sectionIndex].questions.push(question) + // } + // } + // ) + + // } + + createBasicFormProps(pageIndex ? , sectionIndex ? ) { + let formProps = {}; + formProps['name'] = this.rawSchema.name; + formProps['uuid'] = this.rawSchema.uuid; + formProps['processor'] = this.rawSchema.processor; + formProps['referencedForms'] = this.rawSchema.referencedForms; + formProps['pages'] = []; + + if (pageIndex !== undefined && sectionIndex !== undefined) { + + formProps['pages'].push(this.formElementFactory.createFormElement('page', { + 'label': this._formSchema.pages[pageIndex].label + })); + + formProps['pages'][0].sections.push(this.formElementFactory.createFormElement('section', { + 'label': this._formSchema.pages[pageIndex].sections[sectionIndex].label, + 'questions': [] + })); + console.log('formProps', formProps); + return formProps; + } + if (pageIndex !== undefined) { + formProps['pages'].push(this.formElementFactory.createFormElement('page', { + 'label': this._formSchema.pages[pageIndex].label + })); + return formProps; + } else { + return formProps; + } + + + } + + addExcludedQuestions(res, el) { + let exQ = this.excludedQuestions; + let formAlias = res; + let final = []; + let acceptedQuestionIds = []; + let referencedFormDits = []; + + + this.fs.getReferencedFormsDetails().subscribe((dits) => { + referencedFormDits = _.cloneDeep(dits); + referencedFormDits.forEach((form) => { + if (form.alias = formAlias) { + this.referencedForms.forEach((form$, index) => { + if (form$.name === form.formName) { + form$.pages.forEach((page, pageIndex) => { + if (page.label === el.page) { + form$.pages[pageIndex].sections.forEach((section, sectionIndex) => { + if (section.label === el.section) { + form$.pages[pageIndex].sections[sectionIndex].questions.forEach((question) => { + if (question.id) { + acceptedQuestionIds.push(question.id); + } + }); + } + }); + } + }); + } + }); + } + }); + }); + + acceptedQuestionIds.forEach((questionID) => { + exQ.forEach((excludedQuestionId) => { + if (excludedQuestionId === questionID) { + final.push(excludedQuestionId); + } + }); + + }); + return final; + } + + excludeQuestion(pageIndex, sectionIndex, questionIndex, parentQuestionIndex, questionID) { + + if (parentQuestionIndex !== undefined) { + this._formSchema.pages[pageIndex].sections[sectionIndex].questions[parentQuestionIndex].questions.splice(questionIndex, 1); + } else { + this._formSchema.pages[pageIndex].sections[sectionIndex].questions.splice(questionIndex, 1); + } + // this.findAndReplaceReferenceFormByName(this._formSchema.name,this._formSchema); + + this.ns.setExcludedQuestions(questionID); + } + + // excludeSection(pageIndex,sectionIndex){ + // this._formSchema.pages[pageIndex].sections.splice(sectionIndex,1); + // this.findAndReplaceReferenceFormByName(this._formSchema.name,this._formSchema) + // } + + findAndReplaceReferenceFormByName(name: string, schema: Object) { + this.referencedForms.forEach((form, index) => { + if (form.name === name) { + this.referencedForms.splice(index, 1, schema); + } + }); + } + + showAlertDialog(message: string) { + this.dialogService.addDialog(AlertComponent, { + message: message + }); + } + + setRawSchema(obj) { + this.ns.setRawSchema(obj); + } + + setSchema(schema: Object) { + this.ns.setSchema(this._formSchema); + } + + ngOnDestroy() { + this.subscription.unsubscribe(); + } + + editFormName(value: any) { + + this._formSchema.name = value.formname; + this.rawSchema.name = value.formname; + this.setSchema(this._formSchema); + this.setRawSchema(this.rawSchema); + } + + showNameEditForm(name: string) { + this.formName = name; + this.schema['name'] = ''; + } + + showSpinner() { + try { + if (!_.isEmpty(this._formSchema.pages)) { + const lastPageIndex: number = this._formSchema.pages.length - 1; + if (!_.isEmpty(this._formSchema.pages[lastPageIndex].sections)) { + const lastSectionIndex = + this._formSchema.pages[lastPageIndex].sections + .indexOf(this._formSchema.pages[lastPageIndex].sections[this._formSchema.pages[lastPageIndex].sections.length - 1]); + + if (this._formSchema.pages[lastPageIndex].sections[lastSectionIndex]) { + if (this._formSchema.pages[lastPageIndex].sections[lastSectionIndex].questions) { + const lastQuestionIndex = + this._formSchema.pages[lastPageIndex].sections[lastSectionIndex] + .questions.indexOf(this._formSchema.pages[lastPageIndex].sections[lastSectionIndex] + .questions[this._formSchema.pages[lastPageIndex].sections[lastSectionIndex].questions.length - 1]); + if (this._formSchema.pages[lastPageIndex].sections[lastSectionIndex].questions[lastQuestionIndex] === this.schema) { + this.fs.setLoaded(true); + } + } + } else { + this.fs.setLoaded(true); + } + } else { + this.fs.setLoaded(true); + } + + } else { + this.fs.setLoaded(true); + } + } catch (e) { + console.error(e); + } + } + + IsPageReferenced(pageIndex) { + let isReferenced = false; + if (!this.rawSchema.pages[pageIndex]) { + if (!this.rawSchema.pages[pageIndex].label) { + isReferenced = true; + } + + } + return isReferenced; + } + + IsSectionReferenced(pageIndex, sectionIndex) { + let isReferenced = false; + if (this.selectMode) { + return false; + } + try { + if (this.rawSchema.pages[pageIndex].label) { + if (!this.rawSchema.pages[pageIndex].sections[sectionIndex].label) { + isReferenced = true; + } + } else { + isReferenced = true; + } + + } catch (e) { + console.log(pageIndex, sectionIndex); + } + return isReferenced; + } + + IsSectionOnlyReferenced(pageIndex, sectionIndex) { + let result = false; + let section: any = {}; + try { + if (this.rawSchema.pages[pageIndex].label) { + section = this.rawSchema.pages[pageIndex].sections[sectionIndex]; + if (section.reference) { result = true; } else { + result = true; + } + } + } catch (e) { + console.log(pageIndex, sectionIndex); + } + + return result; + } + + + editReferenceSection(pageIndex, sectionIndex: any) { + let section = this.rawSchema.pages[pageIndex].sections[sectionIndex]; + this.ns.setPrechecked(section.reference.section); + _.forEach(this.rawSchema.referencedForms, (form: any) => { + if (_.isEqual(section.reference.form, form.alias)) { + this.fs.fetchFormMetadata(form.ref.uuid, true).then((metadata) => { + this.fs.fetchForm(metadata.resources[0].valueReference, true).then((schema) => { + this.subscription = this.dialogService.addDialog(NavigatorModalComponent, { + title: `Edit Referenced Section`, + schema: schema, + referenceElement: 'section' + }, { + backdropColor: 'rgba(0, 0, 0, 0.5)' + }) + .subscribe((res) => { + console.log(typeof(res)); + if (res) this.createRefSections({ + form: form.alias, + Sections: res + }, pageIndex);}); + }); + }); + } + }); + + + + + } + + + excludeQuestionFromReferencedSection(pageIndex, sectionIndex, k, questionId) { + this._formSchema.pages[pageIndex].sections[sectionIndex].questions.splice(k, 1); + let section = this.rawSchema.pages[pageIndex].sections[sectionIndex]; + let newSection = ''; + if (this.isSectionCustomized(section)) { + this.rawSchema.pages[pageIndex].sections[sectionIndex].excludeQuestions.push(questionId); + } else { + + section['reference']['excludeQuestions'] = [questionId]; + this.rawSchema.pages[pageIndex].sections[sectionIndex] = section; + } + this.setRawSchema(this.rawSchema); + this.setSchema(this._formSchema); + } + + isSectionCustomized(section) { + let isCustomized: boolean = false; + if (section.excludeQuestions) { + isCustomized = true; + } + return isCustomized; + } + + + + checkMode(pageIndex: number, sections: any[]): boolean { + + let result: boolean = false; + + if (this.editMode || this.selectMode) { + result = true; + } + + if (this.updateMode) { + + if (this.IsPageReferenced(pageIndex)){ + if (this.rawSchema.pages[pageIndex].reference.form === this.alias){ + return true; } + } + + if (!_.isEmpty(sections)) { + _.each(sections, (section) => { + if (!section.label) { + if (section.reference.form === this.alias) { + result = true; + }}});}} + return result; + } + + IsSectionReferencedFromComponent(pageIndex, sectionIndex): boolean { + + let results = false; + if (this.editMode || this.selectMode) { + results = true; + } else if (this.IsPageReferenced(pageIndex)) { + return true; + } else if (this.updateMode) { + if (this.IsSectionReferenced(pageIndex, sectionIndex)) { + if (this.rawSchema.pages[pageIndex].sections[sectionIndex].reference.form === this.alias) { + results = true; + } + } + } + + return results; + } + + pageMoved($event, toIndex) { + const fromIndex = $event.dragData.pageIndex; + const schema = _.cloneDeep(this._formSchema); + const rawSchema = _.cloneDeep(this.rawSchema); + this._formSchema.pages = this.moveElementInArray(schema.pages, fromIndex, toIndex); + this.rawSchema.pages = this.moveElementInArray(rawSchema.pages, fromIndex, toIndex); + console.log(rawSchema, schema); + this.setRawSchema(this.rawSchema); + this.setSchema(this._formSchema); + } + + sectionMoved($event, toPageIndex, toSectionIndex) { + const fromPageIndex = $event.dragData.pageIndex; + const fromSectionIndex = $event.dragData.sectionIndex; + const section = $event.dragData.schema; + const schema = _.cloneDeep(this._formSchema); + const rawSchema = _.cloneDeep(this.rawSchema); + schema.pages[fromPageIndex].sections.splice(fromSectionIndex, 1); + schema.pages[toPageIndex].sections.splice(toSectionIndex, 0, section); + + rawSchema.pages[fromPageIndex].sections.splice(fromSectionIndex, 1); + rawSchema.pages[toPageIndex].sections.splice(toSectionIndex, 0, section); + + + this.rawSchema = rawSchema; + this._formSchema = schema; + this.setSchema(this._formSchema); + this.setRawSchema(this.rawSchema); + + } + + + questionMoved($event, toPageIndex, toSectionIndex, toQuestionIndex) { + const fromPageIndex = $event.dragData.pageIndex; + const fromSectionIndex = $event.dragData.sectionIndex; + const fromQuestionIndex = $event.dragData.questionIndex; + const question = $event.dragData.schema; + const schema = _.cloneDeep(this._formSchema); + const rawSchema = _.cloneDeep(this.rawSchema); + + schema.pages[fromPageIndex].sections[fromSectionIndex].questions.splice(fromQuestionIndex, 1); + schema.pages[toPageIndex].sections[toSectionIndex].questions.splice(toQuestionIndex, 0, question); + + rawSchema.pages[fromPageIndex].sections[fromSectionIndex].questions.splice(fromQuestionIndex, 1); + rawSchema.pages[toPageIndex].sections[toSectionIndex].questions.splice(toQuestionIndex, 0, question); + + + this.rawSchema = rawSchema; + this._formSchema = schema; + + this.setSchema(this._formSchema); + this.setRawSchema(this.rawSchema); + } + + + moveElementInArray(array: any[], fromIndex: number, toIndex: number): any[] { + array.splice(toIndex, 0, array.splice(fromIndex, 1)[0]); + return array; + } + + + } + diff --git a/src/app/modals/alert.component.ts b/src/app/modals/alert.component.ts index de0f228..1d00720 100644 --- a/src/app/modals/alert.component.ts +++ b/src/app/modals/alert.component.ts @@ -20,7 +20,11 @@ export interface AlertModel {
`, - styles: [`.msg{white-space: pre}`] + + styles: [`.msg{ + white-space: pre-line; + }`] + }) export class AlertComponent extends DialogComponent implements AlertModel { message: string; diff --git a/src/app/pipes/search-form-filter.pipe.ts b/src/app/pipes/search-form-filter.pipe.ts index dea7229..21371fa 100644 --- a/src/app/pipes/search-form-filter.pipe.ts +++ b/src/app/pipes/search-form-filter.pipe.ts @@ -13,8 +13,6 @@ export class SearchFormFilterPipe implements PipeTransform { return _.filter(forms, (form) => _.includes(form['name'].toLowerCase(), value)); } else if (_.isEqual(filter, 'published')) { return _.filter(forms, (form) => _.includes(form['name'].toLowerCase(), value) && form['published'] === true); - } else if (_.isEqual(filter, 'version')) { - return _.filter(forms, (form) => _.includes(form['name'].toLowerCase(), value)); } } } diff --git a/src/app/view-forms/view-forms.component.css b/src/app/view-forms/view-forms.component.css index 9ccc6cd..163c49f 100644 --- a/src/app/view-forms/view-forms.component.css +++ b/src/app/view-forms/view-forms.component.css @@ -82,9 +82,7 @@ border:0; background:transparent; } -.material-icons.edit{ - color:green; -} + .navbar-btn{ margin: 5px 5px 0px 5px; } @@ -142,4 +140,8 @@ md-card{ } .dropdown-menu>li { margin-left:5px; -} \ No newline at end of file +} +.material-icons.delete{ + color: maroon; +} + diff --git a/src/app/view-forms/view-forms.component.html b/src/app/view-forms/view-forms.component.html index fd3a5c6..0da9f87 100644 --- a/src/app/view-forms/view-forms.component.html +++ b/src/app/view-forms/view-forms.component.html @@ -1,6 +1,8 @@ - Form Builder + + Forms Manager + @@ -68,7 +70,9 @@
@@ -82,12 +86,13 @@ - +
- - - + + + + @@ -99,11 +104,13 @@ {{form.name}} - - diff --git a/src/app/view-forms/view-forms.component.ts b/src/app/view-forms/view-forms.component.ts index 25248b6..ad5e533 100644 --- a/src/app/view-forms/view-forms.component.ts +++ b/src/app/view-forms/view-forms.component.ts @@ -8,8 +8,11 @@ import { Router } from '@angular/router'; import { Constants } from '../Services/constants'; import { FormListService } from '../Services/form-list.service'; import { Subscription } from 'rxjs/Subscription'; +import { SaveFormService } from '../Services/save-form.service'; import * as _ from 'lodash'; import { saveAs } from 'file-saver/FileSaver'; +import { DialogService } from 'ng2-bootstrap-modal'; +import { ConfirmComponent } from '../modals/confirm.component'; @Component({ selector: 'app-view-forms', @@ -39,7 +42,11 @@ export class ViewFormsComponent implements OnInit { private fetchFormDetailService: FetchFormDetailService, private auth: AuthenticationService, private ls: LocalStorageService, - private formListService: FormListService) { + + private formListService: FormListService, + private saveFormService: SaveFormService, + private dialogService: DialogService) { + const user = sessionStorageService.getObject('user'); this.username = user.username; @@ -60,8 +67,9 @@ export class ViewFormsComponent implements OnInit { f.forEach((form, index) => { this.fetchFormDetailService.fetchFormMetadata(form.uuid,false).then(res => { - if (!form.resources[0] || form.resources.length === 0) {this.formsWithoutSchemas.push(form.name); } else { - this.POCForms.push(form); } + console.log(form); + this.POCForms.push(form); + }); }); this.POCForms = _.cloneDeep(f); @@ -173,9 +181,6 @@ export class ViewFormsComponent implements OnInit { } }); - - - } addSchema(form) { @@ -191,6 +196,54 @@ export class ViewFormsComponent implements OnInit { }); } + retire(uuid: string,form: any) { + this.saveFormService.retire(uuid).subscribe((res) => form.retired = true); + } + + unretire(uuid: string,form: any) { + this.saveFormService.unretire(uuid).subscribe((res) => form.retired = false); + } + + publish(uuid: string, form: any) { + console.log(form); + this.subscription = this.fetchAllFormsService.getPOCSameFormsDifferentVersions(form) + .subscribe((forms) => { + console.log(forms); + const publishedForm = this.fetchAllFormsService.getLatestPublishedVersion(forms, form.uuid); + if (!_.isEmpty(publishedForm)) { + const dialogOptions = { + title: 'Confirm publish', + message: `Version ${publishedForm.version} of this form published. + Would you like to unpublish that version and publish this one?`, + buttonText: 'Publish' + }; + this.dialogService.addDialog(ConfirmComponent, dialogOptions, { backdropColor: 'rgba(0,0,0,0.5)'}) + .subscribe((isConfirmed) => { + if (isConfirmed) { + this.saveFormService.unpublish(publishedForm.uuid) + .subscribe((res) => { + this.saveFormService.publish(form.uuid).subscribe( (ress) => { + form.published = true; + }); + }); + }}); + } else { + this.saveFormService.publish(form.uuid).subscribe( (ress) => { + form.published = true; + }); + }}); + } + unpublish(uuid: string, form: any) { + this.saveFormService.unpublish(uuid).subscribe((res) => form.published = false); + } + filterEvent($event: any) { + if ($event.target.checked) { + this.searchFilter = 'published'; + } + if (!$event.target.checked) { + this.searchFilter = undefined; + } + } } diff --git a/src/assets/fav b/src/assets/fav new file mode 100644 index 0000000..5b27cca Binary files /dev/null and b/src/assets/fav differ diff --git a/src/assets/loader.gif b/src/assets/loader.gif index 05843a2..edb17a6 100644 Binary files a/src/assets/loader.gif and b/src/assets/loader.gif differ diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 910b0df..8f1ae25 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -6,6 +6,6 @@ export const environment = { production: false, - date: '1510644978049', + date: '1512388877847', version: '1.1-alpha' }; diff --git a/src/index.html b/src/index.html index 92f4df1..a8ca160 100644 --- a/src/index.html +++ b/src/index.html @@ -9,7 +9,6 @@ -
NameVersionPublishedNameVersionPublishedRetired Actions
{{form.version}} - + + + - + + + @@ -115,9 +122,23 @@ mode_edit + + + speaker_notes + + + speaker_notes_off + get_app + + delete + + + restore + +