Merge "[CORD-1792] modifier key detection"
diff --git a/src/app/core/confirm/confirm.service.spec.ts b/src/app/core/confirm/confirm.service.spec.ts
index 84a61de..d05899d 100644
--- a/src/app/core/confirm/confirm.service.spec.ts
+++ b/src/app/core/confirm/confirm.service.spec.ts
@@ -23,6 +23,8 @@
 let service: IXosConfirm;
 let modal;
 let modalInstance;
+let q;
+let scope;
 
 describe('The XosConfirm service', () => {
 
@@ -33,10 +35,14 @@
 
     angular.mock.inject((
       XosConfirm: IXosConfirm,
-      $uibModal: any
+      $uibModal: any,
+      $q: ng.IQService,
+      $rootScope: ng.IScope
     ) => {
       service = XosConfirm;
       modal = $uibModal;
+      q = $q;
+      scope = $rootScope;
     });
   });
 
@@ -54,19 +60,31 @@
         }]
       };
 
-    it('should open a modal', () => {
-      spyOn(modal, 'open');
+    it('should open the modal', () => {
+      spyOn(modal, 'open').and.returnValue('fake');
       modalInstance = service.open(test1);
       expect(modal.open).toHaveBeenCalled();
+      expect(modalInstance).toEqual('fake');
+      expect(service.modalInstance).toEqual('fake');
     });
-  });
 
-  // describe('the close method', () => {
-  //
-  // });
-  //
-  // describe('the dismiss method', () => {
-  //
-  // });
+    it('should close the modal', (done) => {
+      const p = q.defer();
+      const cb = jasmine.createSpy('cb').and.returnValue(p.promise);
+      service.modalInstance = {
+        close: jasmine.createSpy('close')
+      };
+
+      service.close(cb);
+      expect(cb).toHaveBeenCalled();
+      p.resolve();
+      scope.$apply();
+      expect(service.modalInstance.close).toHaveBeenCalled();
+      done();
+    });
+
+
+
+  });
 
 });
diff --git a/src/app/core/confirm/confirm.service.ts b/src/app/core/confirm/confirm.service.ts
index a8e802e..39336e3 100644
--- a/src/app/core/confirm/confirm.service.ts
+++ b/src/app/core/confirm/confirm.service.ts
@@ -18,36 +18,44 @@
 import {IXosConfirmConfig} from './confirm';
 
 export interface IXosConfirm {
+  modalInstance: any;
   open(config: IXosConfirmConfig) : void;
-  close(cb: Function) : void;
+  close(cb: any) : void;
   dismiss() : void;
 }
 
 export class XosConfirm implements IXosConfirm {
 
-  static $inject = ['$uibModal'];
+  static $inject = ['$uibModal', '$log'];
   public modalInstance;
 
   constructor(
     private $uibModal : any,
+    private $log: ng.ILogService,
   ) {
 
   }
 
   public open(config: IXosConfirmConfig) {
-
+    this.$log.debug('[XosConfirm] called open');
     this.modalInstance = this.$uibModal.open({
-      keyboard: false,
+      keyboard: true,
       component: 'xosConfirm',
       backdrop: 'static',
       resolve: {
         config: () => config
       }
     });
+
     return this.modalInstance;
   }
 
-  public close(cb: Function) {
+  public close(cb: any) {
+    // check if model instance exists
+    if (angular.isUndefined(this.modalInstance)) {
+      this.$log.debug('[XosConfirm] called close without a modalInstance');
+      return;
+    }
     cb()
       .then(() => {
         this.modalInstance.close();
diff --git a/src/app/core/services/helpers/config.helpers.ts b/src/app/core/services/helpers/config.helpers.ts
index e4a0a70..f566e7a 100644
--- a/src/app/core/services/helpers/config.helpers.ts
+++ b/src/app/core/services/helpers/config.helpers.ts
@@ -153,6 +153,7 @@
           color: 'red',
           cb: (item) => {
             let obj = angular.copy(item);
+            const objName = (angular.isUndefined(obj.name)) ? 'instance' : obj.name;
 
             item.$delete()
               .then((res) => {
@@ -160,10 +161,10 @@
                   // TODO understand why it does not go directly in catch
                   throw new Error();
                 }
-                this.toastr.info(`${model.name} ${obj.name} succesfully deleted`);
+                this.toastr.info(`${model.name} ${objName} successfully deleted`);
               })
               .catch(() => {
-                this.toastr.error(`Error while deleting ${obj.name}`);
+                this.toastr.error(`Error while deleting ${objName}`);
               });
           }
         }
@@ -303,7 +304,7 @@
         return;
       }
 
-      const model = angular.copy(item);
+      const itemCopy = angular.copy(item);
 
       // TODO remove ManyToMany relations and save them separately (how??)
       delete item.networks;
@@ -315,24 +316,26 @@
         }
       });
 
+      const itemName = (angular.isUndefined(itemCopy.name)) ? model.name : itemCopy.name;
+
       item.$save()
         .then((res) => {
           formCfg.feedback = {
             show: true,
-            message: `${model.name} succesfully saved`,
+            message: `${itemName} successfully saved`,
             type: 'success',
             closeBtn: true
           };
-          this.toastr.success(`${model.name} succesfully saved`);
+          this.toastr.success(`${itemName} successfully saved`);
         })
         .catch(err => {
           formCfg.feedback = {
             show: true,
-            message: `Error while saving ${model.name}: ${err.error}. ${err.specific_error || ''}`,
+            message: `Error while saving ${itemName}: ${err.error}. ${err.specific_error || ''}`,
             type: 'danger',
             closeBtn: true
           };
-          this.toastr.error(err.specific_error || '', `Error while saving ${model.name}: ${err.error}`);
+          this.toastr.error(err.specific_error || '', `Error while saving ${itemName}: ${err.error}`);
         });
     };
 
diff --git a/src/app/core/side-panel/side-panel.scss b/src/app/core/side-panel/side-panel.scss
index a6c718b..46e84ff 100644
--- a/src/app/core/side-panel/side-panel.scss
+++ b/src/app/core/side-panel/side-panel.scss
@@ -31,7 +31,7 @@
     width: $side-panel-width;
     height: 100%;
     position: fixed;
-    z-index: 9999;
+    z-index: 1049;
     top: 0;
     right: -$side-panel-width;
     background: $background-dark-color;
diff --git a/src/app/core/side-panel/side-panel.ts b/src/app/core/side-panel/side-panel.ts
index 9b2b78f..ba1f5b0 100644
--- a/src/app/core/side-panel/side-panel.ts
+++ b/src/app/core/side-panel/side-panel.ts
@@ -39,5 +39,5 @@
 export const xosSidePanel: angular.IComponentOptions = {
   template: require('./side-panel.html'),
   controllerAs: 'vm',
-  controller: XosSidePanelController
+  controller: XosSidePanelController,
 };