KNOX-1040: Added visual indicator that a provider config has not been removed 
because it is referenced, and improved editable fields


Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/9f666c39
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/9f666c39
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/9f666c39

Branch: refs/heads/master
Commit: 9f666c391ebf5b88496bd1bf2556b8a15b86ca04
Parents: 886f76e
Author: Phil Zampino <pzamp...@apache.org>
Authored: Mon Feb 12 14:11:16 2018 -0500
Committer: Phil Zampino <pzamp...@apache.org>
Committed: Tue Feb 13 16:17:33 2018 -0500

----------------------------------------------------------------------
 .../src/app/resource-detail/descriptor.ts       |  12 +-
 .../resource-detail.component.css               |  62 +++++++++
 .../resource-detail.component.html              | 127 +++++++++----------
 .../resource-detail.component.ts                |  54 ++------
 .../applications/admin-ui/app/index.html        |   2 +-
 .../app/inline.2f727e6f73f32920fc6d.bundle.js   |   1 -
 .../app/inline.c33f88beae0a6c65f63f.bundle.js   |   1 +
 .../app/main.3323b90a117ac8faffa1.bundle.js     |   1 -
 .../app/main.e8ac70095627bac846b5.bundle.js     |   1 +
 9 files changed, 142 insertions(+), 119 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/knox/blob/9f666c39/gateway-admin-ui/src/app/resource-detail/descriptor.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resource-detail/descriptor.ts 
b/gateway-admin-ui/src/app/resource-detail/descriptor.ts
index 433c33b..090e84a 100644
--- a/gateway-admin-ui/src/app/resource-detail/descriptor.ts
+++ b/gateway-admin-ui/src/app/resource-detail/descriptor.ts
@@ -27,18 +27,12 @@ export class Descriptor {
 
     private dirty: boolean = false;
 
-    getServiceParamKeys(service: Service): string[] {
-        let result = [];
-        for(let key in service.params){
-            if (service.params.hasOwnProperty(key)){
-                result.push(key);
-            }
-        }
-        return result;
+    getServiceParamNames(service: Service): string[] {
+      return Object.getOwnPropertyNames(service.params);
     }
 
     getServiceParamValue(service: Service, name: string): string {
-       return  service.params[name];
+       return service.params[name];
     }
 
     setProviderConfig(providerConfigRef: string) {

http://git-wip-us.apache.org/repos/asf/knox/blob/9f666c39/gateway-admin-ui/src/app/resource-detail/resource-detail.component.css
----------------------------------------------------------------------
diff --git 
a/gateway-admin-ui/src/app/resource-detail/resource-detail.component.css 
b/gateway-admin-ui/src/app/resource-detail/resource-detail.component.css
index e69de29..7273b31 100644
--- a/gateway-admin-ui/src/app/resource-detail/resource-detail.component.css
+++ b/gateway-admin-ui/src/app/resource-detail/resource-detail.component.css
@@ -0,0 +1,62 @@
+.inline-editable {
+    text-decoration: none;
+    cursor: pointer;
+    line-height: 1;
+    margin: 0;
+}
+
+.inline-editable.editable-empty{
+    display: inline-block;
+    width: 50px;
+    line-height: 1;
+}
+
+.inline-editable:hover {
+    padding: 0px;
+}
+.inline-editable:hover:after {
+    font-family: 'Glyphicons Halflings';
+    content: "\270f";
+    position: relative;
+    left: 10px;
+}
+
+.inline-editable.editable-empty,
+.inline-editable.editable-empty:hover,
+.inline-editable.editable-empty:focus {
+    font-style: italic;
+    text-decoration: none;
+}
+
+.inline-editor.inlineEditForm {
+    display: inline-block;
+    white-space: nowrap;
+}
+
+#inlineEditWrapper {
+    display: inline-block;
+}
+
+.inline-editor.inlineEditForm input,
+.inline-editor.select {
+    width: auto;
+    display: inline;
+    border-radius: 5px;
+}
+
+.inline-editor.inline-editable-button-group {
+    display: inline-block;
+}
+
+.inline-editor.editInvalid {
+    color: #a94442;
+    margin-bottom: 0;
+}
+
+.inline-editor.error {
+    border-color: #a94442;
+}
+
+[hidden].inline-editor {
+    display: none;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/9f666c39/gateway-admin-ui/src/app/resource-detail/resource-detail.component.html
----------------------------------------------------------------------
diff --git 
a/gateway-admin-ui/src/app/resource-detail/resource-detail.component.html 
b/gateway-admin-ui/src/app/resource-detail/resource-detail.component.html
index b1d919b..4c1ebd8 100644
--- a/gateway-admin-ui/src/app/resource-detail/resource-detail.component.html
+++ b/gateway-admin-ui/src/app/resource-detail/resource-detail.component.html
@@ -8,47 +8,53 @@
   <!-- Provider Configuration Details -->
   <div class="panel-body" *ngIf="hasSelectedResource() && resourceType === 
'Provider Configurations'">
     <div *ngIf="hasSelectedResource()">
+      <div *ngIf="referencedProviderConfigError" class="alert alert-warning 
alert-dismissible" role="alert">
+        <button type="button" class="close" data-dismiss="alert" 
aria-label="Close" (click)="referencedProviderConfigError=false">
+          <span aria-hidden="true">&times;</span>
+        </button>
+        Cannot remove 
<strong>{{resourceService.getResourceDisplayName(resource)}}</strong> because 
it is referenced by one or more descriptors
+      </div>
       <div class="panel panel-default" *ngFor="let provider of providers">
         <span [class]="'clickable glyhpicon glyphicon-' + 
(isShowProvider(provider) ? 'minus' : 'plus')"
               (click)="toggleShowProvider(provider)"></span>
-        <span><b>{{ provider.name }}</b></span>
+        <span><strong>{{ provider.name }}</strong></span>
         <span class="clickable glyphicon glyphicon-remove pull-right btn 
btn-xs"
               [title]="'Remove ' + provider.name"
               (click)="onRemoveProvider(provider.name)"
               data-toggle="tooltip"></span>
         <div *ngIf="isShowProvider(provider)">
-          &nbsp;&nbsp;&nbsp;<b>Role</b> {{ provider.role }}<br>
-          &nbsp;&nbsp;&nbsp;<b>Enabled</b>&nbsp;<input type="checkbox"
+          &nbsp;&nbsp;&nbsp;<strong>Role</strong> {{ provider.role }}<br>
+          &nbsp;&nbsp;&nbsp;<strong>Enabled</strong>&nbsp;<input 
type="checkbox"
                                                        
[checked]="isProviderEnabled(provider)"
                                                        
(click)="onProviderEnabled(provider)"><br>
           <div>
             <span>&nbsp;&nbsp;&nbsp;</span>
             <span [class]="'clickable glyhpicon glyphicon-' + 
(isShowProviderParams(provider) ? 'minus' : 'plus')"
                   (click)="toggleShowProviderParams(provider)"></span>
-            <span><b>Params</b></span>
+            <span><strong>Params</strong></span>
             <span class="clickable glyphicon glyphicon-plus-sign btn btn-xs 
pull-right" data-toggle="tooltip" title="Add Param"></span>
 
             <div class="panel panel-default table-responsive" 
*ngIf="isShowProviderParams(provider)">
               <table class="table table-sm">
-                <tr *ngFor="let key of getParamKeys(provider)">
+                <tr *ngFor="let paramName of getProviderParamNames(provider)">
                   <td>
                     <span class="clickable glyphicon glyphicon-remove btn 
btn-xs"
                           title="Remove Param"
-                          (click)="onRemoveProviderParam(provider, key)"
+                          (click)="onRemoveProviderParam(provider, paramName)"
                           data-toggle="tooltip"></span>
                   </td>
-                  <td><b>{{ key }}</b></td>
+                  <td><strong>{{ paramName }}</strong></td>
                   <td>
-                    <span class="clickable"
-                          (click)="setProviderParamEditFlag(provider, key, 
true)"
-                          *ngIf="!getProviderParamEditFlag(provider, 
key)">{{provider.params[key]}}</span>
-                    <span *ngIf="getProviderParamEditFlag(provider, key)">
-                      <input type="text" [ngModel]="provider.params[key]" 
id="{{provider.name}}{{key}}Value">
+                    <span class="inline-editable"
+                          (click)="setProviderParamEditFlag(provider, 
paramName, true)"
+                          *ngIf="!getProviderParamEditFlag(provider, 
paramName)">{{provider.params[paramName]}}</span>
+                    <span *ngIf="getProviderParamEditFlag(provider, 
paramName)" class="inline-editor inlineEditForm">
+                      <input type="text" size="30" 
[(ngModel)]="provider.params[paramName]">
                       <button class="btn btn-xs"
-                              (click)="setProviderParamEditFlag(provider, key, 
false);onUpdateProviderConfigParam(provider, key, 
getInputElementValue(provider.name+key+'Value'))">
+                              (click)="setProviderParamEditFlag(provider, 
paramName, false);changedProviders=providers">
                         <span class="glyphicon glyphicon-ok"></span>
                       </button>
-                      <button class="btn btn-xs" 
(click)="setProviderParamEditFlag(provider, key, false)">
+                      <button class="btn btn-xs" 
(click)="setProviderParamEditFlag(provider, paramName, false)">
                         <span class="glyphicon glyphicon-remove"></span>
                       </button>
                     </span>
@@ -99,12 +105,11 @@
       <div>
         <div class="panel panel-default col-md-12">
           <span class="col-md-12 pull-left">
-            <span class="col-md-sm"><b>Provider Configuration</b>&nbsp;</span>
-            <span class="col-md-sm clickable" (click)="editModePC=true" 
*ngIf="!editModePC">{{ descriptor.providerConfig}}</span>
-            <span class="col-md-sm" *ngIf="editModePC">
-              <input type="text" [(ngModel)]="descriptor.providerConfig" 
#providerConfig>
-              <button class="btn btn-xs"
-                      
(click)="editModePC=false;onUpdateDescriptorProperty('providerConfig', 
providerConfig.value)">
+            <span class="col-md-sm"><strong>Provider 
Configuration</strong>&nbsp;</span>
+            <span class="col-md-sm inline-editable" (click)="editModePC=true" 
*ngIf="!editModePC">{{ descriptor.providerConfig}}</span>
+            <span class="col-md-sm inline-editor inlineEditForm" 
*ngIf="editModePC">
+              <input type="text" size="40" 
[(ngModel)]="descriptor.providerConfig">
+              <button class="btn btn-xs" 
(click)="editModePC=false;descriptor.setDirty()">
                 <span class="glyphicon glyphicon-ok"></span>
               </button>
               <button class="btn btn-xs" (click)="editModePC=false">
@@ -131,14 +136,14 @@
       <div class="panel panel-default col-md-12">
         <span [class]="'clickable glyhpicon glyphicon-' + (isShowServices() ? 
'minus' : 'plus')"
               (click)="toggleShowServices()"></span>
-        <span><b>Services</b></span>
+        <span><strong>Services</strong></span>
         <span class="clickable glyphicon glyphicon-plus-sign btn btn-xs 
pull-right" data-toggle="tooltip" title="Add Service"></span>
       <div class="col-md-12 table-responsive" *ngIf="isShowServices()">
         <table class="table table-striped table-sm">
           <tr *ngFor="let service of descriptor.services">
             <td>
               <div>
-                <span><b>{{ service.name }}</b></span>
+                <span><strong>{{ service.name }}</strong></span>
                 <span class="clickable glyphicon glyphicon-remove btn btn-xs 
pull-right"
                       [title]="'Remove ' + service.name"
                       (click)="onRemoveDescriptorService(service.name)"
@@ -150,23 +155,22 @@
                 <span>Params</span><span>&nbsp;</span><span class="glyphicon 
glyphicon-plus-sign btn btn-xs" data-toggle="tooltip" title="Add param"></span>
               </div>
               <div class="table-responsive" 
*ngIf="isShowServiceParams(service)">
-                <table class="table table-sm" 
*ngIf="descriptor.getServiceParamKeys(service).length > 0">
-                  <tr *ngFor="let paramKey of 
descriptor.getServiceParamKeys(service)">
+                <table class="table table-sm" 
*ngIf="descriptor.getServiceParamNames(service).length > 0">
+                  <tr *ngFor="let paramKey of 
descriptor.getServiceParamNames(service)">
                     <td width="5%">
                       <span class="clickable glyphicon glyphicon-remove btn 
btn-xs"
                             title="Remove Param"
                             
(click)="onRemoveDescriptorServiceParam(service.name, paramKey)"
                             data-toggle="tooltip"></span>
                     </td>
-                    <td width="30%"><b>{{ paramKey }}</b></td>
+                    <td width="30%"><strong>{{ paramKey }}</strong></td>
                     <td width="65%" align="left">
-                      <span class="clickable"
+                      <span class="inline-editable"
                             (click)="setServiceParamEditFlag(service, 
paramKey, true)"
                             *ngIf="!getServiceParamEditFlag(service, 
paramKey)">{{descriptor.getServiceParamValue(service, paramKey)}}</span>
-                      <span *ngIf="getServiceParamEditFlag(service, paramKey)">
-                      <input type="text" 
[ngModel]="descriptor.getServiceParamValue(service, paramKey)" 
id="{{service.name}}{{paramKey}}Value">
-                      <button class="btn btn-xs"
-                              (click)="setServiceParamEditFlag(service, 
paramKey, false);onUpdateServiceParam(service, paramKey, 
getInputElementValue(service.name+paramKey+'Value'))">
+                      <span *ngIf="getServiceParamEditFlag(service, paramKey)" 
class="inline-editor inlineEditForm">
+                      <input type="text" size="40" 
[(ngModel)]="service.params[paramKey]">
+                      <button class="btn btn-xs" 
(click)="setServiceParamEditFlag(service, paramKey, 
false);descriptor.setDirty()">
                         <span class="glyphicon glyphicon-ok"></span>
                       </button>
                       <button class="btn btn-xs" 
(click)="setServiceParamEditFlag(service, paramKey, false)">
@@ -184,7 +188,7 @@
               </div>
               <div class="table-responsive" *ngIf="isShowServiceURLs(service)">
                 <table class="table table-sm" *ngIf="service.urls && 
service.urls.length > 0">
-                  <tr *ngFor="let url of service.urls; let i = index">
+                  <tr *ngFor="let url of service.urls; let i = index; 
trackBy:trackByServiceURLIndex">
                     <td width="5%">
                       <span class="clickable glyphicon glyphicon-remove btn 
btn-xs"
                             title="Remove URL"
@@ -192,13 +196,12 @@
                             data-toggle="tooltip"></span>
                     </td>
                     <td width="95%">
-                      <span class="clickable"
+                      <span class="inline-editable"
                               (click)="setServiceURLEditFlag(service, i, true)"
                               *ngIf="!getServiceURLEditFlag(service, 
i)">{{url}}</span>
-                      <span *ngIf="getServiceURLEditFlag(service, i)">
-                        <input type="text" [ngModel]="service.urls[i]" 
id="{{service.name + i}}URL">
-                        <button class="btn btn-xs"
-                                (click)="setServiceURLEditFlag(service, i, 
false);onUpdateServiceURL(service, i, 
getInputElementValue(service.name+i+'URL'))">
+                      <span *ngIf="getServiceURLEditFlag(service, i)" 
class="inline-editor inlineEditForm">
+                        <input type="text" size="50" 
[(ngModel)]="service.urls[i]">
+                        <button class="btn btn-xs" 
(click)="setServiceURLEditFlag(service, i, false);descriptor.setDirty()">
                           <span class="glyphicon glyphicon-ok"></span>
                         </button>
                         <button class="btn btn-xs" 
(click)="setServiceURLEditFlag(service, i, false)">
@@ -218,17 +221,16 @@
       <div class="panel panel-default col-md-12">
         <span [class]="'clickable glyhpicon glyphicon-' + 
(isShowServiceDiscovery() ? 'minus' : 'plus')"
               (click)="toggleShowServiceDiscovery()"></span>
-        <span><b>Discovery Details</b></span>
+        <span><strong>Discovery Details</strong></span>
         <div class="col-md-12" *ngIf="isShowServiceDiscovery()">
           <table class="table table-sm">
             <tr>
-              <td>Discovery Address</td>
+              <td width="20%"><strong>Address</strong></td>
               <td>
-                <span class="clickable" (click)="editModeAddress=true" 
*ngIf="!editModeAddress">{{ descriptor.discoveryAddress }}</span>
-                <span *ngIf="editModeAddress">
-                  <input type="text" [ngModel]="descriptor.discoveryAddress" 
#discoveryAddress>
-                  <button class="btn btn-xs"
-                          
(click)="editModeAddress=false;onUpdateDescriptorProperty('discoveryAddress', 
discoveryAddress.value)">
+                <span class="inline-editable" (click)="editModeAddress=true" 
*ngIf="!editModeAddress">{{ descriptor.discoveryAddress }}</span>
+                <span *ngIf="editModeAddress" class="inline-editor 
inlineEditForm">
+                  <input type="text" size="40" 
[(ngModel)]="descriptor.discoveryAddress">
+                  <button class="btn btn-xs" 
(click)="editModeAddress=false;descriptor.setDirty()">
                     <span class="glyphicon glyphicon-ok"></span>
                   </button>
                   <button class="btn btn-xs" (click)="editModeAddress=false">
@@ -238,13 +240,12 @@
               </td>
             </tr>
             <tr>
-              <td>Discovery Cluster</td>
+              <td width="20%"><strong>Cluster</strong></td>
               <td>
-                <span class="clickable" (click)="editModeCluster=true" 
*ngIf="!editModeCluster">{{ descriptor.discoveryCluster}}</span>
-                <span *ngIf="editModeCluster">
-                  <input type="text" [ngModel]="descriptor.discoveryCluster" 
#discoveryCluster>
-                  <button class="btn btn-xs"
-                          
(click)="editModeCluster=false;onUpdateDescriptorProperty('discoveryCluster', 
discoveryCluster.value)">
+                <span class="inline-editable" (click)="editModeCluster=true" 
*ngIf="!editModeCluster">{{ descriptor.discoveryCluster}}</span>
+                <span *ngIf="editModeCluster" class="inline-editor 
inlineEditForm">
+                  <input type="text" size="40" 
[(ngModel)]="descriptor.discoveryCluster">
+                  <button class="btn btn-xs" 
(click)="editModeCluster=false;descriptor.setDirty()">
                     <span class="glyphicon glyphicon-ok"></span>
                   </button>
                   <button class="btn btn-xs" (click)="editModeCluster=false">
@@ -254,15 +255,14 @@
               </td>
             </tr>
             <tr>
-              <td>Discovery User</td>
+              <td width="20%"><strong>Username</strong></td>
               <td>
                 <span *ngIf="!editModeUser"
-                      class="clickable"
-                      (click)="editModeUser=true">{{(descriptor.discoveryUser) 
? descriptor.discoveryUser : 'ambari.discovery.user' }}</span>
-                <span *ngIf="editModeUser">
-                  <input type="text" [ngModel]="descriptor.discoveryUser" 
#discoveryUser>
-                  <button class="btn btn-xs"
-                          
(click)="editModeUser=false;onUpdateDescriptorProperty('discoveryUser', 
discoveryUser.value)">
+                      class="inline-editable"
+                      (click)="editModeUser=true">{{(descriptor.discoveryUser) 
? descriptor.discoveryUser : '' }}</span>
+                <span *ngIf="editModeUser" class="inline-editor 
inlineEditForm">
+                  <input type="text" size="40" 
[(ngModel)]="descriptor.discoveryUser">
+                  <button class="btn btn-xs" 
(click)="editModeUser=false;descriptor.setDirty()">
                     <span class="glyphicon glyphicon-ok"></span>
                   </button>
                   <button class="btn btn-xs" (click)="editModeUser=false">
@@ -272,15 +272,14 @@
               </td>
             </tr>
             <tr>
-              <td>Discovery Password Alias</td>
+              <td width="20%"><strong>Password Alias</strong></td>
               <td>
-                <span class="clickable"
+                <span class="inline-editable"
                       (click)="editModeAlias=true"
                       *ngIf="!editModeAlias">{{ 
(descriptor.discoveryPassAlias) ? descriptor.discoveryPassAlias : 
'ambari.discovery.password' }}</span>
-                <span *ngIf="editModeAlias">
-                  <input type="text" [ngModel]="descriptor.discoveryPassAlias" 
#discoveryAlias>
-                  <button class="btn btn-xs"
-                          
(click)="editModeAlias=false;onUpdateDescriptorProperty('discoveryPassAlias', 
discoveryAlias.value)">
+                <span *ngIf="editModeAlias" class="inline-editor 
inlineEditForm">
+                  <input type="text" size="40" 
[(ngModel)]="descriptor.discoveryPassAlias">
+                  <button class="btn btn-xs" 
(click)="editModeAlias=false;descriptor.setDirty()">
                     <span class="glyphicon glyphicon-ok"></span>
                   </button>
                   <button class="btn btn-xs" (click)="editModeAlias=false">
@@ -329,7 +328,7 @@
       <bs-modal-header [showDismiss]="true">
         <h4 class="modal-title">Deleting {{getTitleSubject()}}</h4>
       </bs-modal-header>
-      <bs-modal-body>Are you sure you want to delete 
<b>{{resourceService.getResourceDisplayName(resource)}}</b>?</bs-modal-body>
+      <bs-modal-body>Are you sure you want to delete 
<strong>{{resourceService.getResourceDisplayName(resource)}}</strong>?</bs-modal-body>
       <bs-modal-footer>
         <button type="button"
                 class="btn btn-default btn-sm"
@@ -345,7 +344,7 @@
       <bs-modal-header [showDismiss]="true">
         <h4 class="modal-title">Discard {{getTitleSubject()}} Changes</h4>
       </bs-modal-header>
-      <bs-modal-body>Are you sure you want to discard 
<b>{{resourceService.getResourceDisplayName(resource)}}</b> 
changes?</bs-modal-body>
+      <bs-modal-body>Are you sure you want to discard 
<strong>{{resourceService.getResourceDisplayName(resource)}}</strong> 
changes?</bs-modal-body>
       <bs-modal-footer>
         <button type="button"
                 class="btn btn-default btn-sm"

http://git-wip-us.apache.org/repos/asf/knox/blob/9f666c39/gateway-admin-ui/src/app/resource-detail/resource-detail.component.ts
----------------------------------------------------------------------
diff --git 
a/gateway-admin-ui/src/app/resource-detail/resource-detail.component.ts 
b/gateway-admin-ui/src/app/resource-detail/resource-detail.component.ts
index e34256d..0f89d26 100644
--- a/gateway-admin-ui/src/app/resource-detail/resource-detail.component.ts
+++ b/gateway-admin-ui/src/app/resource-detail/resource-detail.component.ts
@@ -56,6 +56,9 @@ export class ResourceDetailComponent implements OnInit {
   @ViewChild('choosePC')
   chooseProviderConfigModal: ProviderConfigSelectorComponent;
 
+  referencedProviderConfigError: boolean = false;
+
+
   constructor(private resourceService: ResourceService, private 
resourceTypesService: ResourceTypesService) {
   }
 
@@ -345,6 +348,7 @@ export class ResourceDetailComponent implements OnInit {
                         .catch((err: HttpErrorResponse) => {
                             if (err.status === 304) { // Not Modified
                                 console.log(resourceName + ' cannot be deleted 
while there are descriptors actively referencing it.');
+                                this.referencedProviderConfigError = true;
                             } else {
                                 console.error('Error deleting ' + resourceName 
+ ' : ' + err.message)
                             }
@@ -487,10 +491,6 @@ export class ResourceDetailComponent implements OnInit {
       return this[provider.name+paramName+'EditMode'];
   }
 
-  getInputElementValue(id: string): string {
-      return (<HTMLInputElement>document.getElementById(id)).value;
-  }
-
   setServiceParamEditFlag(service: Service, paramName: string, value: boolean) 
{
       this[service.name + paramName + 'EditMode'] = value;
       this.descriptor.setDirty();
@@ -509,46 +509,9 @@ export class ResourceDetailComponent implements OnInit {
       return this[service.name + index + 'EditMode'];
   }
 
-  onUpdateServiceParam(service: Service, paramName: string, value: string) {
-      service.params[paramName] = value;
-      this.descriptor.setDirty();
-  }
-
-  onUpdateServiceURL(service: Service, urlIndex: number, value: string) {
-      service.urls[urlIndex] = value;
-      this.descriptor.setDirty();
-  }
-
-  onUpdateDescriptorProperty(propertyName: string, value: string) {
-      //console.log('Setting descriptor ' + this.resource.name + ' property ' 
+ propertyName + ' to value ' + value);
-      this.descriptor[propertyName] = value;
-      this.descriptor.setDirty();
-  }
-
-  onUpdateProviderConfigParam(provider: ProviderConfig, propertyName: string, 
value: string) {
-    provider.params[propertyName] = value;
-    this.changedProviders = this.providers;
-  }
-
-  getParamKeys(provider: ProviderConfig): string[] {
-    let result = [];
-    for(let key in provider.params){
-      if (provider.params.hasOwnProperty(key)){
-          result.push(key);
-      }
-    }
-    return result;
-  }
-
 
-  getServiceParamKeys(service: Service): string[] {
-    let result = [];
-    for(let key in service.params){
-      if (service.params.hasOwnProperty(key)){
-        result.push(key);
-      }
-    }
-    return result;
+  getProviderParamNames(provider: ProviderConfig): string[] {
+      return Object.getOwnPropertyNames(provider.params);
   }
 
 
@@ -567,6 +530,11 @@ export class ResourceDetailComponent implements OnInit {
       return result;
   }
 
+  // This method is required to maintain focus on descriptor service URLs when 
they're being edited.
+  trackByServiceURLIndex(index: any, item: any) {
+      return index;
+  }
+
   hasSelectedResource(): boolean {
     return Boolean(this.resource) && Boolean(this.resource.name);
   }

http://git-wip-us.apache.org/repos/asf/knox/blob/9f666c39/gateway-applications/src/main/resources/applications/admin-ui/app/index.html
----------------------------------------------------------------------
diff --git 
a/gateway-applications/src/main/resources/applications/admin-ui/app/index.html 
b/gateway-applications/src/main/resources/applications/admin-ui/app/index.html
index 41726f5..cdf2bd7 100644
--- 
a/gateway-applications/src/main/resources/applications/admin-ui/app/index.html
+++ 
b/gateway-applications/src/main/resources/applications/admin-ui/app/index.html
@@ -11,4 +11,4 @@
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
---><!doctype html><html><head><meta charset="utf-8"><title>Apache Knox 
Manager</title><meta name="viewport" 
content="width=device-width,initial-scale=1"><link rel="icon" 
type="image/x-icon" href="favicon.ico"><meta name="viewport" 
content="width=device-width,initial-scale=1"><!-- Latest compiled and minified 
CSS --><link rel="stylesheet" 
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"; 
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
 crossorigin="anonymous"><!-- Optional theme --><link rel="stylesheet" 
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css";
 
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp"
 crossorigin="anonymous"><!-- Custom styles for this template --><link 
href="assets/sticky-footer.css" rel="stylesheet"><script 
src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js";></script><!--
 Latest compiled and minified JavaScript --><scr
 ipt src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"; 
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
 crossorigin="anonymous"></script><script 
src="assets/vkbeautify.js"></script><link 
href="styles.2ee5b7f4cd59a6cf015e.bundle.css" 
rel="stylesheet"/></head><body><div class="navbar-wrapper"><div 
class="container-fluid"><nav class="navbar navbar-inverse 
navbar-static-top"><div class="container-fluid"><div 
class="navbar-header"><button type="button" class="navbar-toggle collapsed" 
data-toggle="collapse" data-target="#navbar" aria-expanded="false" 
aria-controls="navbar"><span class="sr-only">Toggle navigation</span> <span 
class="icon-bar"></span> <span class="icon-bar"></span> <span 
class="icon-bar"></span></button> <a class="navbar-brand" href="#"><img 
style="max-width:200px; margin-top: -9px;" 
src="assets/knox-logo-transparent.gif" alt="Apache Knox 
Manager"></a></div></div></nav></div><!-- Content --><resource-management></res
 ource-management><footer class="footer"><div>Knox Manager Version 
0.1.0</div><gateway-version></gateway-version></footer><script 
type="text/javascript" 
src="inline.2f727e6f73f32920fc6d.bundle.js"></script><script 
type="text/javascript" 
src="scripts.c50bb762c438ae0f8842.bundle.js"></script><script 
type="text/javascript" 
src="main.3323b90a117ac8faffa1.bundle.js"></script></div></body></html>
\ No newline at end of file
+--><!doctype html><html><head><meta charset="utf-8"><title>Apache Knox 
Manager</title><meta name="viewport" 
content="width=device-width,initial-scale=1"><link rel="icon" 
type="image/x-icon" href="favicon.ico"><meta name="viewport" 
content="width=device-width,initial-scale=1"><!-- Latest compiled and minified 
CSS --><link rel="stylesheet" 
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"; 
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
 crossorigin="anonymous"><!-- Optional theme --><link rel="stylesheet" 
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css";
 
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp"
 crossorigin="anonymous"><!-- Custom styles for this template --><link 
href="assets/sticky-footer.css" rel="stylesheet"><script 
src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js";></script><!--
 Latest compiled and minified JavaScript --><scr
 ipt src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"; 
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
 crossorigin="anonymous"></script><script 
src="assets/vkbeautify.js"></script><link 
href="styles.2ee5b7f4cd59a6cf015e.bundle.css" 
rel="stylesheet"/></head><body><div class="navbar-wrapper"><div 
class="container-fluid"><nav class="navbar navbar-inverse 
navbar-static-top"><div class="container-fluid"><div 
class="navbar-header"><button type="button" class="navbar-toggle collapsed" 
data-toggle="collapse" data-target="#navbar" aria-expanded="false" 
aria-controls="navbar"><span class="sr-only">Toggle navigation</span> <span 
class="icon-bar"></span> <span class="icon-bar"></span> <span 
class="icon-bar"></span></button> <a class="navbar-brand" href="#"><img 
style="max-width:200px; margin-top: -9px;" 
src="assets/knox-logo-transparent.gif" alt="Apache Knox 
Manager"></a></div></div></nav></div><!-- Content --><resource-management></res
 ource-management><footer class="footer"><div>Knox Manager Version 
0.1.0</div><gateway-version></gateway-version></footer><script 
type="text/javascript" 
src="inline.c33f88beae0a6c65f63f.bundle.js"></script><script 
type="text/javascript" 
src="scripts.c50bb762c438ae0f8842.bundle.js"></script><script 
type="text/javascript" 
src="main.e8ac70095627bac846b5.bundle.js"></script></div></body></html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/9f666c39/gateway-applications/src/main/resources/applications/admin-ui/app/inline.2f727e6f73f32920fc6d.bundle.js
----------------------------------------------------------------------
diff --git 
a/gateway-applications/src/main/resources/applications/admin-ui/app/inline.2f727e6f73f32920fc6d.bundle.js
 
b/gateway-applications/src/main/resources/applications/admin-ui/app/inline.2f727e6f73f32920fc6d.bundle.js
deleted file mode 100644
index 3c19a4a..0000000
--- 
a/gateway-applications/src/main/resources/applications/admin-ui/app/inline.2f727e6f73f32920fc6d.bundle.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(e){var 
n=window.webpackJsonp;window.webpackJsonp=function(r,a,c){for(var 
u,i,f,l=0,s=[];l<r.length;l++)t[i=r[l]]&&s.push(t[i][0]),t[i]=0;for(u in 
a)Object.prototype.hasOwnProperty.call(a,u)&&(e[u]=a[u]);for(n&&n(r,a,c);s.length;)s.shift()();if(c)for(l=0;l<c.length;l++)f=o(o.s=c[l]);return
 f};var r={},t={2:0};function o(n){if(r[n])return r[n].exports;var 
t=r[n]={i:n,l:!1,exports:{}};return 
e[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.e=function(e){var 
n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new 
Promise(function(r,o){n=t[e]=[r,o]});n[2]=r;var 
a=document.getElementsByTagName("head")[0],c=document.createElement("script");c.type="text/javascript",c.charset="utf-8",c.async=!0,c.timeout=12e4,o.nc&&c.setAttribute("nonce",o.nc),c.src=o.p+""+e+"."+{0:"3323b90a117ac8faffa1",1:"aed76669724804835353"}[e]+".chunk.js";var
 u=setTimeout(i,12e4);function i(){c.onerror=c.onload=null,clearTimeout(u);var 
n=t[e];0!==n&&(n&&n[1](new Error("Loading chu
 nk "+e+" failed.")),t[e]=void 0)}return 
c.onerror=c.onload=i,a.appendChild(c),r},o.m=e,o.c=r,o.d=function(e,n,r){o.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},o.n=function(e){var
 n=e&&e.__esModule?function(){return e.default}:function(){return e};return 
o.d(n,"a",n),n},o.o=function(e,n){return 
Object.prototype.hasOwnProperty.call(e,n)},o.p="",o.oe=function(e){throw 
console.error(e),e}}([]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/9f666c39/gateway-applications/src/main/resources/applications/admin-ui/app/inline.c33f88beae0a6c65f63f.bundle.js
----------------------------------------------------------------------
diff --git 
a/gateway-applications/src/main/resources/applications/admin-ui/app/inline.c33f88beae0a6c65f63f.bundle.js
 
b/gateway-applications/src/main/resources/applications/admin-ui/app/inline.c33f88beae0a6c65f63f.bundle.js
new file mode 100644
index 0000000..9de102a
--- /dev/null
+++ 
b/gateway-applications/src/main/resources/applications/admin-ui/app/inline.c33f88beae0a6c65f63f.bundle.js
@@ -0,0 +1 @@
+!function(e){var 
n=window.webpackJsonp;window.webpackJsonp=function(r,c,a){for(var 
u,i,f,l=0,s=[];l<r.length;l++)t[i=r[l]]&&s.push(t[i][0]),t[i]=0;for(u in 
c)Object.prototype.hasOwnProperty.call(c,u)&&(e[u]=c[u]);for(n&&n(r,c,a);s.length;)s.shift()();if(a)for(l=0;l<a.length;l++)f=o(o.s=a[l]);return
 f};var r={},t={2:0};function o(n){if(r[n])return r[n].exports;var 
t=r[n]={i:n,l:!1,exports:{}};return 
e[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.e=function(e){var 
n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new 
Promise(function(r,o){n=t[e]=[r,o]});n[2]=r;var 
c=document.getElementsByTagName("head")[0],a=document.createElement("script");a.type="text/javascript",a.charset="utf-8",a.async=!0,a.timeout=12e4,o.nc&&a.setAttribute("nonce",o.nc),a.src=o.p+""+e+"."+{0:"e8ac70095627bac846b5",1:"aed76669724804835353"}[e]+".chunk.js";var
 u=setTimeout(i,12e4);function i(){a.onerror=a.onload=null,clearTimeout(u);var 
n=t[e];0!==n&&(n&&n[1](new Error("Loading chu
 nk "+e+" failed.")),t[e]=void 0)}return 
a.onerror=a.onload=i,c.appendChild(a),r},o.m=e,o.c=r,o.d=function(e,n,r){o.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},o.n=function(e){var
 n=e&&e.__esModule?function(){return e.default}:function(){return e};return 
o.d(n,"a",n),n},o.o=function(e,n){return 
Object.prototype.hasOwnProperty.call(e,n)},o.p="",o.oe=function(e){throw 
console.error(e),e}}([]);
\ No newline at end of file

Reply via email to