CHANGE edit enumeration, bits and boolean values

instead of letting user type new value into an input box, let him
choose from valid values
diff --git a/frontend/config/modifications.service.ts b/frontend/config/modifications.service.ts
index 21e497d..db2fda0 100644
--- a/frontend/config/modifications.service.ts
+++ b/frontend/config/modifications.service.ts
@@ -64,12 +64,32 @@
         }
     }
 
-    setEdit(node, set = true) {
+    setEdit(activeSession, node, set = true) {
+        let waiting = false;
         if (set && node['info']['datatypebase'] == 'empty') {
             node['value'] = '';
             return;
         }
-        node['edit'] = set;
+        if (set && !('values' in node['info'])) {
+            switch (node['info']['datatypebase']) {
+            case 'bits':
+            case 'enumeration':
+                waiting = true;
+                this.sessionsService.schemaValues(activeSession.key, node['info']['path']).then(result => {
+                    if (result['success']) {
+                        node['info']['values'] = result['data'];
+                    }
+                    node['edit'] = set;
+                });
+                break;
+            case 'boolean':
+                node['info']['values'] = ['true', 'false'];
+                break;
+            }
+        }
+        if (!waiting) {
+            node['edit'] = set;
+        }
     }
 
     setLast(list) {
@@ -89,7 +109,7 @@
         let match = false;
         let parent = null;
         let children = activeSession.data['children'];
-        let newChildren;
+        let newChildren = activeSession.data['newChildren'];
 
         while (children || newChildren) {
             match = false;
@@ -210,7 +230,7 @@
                 /* new record */
                 if (node['value'] == leafValue) {
                     /* no change to the original value */
-                    this.setEdit(node, false);
+                    this.setEdit(activeSession, node, false);
                     this.removeModificationsRecord(activeSession);
                     return;
                 }
@@ -232,7 +252,7 @@
         }
 
         node['value'] = leafValue;
-        this.setEdit(node, false);
+        this.setEdit(activeSession, node, false);
     }
 
     createOpen(schemas, node) {
@@ -287,7 +307,7 @@
         }
 
         switch(newNode['info']['type']) {
-        case 1: { /* container */
+        case 1: /* container */
             node['schemaChildren'].splice(index, 1);
 
             newNode['children'] = [];
@@ -296,17 +316,15 @@
                 this.createOpen(result, newNode);
             });
             break;
-        }
-        case 4: { /* leaf */
+        case 4: /* leaf */
             node['schemaChildren'].splice(index, 1);
 
             if ('default' in newNode['info']) {
                 newNode['value'] = newNode['info']['default'];
             }
-            this.setEdit(newNode, true)
+            this.setEdit(activeSession, newNode, true)
             break;
-        }
-        case 16: { /* list */
+        case 16: /* list */
             let search;
             if ('new' in node) {
                 search = node['children'];
@@ -341,7 +359,7 @@
                         newKey['info'] = newNode['schemaChildren'][i];
                         newKey['path'] = newNode['path'] + '/' + this.schemaName(newNode['info'], newKey['info']);
                         newKey['dirty'] = true;
-                        this.setEdit(newKey, true)
+                        this.setEdit(activeSession, newKey, true)
                         newNode['children'].push(newKey)
                         newNode['schemaChildren'].splice(i, 1);
                     }
@@ -350,7 +368,6 @@
 
             break;
         }
-        }
 
         if (!node['schemaChildren'].length) {
             newNode['last'] = true;
diff --git a/frontend/config/sessions.service.ts b/frontend/config/sessions.service.ts
index b9e5dd2..496d0d6 100644
--- a/frontend/config/sessions.service.ts
+++ b/frontend/config/sessions.service.ts
@@ -137,6 +137,15 @@
             }).toPromise();
     }
 
+    schemaValues(key: string, path: string) {
+        let params = new URLSearchParams();
+        params.set('key', key);
+        params.set('path', path);
+        let options = new RequestOptions({ search: params });
+        return this.http.get('/netopeer/session/schema/values', options)
+            .map((resp: Response) => resp.json()).toPromise();
+    }
+
     alive(key: string): Observable<string[]> {
         let params = new URLSearchParams();
         params.set('key', key);
diff --git a/frontend/config/tree.component.html b/frontend/config/tree.component.html
index 451452a..fa9a9f2 100644
--- a/frontend/config/tree.component.html
+++ b/frontend/config/tree.component.html
@@ -99,10 +99,19 @@
 				(click)="changeValue(node, $event.target)" (keyup.enter)="changeValue(node, $event.target)"
 				onmouseover="this.src='assets/netopeer/icons/confirm_active.svg'"
 				onmouseout="this.src='assets/netopeer/icons/confirm.svg'"/>
-			<input id="{{node['path']}}_input" type="text" class="value" value="{{node['value']}}" tabindex=0
-				(keyup)="checkValue(node, $event.target)" (change)="checkValue(node, $event.target)"
-				(keyup.enter)="changeValue(node, $event.target)" (keyup.escape)="changeValueCancel(node)"
-				checkLeafValue [node]="node" (onCheckValue)="checkValue($event.node, $event.element)"/>
+            <select *ngIf="node['info']['values']"
+                id="{{node['path']}}_input" type="text" class="value"
+                (change)="checkValue(node, $event.target, true)"
+                checkLeafValue [node]="node" [trusted]="true" (onCheckValue)="checkValue($event.node, $event.element, $event.trusted)">
+                <ng-container *ngFor="let value of node['info']['values']; let i='index'">
+                    <option value="{{value}}">{{value}}</option>
+                </ng-container>
+            </select>
+            <input *ngIf="!node['info']['values']"
+                id="{{node['path']}}_input" type="text" class="value" value="{{node['value']}}" tabindex=0
+                (keyup)="checkValue(node, $event.target)" (change)="checkValue(node, $event.target)"
+                (keyup.enter)="changeValue(node, $event.target)" (keyup.escape)="changeValueCancel(node)"
+                checkLeafValue [node]="node" (onCheckValue)="checkValue($event.node, $event.element)"/>
 		</div>
 	</ng-container>
 
diff --git a/frontend/config/tree.component.ts b/frontend/config/tree.component.ts
index 2e3ad09..ef04a3b 100644
--- a/frontend/config/tree.component.ts
+++ b/frontend/config/tree.component.ts
@@ -26,6 +26,7 @@
 })
 export class CheckLeafValue {
     @Input() node;
+    @Input() trusted = false;
     @Output() onCheckValue = new EventEmitter();
 
     constructor(private elRef:ElementRef) {}
@@ -33,9 +34,10 @@
     ngAfterContentInit() {
         console.log(this.node)
         let node = this.node;
+        let trusted = this.trusted;
         let element = this.elRef.nativeElement;
         element.value = node['value'];
-        this.onCheckValue.emit({node, element});
+        this.onCheckValue.emit({node, element, trusted});
   }
 }
 
@@ -170,15 +172,26 @@
         }
         let parent = target.parentElement;
 
-        this.modsService.setEdit(node, true)
+        this.modsService.setEdit(this.activeSession, node, true)
         this.changeDetector.detectChanges();
 
         parent.nextElementSibling.lastElementChild.focus();
     }
 
-    checkValue(node, target) {
+    checkValue(node, target, trusted = false) {
         let confirm = target.previousElementSibling;
         let cancel = confirm.previousElementSibling;
+
+        if (trusted) {
+            /* value is selected from valid options */
+            target.classList.remove("invalid");
+            confirm.style.visibility = "visible";
+            if ('value' in node) {
+                cancel.style.visibility = "visible";
+            }
+            return;
+        }
+
         let path: string;
         if ('creatingChild' in node) {
             path = node['creatingChild']['path'];
@@ -204,7 +217,7 @@
 
     changeValueCancel(node) {
         if ('value' in node) {
-            this.modsService.setEdit(node, false);
+            this.modsService.setEdit(this.activeSession, node, false);
         }
     }