mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
Ability to customize order of visualization package display
This commit is contained in:
parent
cd7439618e
commit
e18d9a4d81
8 changed files with 295 additions and 19 deletions
|
|
@ -310,3 +310,69 @@ zeppelin-examples/zeppelin-example-clock/target/zeppelin-example-clock-0.7.0-SNA
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br />
|
||||
|
||||
### Get visualization display order
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method returns display order of enabled visualization packages.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/visualizationOrder```</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Success code</td>
|
||||
<td>200</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> Fail code</td>
|
||||
<td> 500 </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sample JSON response</td>
|
||||
<td>
|
||||
<code>{"status":"OK","body":["zeppelin_horizontalbar","zeppelin-bubblechart"]}</code>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
### Set visualization display order
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```POST``` method set visualization packages display order.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/visualizationOrder```</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Success code</td>
|
||||
<td>200</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> Fail code</td>
|
||||
<td> 500 </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sample JSON input</td>
|
||||
<td>
|
||||
<code>["zeppelin-bubblechart", "zeppelin_horizontalbar"]</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sample JSON response</td>
|
||||
<td>
|
||||
<code>{"status":"OK"}</code>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
@ -19,6 +19,7 @@ package org.apache.zeppelin.rest;
|
|||
|
||||
import com.github.eirslett.maven.plugins.frontend.lib.TaskRunnerException;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.zeppelin.helium.Helium;
|
||||
import org.apache.zeppelin.helium.HeliumPackage;
|
||||
|
|
@ -163,4 +164,26 @@ public class HeliumRestApi {
|
|||
return new JsonResponse(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()).build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("visualizationOrder")
|
||||
public Response getVisualizationPackageOrder() {
|
||||
List<String> order = helium.getVisualizationPackageOrder();
|
||||
return new JsonResponse(Response.Status.OK, order).build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("visualizationOrder")
|
||||
public Response setVisualizationPackageOrder(String orderedPackageNameList) {
|
||||
List<String> orderedList = gson.fromJson(
|
||||
orderedPackageNameList, new TypeToken<List<String>>(){}.getType());
|
||||
|
||||
try {
|
||||
helium.setVisualizationPackageOrder(orderedList);
|
||||
} catch (IOException | TaskRunnerException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return new JsonResponse(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()).build();
|
||||
}
|
||||
return new JsonResponse(Response.Status.OK).build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,12 +16,14 @@
|
|||
|
||||
angular.module('zeppelinWebApp').controller('HeliumCtrl', HeliumCtrl);
|
||||
|
||||
HeliumCtrl.$inject = ['$scope', '$rootScope', '$http', '$sce', 'baseUrlSrv', 'ngToast'];
|
||||
HeliumCtrl.$inject = ['$scope', '$rootScope', '$sce', 'baseUrlSrv', 'ngToast', 'heliumService'];
|
||||
|
||||
function HeliumCtrl($scope, $rootScope, $http, $sce, baseUrlSrv, ngToast) {
|
||||
function HeliumCtrl($scope, $rootScope, $sce, baseUrlSrv, ngToast, heliumService) {
|
||||
$scope.packageInfos = {};
|
||||
$scope.defaultVersions = {};
|
||||
$scope.showVersions = {};
|
||||
$scope.visualizationOrder = [];
|
||||
$scope.visualizationOrderChanged = false;
|
||||
|
||||
var buildDefaultVersionListToDisplay = function(packageInfos) {
|
||||
var defaultVersions = {};
|
||||
|
|
@ -48,7 +50,7 @@
|
|||
};
|
||||
|
||||
var getAllPackageInfo = function() {
|
||||
$http.get(baseUrlSrv.getRestApiBase() + '/helium/all').
|
||||
heliumService.getAllPackageInfo().
|
||||
success(function(data, status) {
|
||||
$scope.packageInfos = data.body;
|
||||
buildDefaultVersionListToDisplay($scope.packageInfos);
|
||||
|
|
@ -58,12 +60,63 @@
|
|||
});
|
||||
};
|
||||
|
||||
var getVisualizationOrder = function() {
|
||||
heliumService.getVisualizationOrder().
|
||||
success(function(data, status) {
|
||||
$scope.visualizationOrder = data.body;
|
||||
}).
|
||||
error(function(data, status) {
|
||||
console.log('Can not get visualization order %o %o', status, data);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.visualizationOrderListeners = {
|
||||
accept: function(sourceItemHandleScope, destSortableScope) {return true;},
|
||||
itemMoved: function(event) {},
|
||||
orderChanged: function(event) {
|
||||
$scope.visualizationOrderChanged = true;
|
||||
}
|
||||
};
|
||||
|
||||
var init = function() {
|
||||
getAllPackageInfo();
|
||||
getVisualizationOrder();
|
||||
$scope.visualizationOrderChanged = false;
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
$scope.saveVisualizationOrder = function() {
|
||||
var confirm = BootstrapDialog.confirm({
|
||||
closable: false,
|
||||
closeByBackdrop: false,
|
||||
closeByKeyboard: false,
|
||||
title: '',
|
||||
message: 'Save changes?',
|
||||
callback: function(result) {
|
||||
if (result) {
|
||||
confirm.$modalFooter.find('button').addClass('disabled');
|
||||
confirm.$modalFooter.find('button:contains("OK")')
|
||||
.html('<i class="fa fa-circle-o-notch fa-spin"></i> Enabling');
|
||||
heliumService.setVisualizationOrder($scope.visualizationOrder).
|
||||
success(function(data, status) {
|
||||
init();
|
||||
confirm.close();
|
||||
}).
|
||||
error(function(data, status) {
|
||||
confirm.close();
|
||||
console.log('Failed to save order');
|
||||
BootstrapDialog.show({
|
||||
title: 'Error on saving order ',
|
||||
message: data.message
|
||||
});
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$scope.enable = function(name, artifact) {
|
||||
var confirm = BootstrapDialog.confirm({
|
||||
closable: false,
|
||||
|
|
@ -76,9 +129,9 @@
|
|||
confirm.$modalFooter.find('button').addClass('disabled');
|
||||
confirm.$modalFooter.find('button:contains("OK")')
|
||||
.html('<i class="fa fa-circle-o-notch fa-spin"></i> Enabling');
|
||||
$http.post(baseUrlSrv.getRestApiBase() + '/helium/enable/' + name, artifact).
|
||||
heliumService.enable(name, artifact).
|
||||
success(function(data, status) {
|
||||
getAllPackageInfo();
|
||||
init();
|
||||
confirm.close();
|
||||
}).
|
||||
error(function(data, status) {
|
||||
|
|
@ -107,9 +160,9 @@
|
|||
confirm.$modalFooter.find('button').addClass('disabled');
|
||||
confirm.$modalFooter.find('button:contains("OK")')
|
||||
.html('<i class="fa fa-circle-o-notch fa-spin"></i> Disabling');
|
||||
$http.post(baseUrlSrv.getRestApiBase() + '/helium/disable/' + name).
|
||||
heliumService.disable(name).
|
||||
success(function(data, status) {
|
||||
getAllPackageInfo();
|
||||
init();
|
||||
confirm.close();
|
||||
}).
|
||||
error(function(data, status) {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,12 @@
|
|||
float: left;
|
||||
}
|
||||
|
||||
.heliumPackageList .heliumPackageName span {
|
||||
font-size: 10px;
|
||||
color: #AAAAAA;
|
||||
}
|
||||
|
||||
|
||||
.heliumPackageList .heliumPackageDisabledArtifact {
|
||||
color:gray;
|
||||
}
|
||||
|
|
@ -45,9 +51,50 @@
|
|||
color:#444444;
|
||||
}
|
||||
|
||||
.heliumPackageList .heliumPackageVersions {
|
||||
.heliumPackageList .heliumPackageEnabledArtifact span,
|
||||
.heliumPackageList .heliumPackageDisabledArtifact span {
|
||||
margin-left:3px;
|
||||
cursor:pointer;
|
||||
text-decoration:
|
||||
underline;color:#3071a9
|
||||
}
|
||||
|
||||
.heliumPackageList .heliumPackageDescription {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.heliumVisualizationOrder {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.heliumVisualizationOrder .as-sortable-item,
|
||||
.heliumVisualizationOrder .as-sortable-placeholder {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.heliumVisualizationOrder .as-sortable-item-handle {
|
||||
width: 35px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.heliumVisualizationOrder .sortable-row:after {
|
||||
content: ".";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.heliumVisualizationOrder .as-sortable-item svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.heliumVisualizationOrder .saveLink {
|
||||
margin-left:10px;
|
||||
margin-top:5px;
|
||||
cursor:pointer;
|
||||
text-decoration:
|
||||
underline;color:#3071a9
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,26 @@ limitations under the License.
|
|||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-show="visualizationOrder.length > 1"
|
||||
class="row heliumVisualizationOrder">
|
||||
<div class="col-md-12 sortable-row btn-group"
|
||||
as-sortable="visualizationOrderListeners"
|
||||
data-ng-model="visualizationOrder">
|
||||
<div style="margin-bottom:5px">Visualization package display order (drag and drop to reorder)</div>
|
||||
<div class="btn-group" data-ng-repeat="pkgName in visualizationOrder"
|
||||
as-sortable-item>
|
||||
<div class="btn btn-default btn-sm"
|
||||
ng-bind-html='defaultVersions[pkgName].pkg.icon'
|
||||
as-sortable-item-handle>
|
||||
</div>
|
||||
</div>
|
||||
<a class="saveLink"
|
||||
ng-show="visualizationOrderChanged"
|
||||
ng-click="saveVisualizationOrder()">
|
||||
save
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -30,7 +50,7 @@ limitations under the License.
|
|||
<div class="heliumPackageHead">
|
||||
<div class="heliumPackageIcon"
|
||||
ng-bind-html=pkgInfo.pkg.icon></div>
|
||||
<div class="heliumPackageName">{{pkgName}}</div>
|
||||
<div class="heliumPackageName">{{pkgName}} <span>{{pkgInfo.pkg.type}}</span></div>
|
||||
<div ng-show="!pkgInfo.enabled"
|
||||
ng-click="enable(pkgName, pkgInfo.pkg.artifact)"
|
||||
class="btn btn-success btn-xs"
|
||||
|
|
@ -43,8 +63,7 @@ limitations under the License.
|
|||
<div ng-class="{heliumPackageDisabledArtifact: !pkgInfo.enabled, heliumPackageEnabledArtifact: pkgInfo.enabled}">
|
||||
{{pkgInfo.pkg.artifact}}
|
||||
<span ng-show="packageInfos[pkgName].length > 0"
|
||||
ng-click="toggleVersions(pkgName)"
|
||||
style="margin-left:3px;cursor:pointer;text-decoration: underline;color:#3071a9">
|
||||
ng-click="toggleVersions(pkgName)">
|
||||
Versions
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -38,5 +38,25 @@
|
|||
this.get = function() {
|
||||
return visualizations;
|
||||
};
|
||||
|
||||
this.getVisualizationOrder = function() {
|
||||
return $http.get(baseUrlSrv.getRestApiBase() + '/helium/visualizationOrder');
|
||||
};
|
||||
|
||||
this.setVisualizationOrder = function(list) {
|
||||
return $http.post(baseUrlSrv.getRestApiBase() + '/helium/visualizationOrder', list);
|
||||
};
|
||||
|
||||
this.getAllPackageInfo = function() {
|
||||
return $http.get(baseUrlSrv.getRestApiBase() + '/helium/all');
|
||||
};
|
||||
|
||||
this.enable = function(name, artifact) {
|
||||
return $http.post(baseUrlSrv.getRestApiBase() + '/helium/enable/' + name, artifact);
|
||||
};
|
||||
|
||||
this.disable = function(name) {
|
||||
return $http.post(baseUrlSrv.getRestApiBase() + '/helium/disable/' + name);
|
||||
};
|
||||
};
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ public class Helium {
|
|||
public synchronized void save() throws IOException {
|
||||
String jsonString;
|
||||
synchronized (registry) {
|
||||
clearNotExistsPackages();
|
||||
heliumConf.setRegistry(registry);
|
||||
jsonString = gson.toJson(heliumConf);
|
||||
}
|
||||
|
|
@ -131,6 +132,28 @@ public class Helium {
|
|||
FileUtils.writeStringToFile(heliumConfFile, jsonString);
|
||||
}
|
||||
|
||||
private void clearNotExistsPackages() {
|
||||
Map<String, List<HeliumPackageSearchResult>> all = getAllPackageInfo();
|
||||
|
||||
// clear visualization display order
|
||||
List<String> packageOrder = heliumConf.getVisualizationDisplayOrder();
|
||||
List<String> clearedOrder = new LinkedList<>();
|
||||
for (String pkgName : packageOrder) {
|
||||
if (all.containsKey(pkgName)) {
|
||||
clearedOrder.add(pkgName);
|
||||
}
|
||||
}
|
||||
heliumConf.setVisualizationDisplayOrder(clearedOrder);
|
||||
|
||||
// clear enabled package
|
||||
Map<String, String> enabledPackages = heliumConf.getEnabledPackages();
|
||||
for (String pkgName : enabledPackages.keySet()) {
|
||||
if (!all.containsKey(pkgName)) {
|
||||
heliumConf.disablePackage(pkgName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, List<HeliumPackageSearchResult>> getAllPackageInfo() {
|
||||
Map<String, String> enabledPackageInfo = heliumConf.getEnabledPackages();
|
||||
|
||||
|
|
@ -301,4 +324,29 @@ public class Helium {
|
|||
|
||||
return orderedVisualizationPackages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get enabled package list in order
|
||||
* @return
|
||||
*/
|
||||
public List<String> getVisualizationPackageOrder() {
|
||||
List orderedPackageList = new LinkedList<>();
|
||||
List<HeliumPackage> packages = getVisualizationPackagesToBundle();
|
||||
|
||||
for (HeliumPackage pkg : packages) {
|
||||
orderedPackageList.add(pkg.getName());
|
||||
}
|
||||
|
||||
return orderedPackageList;
|
||||
}
|
||||
|
||||
public void setVisualizationPackageOrder(List<String> orderedPackageList)
|
||||
throws IOException, TaskRunnerException {
|
||||
heliumConf.setVisualizationDisplayOrder(orderedPackageList);
|
||||
|
||||
// if package is visualization, rebuild bundle
|
||||
visualizationFactory.bundle(getVisualizationPackagesToBundle());
|
||||
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,14 +60,14 @@ public class HeliumConf {
|
|||
}
|
||||
|
||||
public List<String> getVisualizationDisplayOrder() {
|
||||
return visualizationDisplayOrder;
|
||||
if (visualizationDisplayOrder == null) {
|
||||
return new LinkedList<String>();
|
||||
} else {
|
||||
return visualizationDisplayOrder;
|
||||
}
|
||||
}
|
||||
|
||||
public void setVisualizationDisplayOrder(List<HeliumPackage> orderedPackageList) {
|
||||
List<String> order = new LinkedList<>();
|
||||
for (HeliumPackage pkg : orderedPackageList) {
|
||||
order.add(pkg.getName());
|
||||
}
|
||||
visualizationDisplayOrder = order;
|
||||
public void setVisualizationDisplayOrder(List<String> orderedPackageList) {
|
||||
visualizationDisplayOrder = orderedPackageList;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue