KNOX-1040: Implemented the ability to add config elements to provider 
configurations and descriptors.


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

Branch: refs/heads/master
Commit: c3c0bf742dfe2f9f61c844625c1724ac4d133e12
Parents: b751c72
Author: Phil Zampino <pzamp...@apache.org>
Authored: Tue Feb 13 23:56:53 2018 -0500
Committer: Phil Zampino <pzamp...@apache.org>
Committed: Wed Feb 14 15:21:11 2018 -0500

----------------------------------------------------------------------
 .../src/app/resource-detail/descriptor.ts       |  31 ++
 .../resource-detail.component.css               |   6 +-
 .../resource-detail.component.html              | 427 +++++++++++--------
 .../resource-detail.component.ts                |  58 +++
 gateway-admin-ui/src/app/resource/service.ts    |   2 +-
 .../applications/admin-ui/app/index.html        |   2 +-
 .../app/inline.6fba7504840e56503966.bundle.js   |   1 +
 .../app/inline.c33f88beae0a6c65f63f.bundle.js   |   1 -
 .../app/main.1776646c6234f6c1c793.bundle.js     |   1 +
 .../app/main.e8ac70095627bac846b5.bundle.js     |   1 -
 10 files changed, 355 insertions(+), 175 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/knox/blob/c3c0bf74/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 090e84a..6ef217f 100644
--- a/gateway-admin-ui/src/app/resource-detail/descriptor.ts
+++ b/gateway-admin-ui/src/app/resource-detail/descriptor.ts
@@ -28,6 +28,9 @@ export class Descriptor {
     private dirty: boolean = false;
 
     getServiceParamNames(service: Service): string[] {
+      if (!service.params) {
+        service.params = {};
+      }
       return Object.getOwnPropertyNames(service.params);
     }
 
@@ -43,6 +46,34 @@ export class Descriptor {
       }
     }
 
+    addService(name: string) {
+        if (!this.services) {
+            this.services = [];
+        }
+        let s = new Service();
+        s.name = name;
+        s.params = {};
+        s.urls = [];
+        this.services.push(s);
+        this.setDirty();
+    }
+
+    addServiceParam(service: Service, name: string, value: string) {
+        if (!service.params) {
+            service.params = {};
+        }
+        service.params[name] = value;
+        this.setDirty();
+    }
+
+    addServiceURL(service: Service, url: string) {
+        if (!service.urls) {
+            service.urls = [];
+        }
+        service.urls.push(url);
+        this.setDirty();
+    }
+
     setDirty() {
         this.dirty = true;
     }

http://git-wip-us.apache.org/repos/asf/knox/blob/c3c0bf74/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 7273b31..5ca3848 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
@@ -44,7 +44,7 @@
     border-radius: 5px;
 }
 
-.inline-editor.inline-editable-button-group {
+.inline-editor.inline-editor-button-group {
     display: inline-block;
 }
 
@@ -59,4 +59,8 @@
 
 [hidden].inline-editor {
     display: none;
+}
+
+.inline-glyph {
+    vertical-align: 2%;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/c3c0bf74/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 4c1ebd8..225072a 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
@@ -7,66 +7,99 @@
 
   <!-- 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>
+    <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 style="padding-bottom: 10px">
+      <span><strong>Providers</strong></span>
+      <span *ngIf="!isAddingProvider"
+            class="clickable inline-glyph glyphicon glyphicon-plus-sign btn 
btn-xs pull-right"
+            (click)="isAddingProvider=true"
+            data-toggle="tooltip" title="Add Provider"></span>
+      <span *ngIf="isAddingProvider" class="inline-editor inlineEditForm 
pull-right">
+        <input type="text" value="name" onClick="this.setSelectionRange(0, 
this.value.length)" #newProviderName>
+        <input type="text" value="role" onClick="this.setSelectionRange(0, 
this.value.length)" #newProviderRole>
+        <button class="btn btn-xs"
+                (click)="isAddingProvider=false;
+                         addProvider(newProviderName.value, 
newProviderRole.value)">
+          <span class="glyphicon glyphicon-ok "></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')"
+        <button class="btn btn-xs" (click)="isAddingProvider=false">
+          <span class="glyphicon glyphicon-remove"></span>
+        </button>
+      </span>
+    </div>
+    <div class="panel panel-default" *ngFor="let provider of providers">
+      <div class="panel-heading">
+        <span>&nbsp;</span>
+        <span [class]="'clickable inline-glyph glyhpicon glyphicon-' + 
(isShowProvider(provider) ? 'minus' : 'plus')"
               (click)="toggleShowProvider(provider)"></span>
         <span><strong>{{ provider.name }}</strong></span>
-        <span class="clickable glyphicon glyphicon-remove pull-right btn 
btn-xs"
+        <span class="clickable inline-glyph 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;<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><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 paramName of getProviderParamNames(provider)">
-                  <td>
-                    <span class="clickable glyphicon glyphicon-remove btn 
btn-xs"
-                          title="Remove Param"
-                          (click)="onRemoveProviderParam(provider, paramName)"
-                          data-toggle="tooltip"></span>
-                  </td>
-                  <td><strong>{{ paramName }}</strong></td>
-                  <td>
-                    <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, 
paramName, false);changedProviders=providers">
-                        <span class="glyphicon glyphicon-ok"></span>
-                      </button>
-                      <button class="btn btn-xs" 
(click)="setProviderParamEditFlag(provider, paramName, false)">
-                        <span class="glyphicon glyphicon-remove"></span>
-                      </button>
-                    </span>
-                  </td>
-                </tr>
-              </table>
-            </div>
-          </div>
-        </div>
-        <br><br>
       </div>
-    </div>
+      <div class="panel-body" *ngIf="isShowProvider(provider)">
+        <strong>Role</strong> {{ provider.role }}<br>
+        <strong>Enabled</strong>&nbsp;<input type="checkbox"
+                                                     
[checked]="isProviderEnabled(provider)"
+                                                     
(click)="onProviderEnabled(provider)"><br>
+        <div>
+          <span [class]="'clickable inline-glyph glyhpicon glyphicon-' + 
(isShowProviderParams(provider) ? 'minus' : 'plus')"
+                (click)="toggleShowProviderParams(provider)"></span>
+          <span><strong>Params</strong></span>
+          <span *ngIf="!isAddingProviderParam(provider)"
+                class="clickable inline-glyph glyphicon glyphicon-plus-sign 
btn btn-xs"
+                (click)="setAddingProviderParam(provider,true)"
+                data-toggle="tooltip" title="Add Param"></span>
+          <span *ngIf="isAddingProviderParam(provider)" class="inline-editor 
inlineEditForm">
+            <input type="text" value="name" onClick="this.setSelectionRange(0, 
this.value.length)" #newParamName>
+            <input type="text" value="value" 
onClick="this.setSelectionRange(0, this.value.length)" #newParamValue>
+            <button class="btn btn-xs"
+                    (click)="setAddingProviderParam(provider,false);
+                             addProviderParam(provider, newParamName.value, 
newParamValue.value);
+                             showProviderParams(provider)">
+              <span class="glyphicon glyphicon-ok "></span>
+            </button>
+            <button class="btn btn-xs" 
(click)="setAddingProviderParam(provider,false)">
+              <span class="glyphicon glyphicon-remove"></span>
+            </button>
+          </span>
+          <div class="panel panel-default table-responsive" 
*ngIf="isShowProviderParams(provider)">
+            <table class="table table-sm">
+              <tr *ngFor="let paramName of getProviderParamNames(provider)">
+                <td>
+                  <span class="clickable inline-glyph glyphicon 
glyphicon-remove btn btn-xs"
+                        title="Remove Param"
+                        (click)="onRemoveProviderParam(provider, paramName)"
+                        data-toggle="tooltip"></span>
+                </td>
+                <td><strong>{{ paramName }}</strong></td>
+                <td>
+                  <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, 
paramName, false);changedProviders=providers">
+                      <span class="glyphicon glyphicon-ok"></span>
+                    </button>
+                    <button class="btn btn-xs" 
(click)="setProviderParamEditFlag(provider, paramName, false)">
+                      <span class="glyphicon glyphicon-remove"></span>
+                    </button>
+                  </span>
+                </td>
+              </tr>
+            </table>
+          </div> <!-- Provider params -->
+        </div>
+      </div> <!-- Provider Details -->
+    </div> <!-- Provider panel -->
 
     <div> <!-- Provider Configuration Modification Buttons -->
       <button type="button"
@@ -74,7 +107,7 @@
               class="btn btn-default btn-sm pull-left"
               (click)="deleteConfirmModal.open('md')"
               data-toggle="tooltip">
-        <span class="clickable glyphicon glyphicon-trash"></span>
+        <span class="glyphicon glyphicon-trash"></span>
       </button>
       <span class="pull-right">
         <button type="button"
@@ -96,69 +129,102 @@
         </button>
       </span>
     </div>
-  </div>
+  </div> <!-- Provider Configuration Details -->
 
   <!-- Descriptor Details -->
   <div class="panel-body" *ngIf="hasSelectedResource() && resourceType === 
'Descriptors'">
-    <!-- The resource name is undefined if it's the empty descriptor because 
none has been selected yet. -->
-    <div *ngIf="hasSelectedResource()">
-      <div>
-        <div class="panel panel-default col-md-12">
-          <span class="col-md-12 pull-left">
-            <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">
-                <span class="glyphicon glyphicon-remove"></span>
-              </button>
-            </span>
-            &nbsp;
-            <button id="chooseProviderConfig"
-                    class="btn btn-xs"
-                    (click)="chooseProviderConfigModal.open(descriptor, 'sm')"
-                    [disabled]="editModePC"
-                    type="submit"
-                    data-toggle="tooltip"
-                    title="Choose Provider Configuration">
-              <span class="glyphicon glyphicon-edit"></span>
+    <div> <!-- Provider Config reference -->
+      <div class="panel panel-default col-md-12">
+        <span class="col-md-12 pull-left">
+          <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">
+              <span class="glyphicon glyphicon-remove"></span>
             </button>
           </span>
-        </div>
-        <app-provider-config-selector #choosePC></app-provider-config-selector>
+          &nbsp;
+          <button id="chooseProviderConfig"
+                  class="btn btn-xs"
+                  (click)="chooseProviderConfigModal.open(descriptor, 'sm')"
+                  [disabled]="editModePC"
+                  type="submit"
+                  data-toggle="tooltip"
+                  title="Choose Provider Configuration">
+            <span class="glyphicon glyphicon-edit"></span>
+          </button>
+        </span>
       </div>
+      <app-provider-config-selector #choosePC></app-provider-config-selector>
+    </div> <!-- Provider Config reference -->
 
-      <br><br>
+    <br><br>
 
-      <div class="panel panel-default col-md-12">
-        <span [class]="'clickable glyhpicon glyphicon-' + (isShowServices() ? 
'minus' : 'plus')"
+    <div class="panel panel-default">
+      <div class="panel-heading">
+        <span [class]="'clickable inline-glyph glyhpicon glyphicon-' + 
(isShowServices() ? 'minus' : 'plus')"
               (click)="toggleShowServices()"></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()">
+        <span *ngIf="!isAddingService"
+              class="clickable inline-glyph glyphicon glyphicon-plus-sign btn 
btn-xs"
+              (click)="isAddingService=true"
+              data-toggle="tooltip" title="Add Service"></span>
+        <span *ngIf="isAddingService"class="inline-editor inlineEditForm">
+            <input type="text" value="name" onClick="this.setSelectionRange(0, 
this.value.length)" #newServiceName>
+            <button class="btn btn-xs"
+                    (click)="isAddingService=false;
+                             descriptor.addService(newServiceName.value);
+                             showServices()">
+              <span class="glyphicon glyphicon-ok"></span>
+            </button>
+            <button class="btn btn-xs" (click)="isAddingService=false">
+              <span class="glyphicon glyphicon-remove"></span>
+            </button>
+        </span>
+      </div>
+      <div class="panel-body table-responsive" *ngIf="isShowServices()">
         <table class="table table-striped table-sm">
           <tr *ngFor="let service of descriptor.services">
             <td>
               <div>
                 <span><strong>{{ service.name }}</strong></span>
-                <span class="clickable glyphicon glyphicon-remove btn btn-xs 
pull-right"
+                <span class="clickable inline-glyph glyphicon glyphicon-remove 
btn btn-xs pull-right"
                       [title]="'Remove ' + service.name"
                       (click)="onRemoveDescriptorService(service.name)"
                       data-toggle="tooltip"></span>
               </div>
               <div>
-                <span [class]="'clickable glyhpicon glyphicon-' + 
(isShowServiceParams(service) ? 'minus' : 'plus')"
+                <span [class]="'clickable inline-glyph glyhpicon glyphicon-' + 
(isShowServiceParams(service) ? 'minus' : 'plus')"
                       (click)="toggleShowServiceParams(service)"></span>
-                <span>Params</span><span>&nbsp;</span><span class="glyphicon 
glyphicon-plus-sign btn btn-xs" data-toggle="tooltip" title="Add param"></span>
+                <span>Params</span><span>&nbsp;</span>
+                <span *ngIf="!isAddingServiceParam(service)"
+                      class="clickable inline-glyph glyphicon 
glyphicon-plus-sign btn btn-xs"
+                      (click)="setAddingServiceParam(service,true)"
+                      data-toggle="tooltip"
+                      title="Add Param"></span>
+                <span 
*ngIf="isAddingServiceParam(service)"class="inline-editor inlineEditForm">
+                    <input type="text" value="name" 
onClick="this.setSelectionRange(0, this.value.length)" #newParamName>
+                    <input type="text" value="value" 
onClick="this.setSelectionRange(0, this.value.length)" #newParamValue>
+                    <button class="btn btn-xs"
+                            (click)="setAddingServiceParam(service,false);
+                                     descriptor.addServiceParam(service, 
newParamName.value, newParamValue.value);
+                                     showServiceParams(service)">
+                      <span class="glyphicon glyphicon-ok"></span>
+                    </button>
+                    <button class="btn btn-xs" 
(click)="setAddingServiceParam(service,false)">
+                      <span class="glyphicon glyphicon-remove"></span>
+                    </button>
+                </span>
               </div>
               <div class="table-responsive" 
*ngIf="isShowServiceParams(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"
+                      <span class="clickable inline-glyph glyphicon 
glyphicon-remove btn btn-xs"
                             title="Remove Param"
                             
(click)="onRemoveDescriptorServiceParam(service.name, paramKey)"
                             data-toggle="tooltip"></span>
@@ -182,15 +248,31 @@
                 </table>
               </div>
               <div>
-                <span [class]="'clickable glyhpicon glyphicon-' + 
(isShowServiceURLs(service) ? 'minus' : 'plus')"
+                <span [class]="'clickable inline-glyph glyhpicon glyphicon-' + 
(isShowServiceURLs(service) ? 'minus' : 'plus')"
                       (click)="toggleShowServiceURLs(service)"></span>
-                <span>URLs</span><span>&nbsp;</span><span class="glyphicon 
glyphicon-plus-sign btn btn-xs" data-toggle="tooltip" title="Add URL"></span>
+                <span>URLs</span><span>&nbsp;</span>
+                <span *ngIf="!isAddingServiceURL(service)"
+                      (click)="setAddingServiceURL(service,true)"
+                      class="inline-glyph glyphicon glyphicon-plus-sign btn 
btn-xs"
+                      data-toggle="tooltip" title="Add URL"></span>
+                <span *ngIf="isAddingServiceURL(service)"class="inline-editor 
inlineEditForm">
+                    <input type="text" value="url" 
onClick="this.setSelectionRange(0, this.value.length)" #newURL>
+                    <button class="btn btn-xs"
+                            (click)="setAddingServiceURL(service,false);
+                                     descriptor.addServiceURL(service, 
newURL.value);
+                                     showServiceURLs(service)">
+                      <span class="glyphicon glyphicon-ok"></span>
+                    </button>
+                    <button class="btn btn-xs" 
(click)="setAddingServiceURL(service,false)">
+                      <span class="glyphicon glyphicon-remove"></span>
+                    </button>
+                </span>
               </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; 
trackBy:trackByServiceURLIndex">
                     <td width="5%">
-                      <span class="clickable glyphicon glyphicon-remove btn 
btn-xs"
+                      <span class="clickable inline-glyph glyphicon 
glyphicon-remove btn btn-xs"
                             title="Remove URL"
                             
(click)="onRemoveDescriptorServiceURL(service.name, url)"
                             data-toggle="tooltip"></span>
@@ -215,83 +297,88 @@
             </td>
           </tr>
         </table>
-      </div>
-    </div>
-      <br><br>
-      <div class="panel panel-default col-md-12">
-        <span [class]="'clickable glyhpicon glyphicon-' + 
(isShowServiceDiscovery() ? 'minus' : 'plus')"
+      </div> <!-- Services table -->
+    </div> <!-- Services panel -->
+
+    <div class="panel panel-default"> <!-- Discovery panel -->
+      <div class="panel-heading">
+        <span [class]="'clickable inline-glyph glyhpicon glyphicon-' + 
(isShowServiceDiscovery() ? 'minus' : 'plus')"
               (click)="toggleShowServiceDiscovery()"></span>
         <span><strong>Discovery Details</strong></span>
-        <div class="col-md-12" *ngIf="isShowServiceDiscovery()">
-          <table class="table table-sm">
-            <tr>
-              <td width="20%"><strong>Address</strong></td>
-              <td>
-                <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">
-                    <span class="glyphicon glyphicon-remove"></span>
-                  </button>
-                </span>
-              </td>
-            </tr>
-            <tr>
-              <td width="20%"><strong>Cluster</strong></td>
-              <td>
-                <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">
-                    <span class="glyphicon glyphicon-remove"></span>
-                  </button>
-                </span>
-              </td>
-            </tr>
-            <tr>
-              <td width="20%"><strong>Username</strong></td>
-              <td>
-                <span *ngIf="!editModeUser"
-                      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">
-                    <span class="glyphicon glyphicon-remove"></span>
-                  </button>
-                </span>
-              </td>
-            </tr>
-            <tr>
-              <td width="20%"><strong>Password Alias</strong></td>
-              <td>
-                <span class="inline-editable"
-                      (click)="editModeAlias=true"
-                      *ngIf="!editModeAlias">{{ 
(descriptor.discoveryPassAlias) ? descriptor.discoveryPassAlias : 
'ambari.discovery.password' }}</span>
-                <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">
-                    <span class="glyphicon glyphicon-remove"></span>
-                  </button>
-                </span>
-              </td>
-            </tr>
-          </table>
-        </div>
       </div>
-    </div>
+      <div class="panel-body" *ngIf="isShowServiceDiscovery()">
+        <table class="table table-sm">
+          <tr>
+            <td width="20%"><strong>Address</strong></td>
+            <td>
+              <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">
+                  <span class="glyphicon glyphicon-remove"></span>
+                </button>
+              </span>
+            </td>
+          </tr>
+          <tr>
+            <td width="20%"><strong>Cluster</strong></td>
+            <td>
+              <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">
+                  <span class="glyphicon glyphicon-remove"></span>
+                </button>
+              </span>
+            </td>
+          </tr>
+          <tr>
+            <td width="20%"><strong>Username</strong></td>
+            <td>
+              <span class="inline-editable"
+                    (click)="editModeUser=true"
+                    *ngIf="!editModeUser">{{(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">
+                  <span class="glyphicon glyphicon-remove"></span>
+                </button>
+              </span>
+            </td>
+          </tr>
+          <tr>
+            <td width="20%"><strong>Password Alias</strong></td>
+            <td>
+              <span class="inline-editable"
+                    (click)="editModeAlias=true"
+                    *ngIf="!editModeAlias">{{ (descriptor.discoveryPassAlias) 
? descriptor.discoveryPassAlias : 'ambari.discovery.password' }}</span>
+              <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">
+                  <span class="glyphicon glyphicon-remove"></span>
+                </button>
+              </span>
+            </td>
+          </tr>
+        </table>
+      </div><!-- Discovery details -->
+    </div><!-- Discovery panel -->
 
     <div> <!-- Descriptor Modification Buttons -->
       <button type="button"
@@ -299,7 +386,7 @@
               class="btn btn-default btn-sm pull-left"
               (click)="deleteConfirmModal.open('md')"
               data-toggle="tooltip">
-        <span class="clickable glyphicon glyphicon-trash"></span>
+        <span class="glyphicon glyphicon-trash"></span>
       </button>
       <span class="pull-right">
         <button type="button"
@@ -321,7 +408,7 @@
         </button>
       </span>
     </div>
-  </div>
+  </div> <!-- Descriptor Details -->
 
   <div> <!-- Confirmation Modal Dialogs -->
     <bs-modal (onClose)="deleteResource()" #deleteConfirmModal>

http://git-wip-us.apache.org/repos/asf/knox/blob/c3c0bf74/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 0f89d26..52dd09d 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
@@ -446,6 +446,10 @@ export class ResourceDetailComponent implements OnInit {
       this[this.resource.name + provider.name + 'ShowParams'] = 
!this.isShowProviderParams(provider);
   }
 
+  showProviderParams(provider: ProviderConfig) {
+    this[this.resource.name + provider.name + 'ShowParams'] = true;
+  }
+
   isShowProviderParams(provider: ProviderConfig): boolean {
       return this[this.resource.name + provider.name + 'ShowParams'];
   }
@@ -454,6 +458,10 @@ export class ResourceDetailComponent implements OnInit {
       this[this.resource.name + 'ShowServices'] = !this.isShowServices();
   }
 
+  showServices() {
+    this[this.resource.name + 'ShowServices'] = true;
+  }
+
   isShowServices(): boolean {
       return this[this.resource.name + 'ShowServices'];
   }
@@ -470,6 +478,10 @@ export class ResourceDetailComponent implements OnInit {
       this[this.resource.name + service.name + 'ShowParams'] = 
!this.isShowServiceParams(service);
   }
 
+  showServiceParams(service: Service) {
+      this[this.resource.name + service.name + 'ShowParams'] = true;
+  }
+
   isShowServiceParams(service: Service): boolean {
       return this[this.resource.name + service.name + 'ShowParams'];
   }
@@ -478,6 +490,10 @@ export class ResourceDetailComponent implements OnInit {
       this[this.resource.name + service.name + 'ShowURLs'] = 
!this.isShowServiceURLs(service);
   }
 
+  showServiceURLs(service: Service) {
+      this[this.resource.name + service.name + 'ShowURLs'] = true;
+  }
+
   isShowServiceURLs(service: Service): boolean {
       return this[this.resource.name + service.name + 'ShowURLs'];
   }
@@ -509,8 +525,50 @@ export class ResourceDetailComponent implements OnInit {
       return this[service.name + index + 'EditMode'];
   }
 
+  isAddingServiceParam(service: Service): boolean {
+      return this['addParam' + service.name];
+  }
+
+  setAddingServiceParam(service: Service, value: boolean) {
+      this['addParam' + service.name] = value;
+  }
+
+  isAddingServiceURL(service: Service): boolean {
+    return this['addURL' + service.name];
+  }
+
+  setAddingServiceURL(service: Service, value: boolean) {
+    this['addURL' + service.name] = value;
+  }
+
+  isAddingProviderParam(provider: ProviderConfig): boolean {
+    return this['addParam' + provider.name];
+  }
+
+  setAddingProviderParam(provider: ProviderConfig, value: boolean) {
+    this['addParam' + provider.name] = value;
+  }
+
+  addProvider(name: string, role: string) {
+      let p = new ProviderConfig();
+      p.name = name;
+      p.role = role;
+      this.providers.push(p);
+      this.changedProviders = this.providers;
+  }
+
+  addProviderParam(provider: ProviderConfig, name: string, value: string) {
+      if (!provider.params) {
+          provider.params = {};
+      }
+      provider.params[name] = value;
+      this.changedProviders = this.providers;
+  }
 
   getProviderParamNames(provider: ProviderConfig): string[] {
+      if (!provider.params) {
+          provider.params = {};
+      }
       return Object.getOwnPropertyNames(provider.params);
   }
 

http://git-wip-us.apache.org/repos/asf/knox/blob/c3c0bf74/gateway-admin-ui/src/app/resource/service.ts
----------------------------------------------------------------------
diff --git a/gateway-admin-ui/src/app/resource/service.ts 
b/gateway-admin-ui/src/app/resource/service.ts
index 3997290..e46cea2 100644
--- a/gateway-admin-ui/src/app/resource/service.ts
+++ b/gateway-admin-ui/src/app/resource/service.ts
@@ -18,5 +18,5 @@
 export class Service {
     name: string;
     params: Object;
-    urls: string[]
+    urls: string[];
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/c3c0bf74/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 cdf2bd7..f83af6b 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.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
+--><!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.6fba7504840e56503966.bundle.js"></script><script 
type="text/javascript" 
src="scripts.c50bb762c438ae0f8842.bundle.js"></script><script 
type="text/javascript" 
src="main.1776646c6234f6c1c793.bundle.js"></script></div></body></html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/c3c0bf74/gateway-applications/src/main/resources/applications/admin-ui/app/inline.6fba7504840e56503966.bundle.js
----------------------------------------------------------------------
diff --git 
a/gateway-applications/src/main/resources/applications/admin-ui/app/inline.6fba7504840e56503966.bundle.js
 
b/gateway-applications/src/main/resources/applications/admin-ui/app/inline.6fba7504840e56503966.bundle.js
new file mode 100644
index 0000000..ab94a0e
--- /dev/null
+++ 
b/gateway-applications/src/main/resources/applications/admin-ui/app/inline.6fba7504840e56503966.bundle.js
@@ -0,0 +1 @@
+!function(e){var 
n=window.webpackJsonp;window.webpackJsonp=function(r,c,u){for(var 
a,i,f,l=0,s=[];l<r.length;l++)t[i=r[l]]&&s.push(t[i][0]),t[i]=0;for(a in 
c)Object.prototype.hasOwnProperty.call(c,a)&&(e[a]=c[a]);for(n&&n(r,c,u);s.length;)s.shift()();if(u)for(l=0;l<u.length;l++)f=o(o.s=u[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],u=document.createElement("script");u.type="text/javascript",u.charset="utf-8",u.async=!0,u.timeout=12e4,o.nc&&u.setAttribute("nonce",o.nc),u.src=o.p+""+e+"."+{0:"1776646c6234f6c1c793",1:"aed76669724804835353"}[e]+".chunk.js";var
 a=setTimeout(i,12e4);function i(){u.onerror=u.onload=null,clearTimeout(a);var 
n=t[e];0!==n&&(n&&n[1](new Error("Loading chu
 nk "+e+" failed.")),t[e]=void 0)}return 
u.onerror=u.onload=i,c.appendChild(u),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/c3c0bf74/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
deleted file mode 100644
index 9de102a..0000000
--- 
a/gateway-applications/src/main/resources/applications/admin-ui/app/inline.c33f88beae0a6c65f63f.bundle.js
+++ /dev/null
@@ -1 +0,0 @@
-!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