[sidebar][bugfix] Is now able to save new coordinates on existing organisational...
[u/erikhf/frm.git] / src / components / sidebar / sidebar.ts
1 import {Component, NgFor, NgIf, EventEmitter, NgModel, Control, ControlGroup, ControlArray, Validators, FormBuilder, CORE_DIRECTIVES,FORM_DIRECTIVES} from 'angular2/angular2';
2 import {Http, Headers} from 'angular2/http';
3
4 declare var zone: Zone;
5
6 @Component({
7     selector: 'mou-sidebar',
8     directives: [CORE_DIRECTIVES, FORM_DIRECTIVES, NgFor, NgModel, NgIf],
9     events: ['tempmarker','updateorg'],
10     templateUrl: './components/sidebar/sidebar.html'
11 })
12
13 export class Sidebar {
14
15
16     http:Http;
17     newObject: boolean;
18     editmode:boolean;
19     active: boolean;
20     coordinatePoint: boolean;
21
22     groupSets: Array<any> = [];
23     groupsDoubleArray: any[][] = [];
24
25     id: Control = new Control("");
26     name: Control = new Control("", Validators.required);
27     shortName: Control = new Control("",Validators.required);
28     description: Control = new Control("");
29     code: Control = new Control("");
30     openingDate: Control = new Control("",Validators.required);
31     closedDate: Control = new Control("");
32     url: Control = new Control("");
33     lat: Control = new Control("");
34     lng: Control = new Control("");
35     parent: Control = new Control("");
36     contactPerson: Control = new Control("");
37     address: Control = new Control("");
38     email: Control = new Control("");
39     phoneNumber: Control = new Control("");
40     exitButton: any;
41     featureType: Control = new Control("");
42     coordinates: Control = new Control("");
43     ctrlGroups: Array<Control> = [new Control('')];
44     groupsArray: ControlArray = new ControlArray(this.ctrlGroups);
45
46
47     form: ControlGroup = new ControlGroup({
48         organisationUnitGroups: this.groupsArray,
49         id: this.id,
50         name: this.name,
51         shortName: this.shortName,
52         description: this.description,
53         code: this.code,
54         openingDate: this.openingDate,
55         closedDate: this.closedDate,
56         url: this.url,
57         lat: this.lat,
58         lng: this.lng,
59         parent: this.parent,
60         contactPerson: this.contactPerson,
61         address: this.address,
62         email: this.email,
63         phoneNumber: this.phoneNumber,
64         featureType: this.featureType,
65         coordinates: this.coordinates
66     });
67
68     constructor(http:Http, fb: FormBuilder) {
69         this.http = http;
70         this.editmode = false;
71         this.active = false;
72         this.coordinatePoint = false;
73         this.tempmarker = new EventEmitter();
74         this.updateorg = new EventEmitter();
75         this.exitButton = document.getElementById("slideout")
76         let instance = this;
77
78         // listener for value change in coordinate input field
79         this.lat.valueChanges.observer({
80             next: (value) => {
81                 if(instance.lng.value && value) {
82                     let pos = {lat: value, lng: instance.lng.value};
83                     this.tempmarker.next(pos);
84                 }
85             }
86         });
87         this.lng.valueChanges.observer({
88             next: (value) => {
89                 if(instance.lat.value && value) {
90                     let pos = {lat: instance.lat.value, lng: value};
91                     this.tempmarker.next(pos);
92                 }
93             }
94         });
95
96         // find all orgUnitSets
97         this.findOrgUnitSets();
98     }
99
100     // this method is called when the sidebar should update its content with new org unit
101     update(orgunitId) {
102         this.active = true;
103         this.newObject = false;
104         this.http.get(dhisAPI + "/api/organisationUnits/" + orgunitId)
105             .map(res => res.json())
106             .subscribe(res => this.updateValues(res))
107     }
108
109     // update form values with new information from http get result
110     updateValues(res){
111
112         // update the form controls with data from incoming json object
113         for(control in this.form.controls){
114             if(this.form.controls[control] instanceof ControlArray){
115                 console.log("nothing to do here");
116             }
117             else if(res[control] !== undefined) {
118                 this.form.controls[control].updateValue(res[control]);
119             }
120             else
121                 this.form.controls[control].updateValue("");
122
123         }
124
125         // Date fix:
126         if(res["openingDate"]){
127             this.form.controls["openingDate"].updateValue((new Date(res["openingDate"].substring(0,10))).toISOString().substring(0,10));
128         }
129         if(res["closedDate"]){
130             this.form.controls["closedDate"].updateValue((new Date(res["closedDate"].substring(0,10))).toISOString().substring(0,10));
131         }
132
133         // we're only interested in coordinates if it's a featureType point. Since we want to use two different input fields for lat and lang (and the api uses a single object for both)
134         // we need to have a separate data structure for coordinates, and update them manually
135         if(res.featureType === "POINT"){
136             this.coordinatePoint = true;
137             let coord = new Object();
138             coord = JSON.parse(res["coordinates"]);
139             this.form.controls.lat.updateValue(coord[1]);
140             this.form.controls.lng.updateValue(coord[0]);
141         }
142         else{
143             this.coordinatePoint = false;
144         }
145
146         // Update organisationUnitGroups with correct values from api
147         for(var i = 0; i < this.groupsDoubleArray.length; i++){
148             for(var j = 0; j < this.groupsDoubleArray[i].length; j++){
149                 for( group in res.organisationUnitGroups){
150                     if( res.organisationUnitGroups[group].id == this.groupsDoubleArray[i][j].id ){
151                         this.form.controls.organisationUnitGroups.controls[i].updateValue(this.groupsDoubleArray[i][j].name);
152                     }
153                 }
154             }
155         }
156     }
157
158
159     // called on form submit
160     onSubmit() {
161         this.editmode = false;
162
163         let headers = new Headers();
164         headers.append('Accept', 'application/json');
165
166         headers.append('Content-Type', 'application/json');
167
168
169         let jsonObject = this.form.value;
170
171         // remove empty fields from the form object, no need to send empty values to the api
172         $.each(jsonObject, function(key, value){
173             if (value === "" || value === null){
174                 delete jsonObject[key];
175             }
176         });
177
178         // we were unable to find a way to associate a new (or existing) organisation unit with one or more organisationUnitGroups, so we're removing the data before posting to API
179         $.each(jsonObject.organisationUnitGroups, function(key, value){
180 //            if( value === "" || value === null){
181                 delete jsonObject.organisationUnitGroups[key];
182   //          } else {
183   //              jsonObject.organisationUnitGroups[key].id = value;
184    //         }
185         });
186
187
188         jsonObject.openingDate = (new Date(this.form.value.openingDate)).toISOString();
189
190         if(this.form.value.closedDate){
191             jsonObject.closedDate = (new Date(this.form.value.closedDate)).toISOString();
192         }
193
194         if(this.coordinatePoint){
195             jsonObject.featureType="POINT";
196             jsonObject.coordinates="[" + this.form.controls.lng.value + ","+this.form.controls.lat.value+"]";
197         }
198
199         // POST if the object is new, PUT if it's an update to an existing orgUnit
200         if (this.newObject) {
201             jsonObject.parent = {};
202             jsonObject.parent.id = this.form.controls.parent.value;
203
204             delete jsonObject["lat"];
205             delete jsonObject["lng"];
206             this.http.post(dhisAPI + "/api/organisationUnits/", JSON.stringify(jsonObject), {
207                     headers: headers
208                 })
209                 .map(res => res.json())
210                 .subscribe(res => this.emitNewUpdatedObject(res));
211         }else {
212             this.http.put(dhisAPI + "/api/organisationUnits/" + this.form.controls.id.value, JSON.stringify(jsonObject), {
213                     headers: headers
214                 })
215                 .map(res => res.json())
216                 .subscribe(res => console.log(res));
217         }
218
219
220
221
222     }
223
224     emitNewUpdatedObject(obj){
225         console.log(obj);
226         this.updateorg.next(obj.response.lastImported);
227     }
228
229     cancel(){
230         this.editmode = false;
231         this.tempmarker.next(null);
232     }
233
234
235     add(data){
236         this.coordinatePoint = true;
237         this.newObject=true;
238         this.active = true;
239         this.editmode = true;
240
241         for(control in this.form.controls){
242             if(!(this.form.controls[control] instanceof ControlArray))
243                 this.form.controls[control].updateValue("");
244         }
245
246         this.form.controls.lat.updateValue(data.location.lat);
247         this.form.controls.lng.updateValue(data.location.lng);
248         this.form.controls.parent.updateValue(data.parent);
249
250     }
251
252     exit(){
253         this.active = false;
254     }
255
256     findOrgUnitSets(){
257         let instance = this;
258         this.http.get(dhisAPI + "/api/organisationUnitGroupSets?paging=false")
259             .map(res => res.json())
260             .map(res => res.organisationUnitGroupSets)
261             .subscribe(res => this.addOrgUnitSets(instance, res))
262     }
263
264     addOrgUnitSets(instance, res){
265         //delete instance.ctrlGroups[0];
266         for( group in res){
267             console.log(instance.form.controls);
268             instance.groupsArray.push(new Control(''));
269             instance.groupSets.push(res[group]);
270
271             this.http.get(dhisAPI + "/api/organisationUnitGroupSets/" + res[group].id)
272                 .map(res => res.json())
273                 .map(res => res.organisationUnitGroups)
274                 .subscribe(res => this.addOrgUnitGroup(instance, res))
275
276             //    instance.form.push(new Control(""));
277         }
278         console.log(instance.groupSets);
279     }
280
281     addOrgUnitGroup(instance, res){
282         let ar: Array<any> = [];
283         for( group in res){
284             ar.push(res[group]);
285         }
286         instance.groupsDoubleArray.push(ar);
287
288         console.log(instance.groupsDoubleArray);
289     }
290 }
291