KNOX-1040: Fixed refresh after descriptor saving, and added editable discovery fields to descriptor detail view
Project: http://git-wip-us.apache.org/repos/asf/knox/repo Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/faad66d1 Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/faad66d1 Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/faad66d1 Branch: refs/heads/master Commit: faad66d1239a4f4151b0433f5a8862064eee4210 Parents: ce710ae Author: Phil Zampino <pzamp...@apache.org> Authored: Wed Feb 7 21:00:02 2018 -0500 Committer: Phil Zampino <pzamp...@apache.org> Committed: Thu Feb 8 09:44:49 2018 -0500 ---------------------------------------------------------------------- .../src/app/resource-detail/descriptor.ts | 2 +- .../resource-detail.component.html | 99 +++++++++++++++++--- .../resource-detail.component.ts | 39 +++++++- .../src/app/resource/resource.service.ts | 8 -- .../applications/admin-ui/app/index.html | 2 +- .../app/inline.e0d8c7408caf97685893.bundle.js | 1 + .../app/inline.fc8062b5f4142b799c86.bundle.js | 1 - .../app/main.823edabc06e8cc0c56a3.bundle.js | 1 + .../app/main.d7a49b80ffa47171174f.bundle.js | 1 - 9 files changed, 122 insertions(+), 32 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/knox/blob/faad66d1/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 998265a..433c33b 100644 --- a/gateway-admin-ui/src/app/resource-detail/descriptor.ts +++ b/gateway-admin-ui/src/app/resource-detail/descriptor.ts @@ -42,7 +42,7 @@ export class Descriptor { } setProviderConfig(providerConfigRef: string) { - console.debug('Descriptor --> setProviderConfig() --> ' + providerConfigRef); + //console.debug('Descriptor --> setProviderConfig() --> ' + providerConfigRef); if (providerConfigRef !== this.providerConfig) { this.providerConfig = providerConfigRef; this.setDirty(); http://git-wip-us.apache.org/repos/asf/knox/blob/faad66d1/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 96f6efb..685a1a3 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 @@ -18,7 +18,9 @@ data-toggle="tooltip"></span> <div *ngIf="provider.show"> <b>Role</b> {{ provider.role }}<br> - <b>Enabled</b> {{ provider.enabled }}<br> + <b>Enabled</b> <input type="checkbox" + [checked]="isProviderEnabled(provider)" + (click)="onProviderEnabled(provider)"><br> <div> <span> </span> <span [class]="'clickable glyhpicon glyphicon-' + (provider.showParamDetails ? 'minus' : 'plus')" @@ -82,21 +84,28 @@ <div *ngIf="hasSelectedResource()"> <div> <div class="panel panel-default col-md-12"> - <span class="col-md-4"><b>Provider Configuration</b></span> - <span class="col-md-7"> - <input type="text" - id="textbox" - class="col-md-sm form-control input-sm" - (input)="descriptor.setDirty()" - [(ngModel)]="descriptor.providerConfig"/> - </span> - <span class="col-md-1 pull-left"> + <span class="col-md-12 pull-left"> + <span class="col-md-sm"><b>Provider Configuration</b> </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(descriptor,'providerConfig', providerConfig.value)"> + <span class="glyphicon glyphicon-ok"></span> + </button> + <button class="btn btn-xs" (click)="editModePC=false"> + <span class="glyphicon glyphicon-remove"></span> + </button> + </span> + <button id="chooseProviderConfig" - class="btn btn-default btn-xs glyphicon glyphicon-edit" + 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> @@ -170,10 +179,70 @@ <span><b>Discovery Details</b></span> <div class="col-md-12" *ngIf="showDiscDetails"> <table class="table table-sm"> - <tr><td>Discovery Address</td><td>{{ descriptor.discoveryAddress }}</td></tr> - <tr><td>Discovery User</td><td>{{ descriptor.discoveryUser }}</td></tr> - <tr><td>Discovery Password Alias</td><td>{{ descriptor.discoveryPassAlias }}</td></tr> - <tr><td>Discovery Cluster</td><td>{{ descriptor.discoveryCluster }}</td></tr> + <tr> + <td>Discovery Address</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(descriptor,'discoveryAddress', discoveryAddress.value)"> + <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>Discovery User</td> + <td> + <span class="clickable" (click)="editModeUser=true" *ngIf="!editModeUser">{{ descriptor.discoveryUser}}</span> + <span *ngIf="editModeUser"> + <input type="text" [ngModel]="descriptor.discoveryUser" #discoveryUser> + <button class="btn btn-xs" + (click)="editModeUser=false;onUpdateDescriptorProperty(descriptor,'discoveryUser', discoveryUser.value)"> + <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>Discovery Password Alias</td> + <td> + <span class="clickable" (click)="editModeAlias=true" *ngIf="!editModeAlias">{{ descriptor.discoveryPassAlias}}</span> + <span *ngIf="editModeAlias"> + <input type="text" [ngModel]="descriptor.discoveryPassAlias" #discoveryAlias> + <button class="btn btn-xs" + (click)="editModeAlias=false;onUpdateDescriptorProperty(descriptor,'discoveryPassAlias', discoveryAlias.value)"> + <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> + <tr> + <td>Discovery Cluster</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(descriptor,'discoveryCluster', discoveryCluster.value)"> + <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> </table> </div> </div> http://git-wip-us.apache.org/repos/asf/knox/blob/faad66d1/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 d2c7115..9f49ee7 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 @@ -52,7 +52,6 @@ export class ResourceDetailComponent implements OnInit { changedProviders: Array<ProviderConfig>; descriptor: Descriptor; - changedDescriptor: Descriptor; @ViewChild('choosePC') chooseProviderConfigModal: ProviderConfigSelectorComponent; @@ -80,7 +79,7 @@ export class ResourceDetailComponent implements OnInit { this.resource = res; this.providers = []; this.changedProviders = null; - this.descriptor = null; + this.descriptor = ResourceDetailComponent.emptyDescriptor; if (res) { this.resourceService.getResource(this.resourceType, res) .then(content => this.setResourceContent(res, content)) @@ -266,10 +265,16 @@ export class ResourceDetailComponent implements OnInit { break; } } - this.resourceService.saveResource(this.resource, content); - // Refresh the presentation - this.resourceService.selectedResource(this.resource); + // Save the updated content + this.resourceService.saveResource(this.resource, content) + .then(() => { + // Refresh the presentation + this.resourceService.selectedResource(this.resource); + }) + .catch(err => { + console.error('Error persisting ' + this.resource.name + ' : ' + err); + }); } @@ -372,6 +377,10 @@ export class ResourceDetailComponent implements OnInit { this.changedProviders = this.providers; } + onProviderEnabled(provider: ProviderConfig) { + provider.enabled = this.isProviderEnabled(provider) ? 'false' : 'true'; + this.changedProviders = this.providers; + } onRemoveProviderParam(pc: ProviderConfig, paramName: string) { //console.debug('ResourceDetailComponent --> onRemoveProviderParam() --> ' + pc.name + ' --> ' + paramName); @@ -435,6 +444,11 @@ export class ResourceDetailComponent implements OnInit { } } + onUpdateDescriptorProperty(desc: Descriptor, propertyName: string, value: string) { + desc[propertyName] = value; + desc.setDirty(); + } + getParamKeys(provider: ProviderConfig): string[] { let result = []; for(let key in provider.params){ @@ -457,6 +471,21 @@ export class ResourceDetailComponent implements OnInit { } + isProviderEnabled(pc: ProviderConfig): boolean { + let result: boolean = false; + + if (pc) { + if (typeof(pc.enabled) === 'string') { + let lowered = pc.enabled.toLowerCase().trim(); + result = (lowered === 'true'); + } else if (typeof(pc.enabled) === 'boolean') { + result = pc.enabled; + } + } + + return result; + } + hasSelectedResource(): boolean { return Boolean(this.resource) && Boolean(this.resource.name); } http://git-wip-us.apache.org/repos/asf/knox/blob/faad66d1/gateway-admin-ui/src/app/resource/resource.service.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/resource/resource.service.ts b/gateway-admin-ui/src/app/resource/resource.service.ts index 14a20d6..1b36823 100644 --- a/gateway-admin-ui/src/app/resource/resource.service.ts +++ b/gateway-admin-ui/src/app/resource/resource.service.ts @@ -20,7 +20,6 @@ import 'rxjs/add/operator/toPromise'; import { Subject } from 'rxjs/Subject'; import { Resource } from './resource'; import {ProviderConfig} from "../resource-detail/provider-config"; -import {Descriptor} from "../resource-detail/descriptor"; @Injectable() @@ -43,9 +42,6 @@ export class ResourceService { changedProviderConfigurationSource = new Subject<Array<ProviderConfig>>(); changedProviderConfiguration$ = this.changedProviderConfigurationSource.asObservable(); - changedDescriptorSource = new Subject<Descriptor>(); - changedDescriptor = this.changedDescriptorSource.asObservable(); - constructor(private http: HttpClient) { } getResources(resType: string): Promise<Resource[]> { @@ -220,10 +216,6 @@ export class ResourceService { this.changedProviderConfigurationSource.next(pc); } - descriptorChanged(desc: Descriptor) { - this.changedDescriptorSource.next(desc); - } - public getResourceDisplayName(res: Resource): string { if (res && res.name) { let index = res.name.lastIndexOf('.'); http://git-wip-us.apache.org/repos/asf/knox/blob/faad66d1/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 984782b..3f3d746 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 @@ -14,4 +14,4 @@ --><!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/1.12.4/jquery.min.js"></script><!-- Latest compiled and minified JavaScript --><sc ript 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><!-- <script src="assets/esprima.js"></script> <script src="assets/js-yaml.min.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></resource-management><footer class="footer"><div>Knox Manager Version 0.1.0</div><gateway-version></gateway-version></footer><script type="text/javascript" src="inline.fc8062b5f4142b799c86.bundle.js"></script><script type="text/javascript " src="scripts.c50bb762c438ae0f8842.bundle.js"></script><script type="text/javascript" src="main.d7a49b80ffa47171174f.bundle.js"></script></div></body></html> \ No newline at end of file + --><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></resource-management><footer class="footer"><div>Knox Manager Version 0.1.0</div><gateway-version></gateway-version></footer><script type="text/javascript" src="inline.e0d8c7408caf97685893.bundle.js"></script><script type="text/javascript " src="scripts.c50bb762c438ae0f8842.bundle.js"></script><script type="text/javascript" src="main.823edabc06e8cc0c56a3.bundle.js"></script></div></body></html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/faad66d1/gateway-applications/src/main/resources/applications/admin-ui/app/inline.e0d8c7408caf97685893.bundle.js ---------------------------------------------------------------------- diff --git a/gateway-applications/src/main/resources/applications/admin-ui/app/inline.e0d8c7408caf97685893.bundle.js b/gateway-applications/src/main/resources/applications/admin-ui/app/inline.e0d8c7408caf97685893.bundle.js new file mode 100644 index 0000000..56e9a9b --- /dev/null +++ b/gateway-applications/src/main/resources/applications/admin-ui/app/inline.e0d8c7408caf97685893.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:"823edabc06e8cc0c56a3",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 http://git-wip-us.apache.org/repos/asf/knox/blob/faad66d1/gateway-applications/src/main/resources/applications/admin-ui/app/inline.fc8062b5f4142b799c86.bundle.js ---------------------------------------------------------------------- diff --git a/gateway-applications/src/main/resources/applications/admin-ui/app/inline.fc8062b5f4142b799c86.bundle.js b/gateway-applications/src/main/resources/applications/admin-ui/app/inline.fc8062b5f4142b799c86.bundle.js deleted file mode 100644 index 5f025e5..0000000 --- a/gateway-applications/src/main/resources/applications/admin-ui/app/inline.fc8062b5f4142b799c86.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:"d7a49b80ffa47171174f",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