| <!-- |
| Copyright 2016 The LUCI Authors. All rights reserved. |
| Use of this source code is governed under the Apache License, Version 2.0 |
| that can be found in the LICENSE file. |
| --> |
| |
| <link rel="import" href="../bower_components/polymer/polymer.html"> |
| <link rel="import" href="../bower_components/google-signin/google-signin-aware.html"> |
| |
| <link rel="import" href="../rpc/rpc-client.html"> |
| |
| <link rel="import" href="rpc-descriptor-util.html"> |
| <link rel="import" href="rpc-editor.html"> |
| |
| <!-- The `rpc-method` is a service method page --> |
| <dom-module id="rpc-method"> |
| <template> |
| <style> |
| rpc-editor { |
| height: 300px; |
| } |
| button { |
| margin: 5px; |
| } |
| </style> |
| |
| <div on-keypress="_onKeypress"> |
| <rpc-client |
| id="client" |
| service="[[service]]" |
| method="[[method]]" |
| request="[[requestObject]]" |
| on-response="_onCallComplete" |
| on-error="_onCallComplete"> |
| </rpc-client> |
| <div>[[methodDesc.sourceCodeInfo.leadingComments]]</div> |
| <hr> |
| |
| <p>Request:</p> |
| <div class="row"> |
| <div class="col-md-7"> |
| <rpc-editor value="{{requestText}}" |
| description="[[description]]" |
| root-type-name="[[requestTypeName]]"></rpc-editor> |
| </div> |
| <div class="col-md-3"> |
| <p>Ctrl+Space for Autocomplete</p> |
| <p>Shift+Enter for Send</p> |
| </div> |
| </div> |
| |
| <div> |
| <button on-tap="send">Send</button> |
| </div> |
| |
| <div class="alert alert-danger" role="alert" hidden="[[!error]]"> |
| <template is="dom-if" if="[[error.isGrpcError]]"> |
| <div> |
| Code: [[error.code]] |
| <template is="dom-if" if="[[error.codeName]]"> |
| ([[error.codeName]]) |
| </template> |
| </div> |
| <div>Description: [[error.description]]</div> |
| </template> |
| |
| <template is="dom-if" if="[[!error.isGrpcError]]"> |
| [[error]] |
| </template> |
| </div> |
| |
| <div class="row"> |
| <div class="col-md-7"> |
| <rpc-editor value="[[responseText]]"></rpc-editor> |
| </div> |
| </div> |
| </div> |
| </template> |
| |
| <script> |
| 'use strict'; |
| |
| Polymer({ |
| is: 'rpc-method', |
| |
| properties: { |
| /** @type {FileDescriptorSet} */ |
| description: Object, |
| |
| service: String, |
| |
| method: String, |
| |
| /** @type {MethodDescriptorProto} */ |
| methodDesc: { |
| type: Object, |
| computed: '_resolveMethod(description, service, method)' |
| }, |
| |
| requestTypeName: { |
| type: String, |
| computed: '_getRequestTypeName(methodDesc)' |
| }, |
| |
| /** "request" query string parameter. */ |
| request: { |
| type: String, |
| value: '{}', |
| observer: '_onRequestChanged', |
| notify: true |
| }, |
| |
| /** Request editor text. */ |
| requestText: String, |
| |
| /** Parsed from requestText. */ |
| requestObject: Object, |
| |
| /** Response editor text. */ |
| responseText: String, |
| |
| error: { |
| type: Object, |
| value: null |
| } |
| }, |
| |
| _resolveMethod: function(desc, service, method) { |
| if (!desc || !service || !method) { |
| return null; |
| } |
| var methodDesc = rpcExplorer.descUtil.resolve( |
| desc, service + '.' + method); |
| return methodDesc && methodDesc.type === 'method' && methodDesc.desc; |
| }, |
| |
| _getRequestTypeName: function(methodDesc) { |
| return (methodDesc && |
| rpcExplorer.descUtil.trimPrefixDot(methodDesc.inputType)); |
| }, |
| |
| _onRequestChanged: function() { |
| try { |
| this.requestObject = JSON.parse(this.request); |
| } catch (e) { |
| console.error('Invalid request: ' + this.request); |
| this.requestText = this.request; |
| return; |
| } |
| |
| // Reformat the request read from query string parameter |
| // because it gets corrupted there. |
| this.requestText = JSON.stringify(this.requestObject, null, 4); |
| }, |
| |
| _onKeypress: function(e) { |
| if (e.key === 'Enter' && e.shiftKey) { |
| this.send(); |
| e.preventDefault(); |
| } |
| }, |
| |
| getAccessToken: function() { |
| var user = gapi.auth2.getAuthInstance().currentUser.get(); |
| if (!user) { |
| return null; |
| } |
| return user.getAuthResponse().access_token; |
| }, |
| |
| send: function() { |
| this.error = null; |
| try { |
| this.requestObject = JSON.parse(this.requestText); |
| |
| // Reformat request |
| this.requestText = JSON.stringify(this.requestObject, null, 4); |
| |
| // Update URL without a refresh. |
| history.replaceState( |
| history.state, document.title, "?request=" + this.requestText); |
| |
| this.$.client.accessToken = this.getAccessToken(); |
| |
| // Actually send the request. |
| this.$.client.call(); |
| } catch (e) { |
| this.error = e; |
| console.error(this.error) |
| } |
| }, |
| |
| _onCallComplete: function() { |
| var client = this.$.client; |
| if (client.lastError) { |
| console.error(client.lastError); |
| } |
| |
| if (client.lastResponse) { |
| this.responseText = JSON.stringify(client.lastResponse, null, 4); |
| } else { |
| this.responseText = ''; |
| } |
| |
| this.error = client.lastError; |
| if (this.error instanceof luci.rpc.GrpcError) { |
| this.error = { |
| isGrpcError: true, |
| code: this.error.code, |
| codeName: luci.rpc.CodeName(this.error.code), |
| description: this.error.description |
| }; |
| } |
| } |
| }); |
| </script> |
| </dom-module> |