Skip to content

Commit

Permalink
[CE-38] Add chain detail functions for user dashboard
Browse files Browse the repository at this point in the history
Include below functions:

    1. Chain topology overview, include network latency show.
    2. Chain logs tracking.
    3. Chain blocks presentation and transactions reveal.
    4. Chain APIs list.
    5. Chaincode list, invoke and query.

Change-Id: I138205b807d747fc8f7a65a5937e1777ab6f6abd
Signed-off-by: lixucheng <[email protected]>
  • Loading branch information
xuchengli committed May 10, 2017
1 parent 64b7566 commit 0aabffd
Show file tree
Hide file tree
Showing 26 changed files with 2,332 additions and 0 deletions.
156 changes: 156 additions & 0 deletions user-dashboard/modules/chaincode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/**
* Created by lixuc on 2017/5/10.
*/
var rp = require("request-promise");
var config = require("./configuration");
var Pagination = require("../kit/pagination");
var dt = require("../kit/date-tool");

function chaincode(chainId) {
this.chainId = chainId;
}
chaincode.prototype = {
RESTfulURL: "http://" + config.RESTful_Server + config.RESTful_BaseURL,
PoolManagerURL: "http://" + config.PoolManager_Server + config.PoolManager_BaseURL,
list: function(page) {
return new Promise(function(resolve, reject) {
rp({
uri: this.RESTfulURL + "cluster/chaincode/deployed?cluster_id=" + this.chainId,
json: true
}).then(function(response) {
if (response.success) {
var cc = [];
var chain = response.result.cluster_info;
var chaincodes = response.result.chaincodes;
var pageNo = page || 1;
var pg = new Pagination(chaincodes);
chaincodes = pg.gotoPage(pageNo);
for (var i in chaincodes) {
cc.push({
id: chaincodes[i]["chaincode_id"],
name: chaincodes[i]["chaincode_name"],
contract: {
id: chaincodes[i]["contract_id"],
name: chaincodes[i]["contract_name"],
invoke: chaincodes[i]["contract_default_functions"]["invoke"] || [],
query: chaincodes[i]["contract_default_functions"]["query"] || []
},
deployTime: dt.diff2Now(chaincodes[i]["deploy_time"])
});
}
resolve({
success: true,
chain: {
name: chain["cluster_name"],
description: chain["cluster_description"]
},
chaincodes: cc,
totalNumber: pg.getTotalRow(),
totalPage: pg.getTotalPage()
});
} else {
var e = new Error(response.message);
e.status = 503;
throw e;
}
}).catch(function(err) {
reject({
success: false,
message: (err.status == 503 && err.message) || "System maintenance, please try again later!"
});
});
}.bind(this));
},
getAPIs: function() {
return new Promise(function(resolve, reject) {
rp({
uri: this.PoolManagerURL + "cluster/" + this.chainId,
json: true
}).then(function(response) {
if (response.status.toLowerCase() == "ok") {
var serviceUrl = response.data.service_url;
delete serviceUrl["ecaa"];
delete serviceUrl["ecap"];
delete serviceUrl["tcaa"];
delete serviceUrl["tcap"];
delete serviceUrl["tlscaa"];
delete serviceUrl["tlscap"];
resolve({
success: true,
serviceUrl: serviceUrl
});
} else {
var e = new Error(response.error);
e.status = 503;
throw e;
}
}).catch(function(err) {
reject({
success: false,
message: (err.status == 503 && err.message) || "System maintenance, please try again later!"
});
});
}.bind(this));
},
invoke: function(id, func, args) {
return new Promise(function(resolve, reject) {
rp({
method: "POST",
uri: this.RESTfulURL + "cluster/chaincode/invoke",
body: {
cluster_id: this.chainId,
chaincode_id: id,
func: func,
args: JSON.parse(args)
},
json: true
}).then(function(response) {
if (response.success) {
resolve(response);
} else {
var e = new Error(response.message);
e.status = 503;
throw e;
}
}).catch(function(err) {
reject({
success: false,
message: (err.status == 503 && err.message) || "System maintenance, please try again later!"
});
});
}.bind(this));
},
query: function(id, func, args) {
return new Promise(function(resolve, reject) {
rp({
method: "POST",
uri: this.RESTfulURL + "cluster/chaincode/query",
body: {
cluster_id: this.chainId,
chaincode_id: id,
func: func,
args: JSON.parse(args)
},
json: true
}).then(function(response) {
if (response.success) {
var result = response.result.response;
resolve({
success: true,
result: result
});
} else {
var e = new Error(response.message);
e.status = 503;
throw e;
}
}).catch(function(err) {
reject({
success: false,
message: (err.status == 503 && err.message) || "System maintenance, please try again later!"
});
});
}.bind(this));
}
};
module.exports = chaincode;
36 changes: 36 additions & 0 deletions user-dashboard/public/css/dashboard/chain-detail.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@CHARSET "UTF-8";
.ds-chain-main-container{width:80%;margin-top:60px;font-family:"Helvetica Neue",Arial,sans-serif;}
.ds-chain-main-container h1{font-size:24px;color:#4178BE;margin-top:42px;border-bottom:none;}
.ds-chain-main-container h1>label{color:#ADADAD;font-size:14px;}
.ds-chain-main h1>a{color:#4178BE;}
.ds-chain-main h2{font-size:18px;color:#296fb6;margin-bottom:30px;border-bottom:2px solid #296fb6;}
.ds-chain-main th{font-size:16px;color:#4178BE;}
.ds-chain-main thead :hover{color:#FF5003;}
.expand-compress-icon{margin-top:10px;cursor:pointer;}
.latency-show{position:absolute;bottom:0;right:10px;font-size:10px;font-weight:500;}
.log-badge{position:absolute;bottom:0;left:0;}
.log-badge-normal{background-color:#f7f7f7;color:#666;font-weight:inherit;}
.log-show{position:absolute;bottom:0;right:15px;font-size:10px;font-weight:500;}
ul.listico{margin:30px auto 0;border-top:2px solid #4178BE;overflow:hidden;width:200px;}
ul.listico li{float:left;width:46px;padding:12px 8px 10px 12px;list-style:none;}
ul.listico li a{display:block;padding-top:42px;height:32px;line-height:32px;text-align:center;}
ul.listico li a.ico0{background:url(/images/icon-deploy.png) no-repeat center 0;color:#ff6523;}
ul.listico li a.ico1{background:url(/images/icon-invoke.png) no-repeat center 0;color:#ff6523;}
ul.listico li a.ico2{background:url(/images/icon-query.png) no-repeat center 0;color:#ff6523;}
ul.listico li a.ico3{background:url(/images/icon-topo.png) no-repeat center 0;}
ul.listico li a.ico4{background:url(/images/icon-log.png) no-repeat center 0;}
ul.listico li a.ico5{background:url(/images/icon-bc.png) no-repeat center 0;}
ul.listico li a.ico6{background:url(/images/icon-apis.png) no-repeat center 0;}
.img-dropdown{margin-right:12px;margin-left:-2px;}
td.no-result{color:#b2b2b2;text-align:center;line-height:80px;font-style:italic;font-size:24px;}
.panel-overlayer{position:absolute;top:0;left:0;width:100%;height:100%;
background:#fafafa;opacity:0.3;border-radius:4px;z-index:999;}
.iconrefresh{position:absolute;width:20px;height:20px;top:50%;left:50%;margin-top:-10px;margin-left:-10px;}
.nodeDetail{background:#333 none repeat scroll 0 0;border-radius:3px;box-sizing:border-box;
color:rgba(255, 255, 255, 0.7);font-size:12px;line-height:18px;padding:5px 8px;text-shadow:0 1px 0 rgba(0, 0, 0, 0.5);}
.block{width:60px;height:60px;border:1px solid rgba(0, 0, 0, 0.25);box-shadow:0 0 6px rgba(0, 0, 0, 0.5);
background-color:rgba(255, 255, 255, 0.4);text-align:center;}
.block:hover{box-shadow:0px 0px 12px rgba(0,0,0,0.5);border:1px solid rgba(0,0,0,0.75);}
.block .symbol{position:absolute;top:35px;left:0px;right:0px;font-size:60px;font-weight:bold;color:rgba(0,0,0,0.7);
text-shadow:0 0 10px rgba(255,255,255,0.95);}
.notify-message{background:#444 none repeat scroll 0 0;border:1px solid #444;color:#fff;}
28 changes: 28 additions & 0 deletions user-dashboard/public/js/app/dashboard/chain/detail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Created by lixuc on 2017/5/10.
*/
define([
"jquery",
"app/dashboard/profile",
"app/dashboard/chain/detail/topology",
"app/dashboard/chain/detail/log",
"app/dashboard/chain/detail/blocks",
"app/dashboard/chain/detail/api",
"app/dashboard/chaincode/list",
"uikit"
], function($, Profile, Topology, Log, Blocks, API, Chaincodelist) {
$(function() {
new Profile();

var $chainId = $("#chainId");
var topology = new Topology($chainId.val());
var log = new Log($chainId.val());
var blocks = new Blocks($chainId.val());
new API();
new Chaincodelist($chainId.val());

topology.load();
log.load();
blocks.load();
});
});
40 changes: 40 additions & 0 deletions user-dashboard/public/js/app/dashboard/chain/detail/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Created by lixuc on 2017/5/10.
*/
define([
"jquery",
"app/dashboard/chain/detail/scrollspy",
"plugin/text!resources/dashboard/chain/detail/largeContainer.html"
], function($, Scrollspy, largeContainer) {
var scrollspy = new Scrollspy();
var $largeContainer;
var $expandCompressBtn;
var $apiPanel;

function api() {
$expandCompressBtn = $("#api .expand-compress-icon");
$apiPanel = $("#apiPanel");

$expandCompressBtn.on("click", function() {
$largeContainer = $(largeContainer);
$largeContainer.find(">div").append($apiPanel.detach().css("height", "450px"));
$largeContainer.on({
"hide.uk.modal": function() {
$("#api").after($apiPanel.detach().css("height", "300px"));
$(this).remove();
}
});
$("body").append($largeContainer);
var $container = UIkit.modal($largeContainer);
$container.options.center = true;
$container.show();
});
$apiPanel.on("inview.uk.scrollspy", function() {
scrollspy.select("apis", true);
});
$apiPanel.on("outview.uk.scrollspy", function() {
scrollspy.select("apis", false);
});
}
return api;
});
Loading

0 comments on commit 0aabffd

Please sign in to comment.