mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
feat: Support helium conf in frontend
This commit is contained in:
parent
dea29295c7
commit
3aa6c54735
12 changed files with 596 additions and 95 deletions
100
zeppelin-web/src/app/helium/helium.config.js
Normal file
100
zeppelin-web/src/app/helium/helium.config.js
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export const HeliumConfFieldType = {
|
||||
NUMBER: 'number',
|
||||
JSON: 'json',
|
||||
STRING: 'string',
|
||||
};
|
||||
|
||||
/**
|
||||
* @param persisted <Object> including `type`, `description`, `defaultValue` for each conf key
|
||||
* @param spec <Object> including `value` for each conf key
|
||||
*/
|
||||
export function mergePersistedConfWithSpec(persisted, spec) {
|
||||
const confs = [];
|
||||
|
||||
for(let name in spec) {
|
||||
const specField = spec[name];
|
||||
const persistedValue = persisted[name];
|
||||
|
||||
const value = (persistedValue) ? persistedValue : specField.defaultValue;
|
||||
const merged = {
|
||||
name: name, type: specField.type, description: specField.description,
|
||||
value: value, defaultValue: specField.defaultValue,
|
||||
};
|
||||
|
||||
confs.push(merged);
|
||||
}
|
||||
|
||||
return confs;
|
||||
}
|
||||
|
||||
export function createPackageConf(defaultPackages, persistedPackacgeConfs) {
|
||||
let packageConfs = {};
|
||||
|
||||
for (let name in defaultPackages) {
|
||||
const pkgInfo = defaultPackages[name];
|
||||
|
||||
const configSpec = pkgInfo.pkg.config;
|
||||
if (!configSpec) { continue; }
|
||||
|
||||
const version = pkgInfo.pkg.version;
|
||||
if (!version) { continue; }
|
||||
|
||||
let config = {};
|
||||
if (persistedPackacgeConfs[name] && persistedPackacgeConfs[name][version]) {
|
||||
config = persistedPackacgeConfs[name][version];
|
||||
}
|
||||
|
||||
const confs = mergePersistedConfWithSpec(config, configSpec);
|
||||
packageConfs[name] = confs;
|
||||
}
|
||||
|
||||
return packageConfs;
|
||||
}
|
||||
|
||||
export function parseConfigValue(type, stringified) {
|
||||
let value = stringified;
|
||||
|
||||
try {
|
||||
if (HeliumConfFieldType.NUMBER === type) {
|
||||
value = parseFloat(stringified);
|
||||
} else if (HeliumConfFieldType.JSON === type) {
|
||||
value = JSON.parse(stringified);
|
||||
}
|
||||
} catch(error) {
|
||||
// return just the stringified one
|
||||
console.error(`Failed to parse conf type ${type}, value ${value}`);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* create persistable config object
|
||||
*/
|
||||
export function createPersistableConfig(currentConf) {
|
||||
// persist key-value only
|
||||
// since other info (e.g type, desc) can be provided by default config
|
||||
const filtered = currentConf.reduce((acc, c) => {
|
||||
let value = parseConfigValue(c.type, c.value);
|
||||
acc[c.name] = value;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -14,61 +14,36 @@
|
|||
|
||||
import { HeliumType, } from '../../components/helium/helium-type';
|
||||
|
||||
angular.module('zeppelinWebApp').controller('HeliumCtrl', HeliumCtrl);
|
||||
|
||||
function HeliumCtrl($scope, $rootScope, $sce, baseUrlSrv, ngToast, heliumService) {
|
||||
export default function HeliumCtrl($scope, $rootScope, $sce,
|
||||
baseUrlSrv, ngToast, heliumService) {
|
||||
'ngInject';
|
||||
|
||||
$scope.packageInfos = {};
|
||||
$scope.defaultVersions = {};
|
||||
$scope.pkgSearchResults = {};
|
||||
$scope.defaultPackages = {};
|
||||
$scope.showVersions = {};
|
||||
$scope.bundleOrder = [];
|
||||
$scope.bundleOrderChanged = false;
|
||||
$scope.defaultPackageConfigs = {}; // { pkgName, [{name, type, desc, value, defaultValue}] }
|
||||
|
||||
var buildDefaultVersionListToDisplay = function(packageInfos) {
|
||||
var defaultVersions = {};
|
||||
// show enabled version if any version of package is enabled
|
||||
for (var name in packageInfos) {
|
||||
var pkgs = packageInfos[name];
|
||||
for (var pkgIdx in pkgs) {
|
||||
var pkg = pkgs[pkgIdx];
|
||||
pkg.pkg.icon = $sce.trustAsHtml(pkg.pkg.icon);
|
||||
if (pkg.enabled) {
|
||||
defaultVersions[name] = pkg;
|
||||
pkgs.splice(pkgIdx, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
function init() {
|
||||
// get all package info and set config
|
||||
heliumService.getAllPackageInfoAndDefaultPackages()
|
||||
.then(({ pkgSearchResults, defaultPackages }) => {
|
||||
$scope.pkgSearchResults = pkgSearchResults;
|
||||
$scope.defaultPackages = defaultPackages;
|
||||
return heliumService.getAllPackageConfigs()
|
||||
})
|
||||
.then(defaultPackageConfigs => {
|
||||
$scope.defaultPackageConfigs = defaultPackageConfigs;
|
||||
});
|
||||
|
||||
// show first available version if package is not enabled
|
||||
if (!defaultVersions[name]) {
|
||||
defaultVersions[name] = pkgs[0];
|
||||
pkgs.splice(0, 1);
|
||||
}
|
||||
}
|
||||
$scope.defaultVersions = defaultVersions;
|
||||
};
|
||||
|
||||
var getAllPackageInfo = function() {
|
||||
heliumService.getAllPackageInfo().
|
||||
success(function(data, status) {
|
||||
$scope.packageInfos = data.body;
|
||||
buildDefaultVersionListToDisplay($scope.packageInfos);
|
||||
}).
|
||||
error(function(data, status) {
|
||||
console.log('Can not load package info %o %o', status, data);
|
||||
});
|
||||
};
|
||||
|
||||
var getBundleOrder = function() {
|
||||
heliumService.getVisualizationPackageOrder().
|
||||
success(function(data, status) {
|
||||
$scope.bundleOrder = data.body;
|
||||
}).
|
||||
error(function(data, status) {
|
||||
console.log('Can not get bundle order %o %o', status, data);
|
||||
});
|
||||
};
|
||||
// 2. get vis package order
|
||||
heliumService.getVisualizationPackageOrder()
|
||||
.then(visPackageOrder => {
|
||||
$scope.bundleOrder = visPackageOrder;
|
||||
$scope.bundleOrderChanged = false;
|
||||
});
|
||||
}
|
||||
|
||||
$scope.bundleOrderListeners = {
|
||||
accept: function(sourceItemHandleScope, destSortableScope) {return true;},
|
||||
|
|
@ -78,14 +53,6 @@ function HeliumCtrl($scope, $rootScope, $sce, baseUrlSrv, ngToast, heliumService
|
|||
}
|
||||
};
|
||||
|
||||
var init = function() {
|
||||
getAllPackageInfo();
|
||||
getBundleOrder();
|
||||
$scope.bundleOrderChanged = false;
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
$scope.saveBundleOrder = function() {
|
||||
var confirm = BootstrapDialog.confirm({
|
||||
closable: false,
|
||||
|
|
@ -115,24 +82,24 @@ function HeliumCtrl($scope, $rootScope, $sce, baseUrlSrv, ngToast, heliumService
|
|||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var getLicense = function(name, artifact) {
|
||||
var pkg = _.filter($scope.defaultVersions[name], function(p) {
|
||||
var filteredPkgSearchResults = _.filter($scope.defaultPackages[name], function(p) {
|
||||
return p.artifact === artifact;
|
||||
});
|
||||
|
||||
var license;
|
||||
if (pkg.length === 0) {
|
||||
pkg = _.filter($scope.packageInfos[name], function(p) {
|
||||
if (filteredPkgSearchResults.length === 0) {
|
||||
filteredPkgSearchResults = _.filter($scope.pkgSearchResults[name], function(p) {
|
||||
return p.pkg.artifact === artifact;
|
||||
});
|
||||
|
||||
if (pkg.length > 0) {
|
||||
license = pkg[0].pkg.license;
|
||||
if (filteredPkgSearchResults.length > 0) {
|
||||
license = filteredPkgSearchResults[0].pkg.license;
|
||||
}
|
||||
} else {
|
||||
license = pkg[0].license;
|
||||
license = filteredPkgSearchResults[0].license;
|
||||
}
|
||||
|
||||
if (!license) {
|
||||
|
|
@ -226,4 +193,46 @@ function HeliumCtrl($scope, $rootScope, $sce, baseUrlSrv, ngToast, heliumService
|
|||
return (pkg.type === HeliumType.SPELL || pkg.type === HeliumType.VISUALIZATION) &&
|
||||
!$scope.isLocalPackage(pkgSearchResult);
|
||||
};
|
||||
|
||||
$scope.configExists = function(pkgSearchResult) {
|
||||
// helium package config is persisted per version
|
||||
return pkgSearchResult.pkg.config && pkgSearchResult.pkg.version;
|
||||
};
|
||||
|
||||
$scope.configOpened = function(pkgSearchResult) {
|
||||
return pkgSearchResult.configOpened;
|
||||
};
|
||||
|
||||
$scope.toggleConfigButton = function(pkgSearchResult) {
|
||||
if (pkgSearchResult.configOpened) {
|
||||
pkgSearchResult.configOpened = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const pkg = pkgSearchResult.pkg;
|
||||
const pkgName = pkg.name;
|
||||
const pkgVersion = pkg.version;
|
||||
|
||||
if (!pkgName || !pkgVersion) {
|
||||
console.error(`Failed to fetch config for '${pkgSearchResult}@${pkgVersion}'`);
|
||||
return;
|
||||
}
|
||||
|
||||
heliumService.getSinglePackageConfig(pkgName, pkgVersion)
|
||||
.then(conf => {
|
||||
$scope.defaultPackageConfigs[pkgName] = conf;
|
||||
pkgSearchResult.configOpened = true;
|
||||
$scope.$digest(); // to trigger view update
|
||||
});
|
||||
};
|
||||
|
||||
$scope.saveConfig = function(pkgSearchResult) {
|
||||
const pkgName = pkgSearchResult.pkg.name;
|
||||
const pkgVersion = pkgSearchResult.pkg.version;
|
||||
const currentConf = $scope.defaultPackageConfigs[pkgName];
|
||||
|
||||
heliumService.saveConfig(pkgName, pkgVersion, currentConf);
|
||||
};
|
||||
|
||||
init();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,6 +79,10 @@
|
|||
width: 500px;
|
||||
}
|
||||
|
||||
.spellConfigButton {
|
||||
background-color: #FEFEFE;
|
||||
}
|
||||
|
||||
.heliumPackageList .heliumPackageDisabledArtifact {
|
||||
color:gray;
|
||||
}
|
||||
|
|
@ -132,4 +136,21 @@
|
|||
color: #636363;
|
||||
}
|
||||
|
||||
.heliumConfig {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.heliumConfigTable {
|
||||
margin-top: 15px;
|
||||
vertical-align:middle;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.heliumConfigValueInput {
|
||||
|
||||
}
|
||||
|
||||
.heliumConfigValueText {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ limitations under the License.
|
|||
<div class="btn-group" data-ng-repeat="pkgName in bundleOrder"
|
||||
as-sortable-item>
|
||||
<div class="btn btn-default btn-sm"
|
||||
ng-bind-html='defaultVersions[pkgName].pkg.icon'
|
||||
ng-bind-html='defaultPackages[pkgName].pkg.icon'
|
||||
as-sortable-item-handle>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -45,32 +45,37 @@ limitations under the License.
|
|||
|
||||
<div class="box width-full heliumPackageContainer">
|
||||
<div class="row heliumPackageList"
|
||||
ng-repeat="(pkgName, pkgInfo) in defaultVersions">
|
||||
ng-repeat="(pkgName, pkgSearchResult) in defaultPackages">
|
||||
|
||||
<div class="col-md-12">
|
||||
<div class="heliumPackageHead">
|
||||
<div class="heliumPackageIcon"
|
||||
ng-bind-html=pkgInfo.pkg.icon></div>
|
||||
ng-bind-html=pkgSearchResult.pkg.icon></div>
|
||||
<div class="heliumPackageName">
|
||||
<span ng-if="hasNpmLink(pkgInfo)">
|
||||
<span ng-if="hasNpmLink(pkgSearchResult)">
|
||||
<a target="_blank" href="https://www.npmjs.com/package/{{pkgName}}">{{pkgName}}</a>
|
||||
</span>
|
||||
<span ng-if="!hasNpmLink(pkgInfo)" ng-class="{'heliumLocalPackage': isLocalPackage(pkgInfo)}">
|
||||
<span ng-if="!hasNpmLink(pkgSearchResult)" ng-class="{'heliumLocalPackage': isLocalPackage(pkgSearchResult)}">
|
||||
{{pkgName}}
|
||||
</span>
|
||||
<span class="heliumType">{{pkgInfo.pkg.type}}</span>
|
||||
<span class="heliumType">{{pkgSearchResult.pkg.type}}</span>
|
||||
</div>
|
||||
<div ng-show="!pkgInfo.enabled"
|
||||
ng-click="enable(pkgName, pkgInfo.pkg.artifact)"
|
||||
<div ng-show="!pkgSearchResult.enabled"
|
||||
ng-click="enable(pkgName, pkgSearchResult.pkg.artifact)"
|
||||
class="btn btn-success btn-xs"
|
||||
style="float:right">Enable</div>
|
||||
<div ng-show="pkgInfo.enabled"
|
||||
<div ng-show="pkgSearchResult.enabled"
|
||||
ng-click="disable(pkgName)"
|
||||
class="btn btn-info btn-xs"
|
||||
style="float:right">Disable</div>
|
||||
<div ng-show="configExists(pkgSearchResult)"
|
||||
ng-click="toggleConfigButton(pkgSearchResult)"
|
||||
class="btn btn-default btn-xs spellConfigButton"
|
||||
style="float:right; margin-right:5px;">Config</div>
|
||||
</div>
|
||||
<div ng-class="{heliumPackageDisabledArtifact: !pkgInfo.enabled, heliumPackageEnabledArtifact: pkgInfo.enabled}">
|
||||
{{pkgInfo.pkg.artifact}}
|
||||
<span ng-show="packageInfos[pkgName].length > 0"
|
||||
<div ng-class="{heliumPackageDisabledArtifact: !pkgSearchResult.enabled, heliumPackageEnabledArtifact: pkgSearchResult.enabled}">
|
||||
{{pkgSearchResult.pkg.artifact}}
|
||||
<span ng-show="pkgSearchResults[pkgName].length > 0"
|
||||
ng-click="toggleVersions(pkgName)">
|
||||
versions
|
||||
</span>
|
||||
|
|
@ -78,28 +83,64 @@ limitations under the License.
|
|||
<ul class="heliumPackageVersions"
|
||||
ng-show="showVersions[pkgName]">
|
||||
<li class="heliumPackageDisabledArtifact"
|
||||
ng-repeat="pkg in packageInfos[pkgName]">
|
||||
{{pkg.pkg.artifact}} -
|
||||
<span ng-click="enable(pkgName, pkg.pkg.artifact)"
|
||||
ng-repeat="pkgSearchResult in pkgSearchResults[pkgName]">
|
||||
{{pkgSearchResult.pkg.artifact}} -
|
||||
<span ng-click="enable(pkgName, pkgSearchResult.pkg.artifact)"
|
||||
style="margin-left:3px;cursor:pointer;text-decoration: underline;color:#3071a9">
|
||||
enable
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="heliumPackageDescription">
|
||||
{{pkgInfo.pkg.description}}
|
||||
{{pkgSearchResult.pkg.description}}
|
||||
</div>
|
||||
<div ng-if="pkgInfo.pkg.type === 'SPELL' && pkgInfo.pkg.spell"
|
||||
<div ng-if="pkgSearchResult.pkg.type === 'SPELL' && pkgSearchResult.pkg.spell"
|
||||
class="spellInfo">
|
||||
<div>
|
||||
<span class="spellInfoDesc">MAGIC</span>
|
||||
<span class="spellInfoValue">{{pkgInfo.pkg.spell.magic}} </span>
|
||||
<span class="spellInfoValue">{{pkgSearchResult.pkg.spell.magic}} </span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="spellInfoDesc">USAGE</span>
|
||||
<pre class="spellUsage">{{pkgInfo.pkg.spell.usage}} </pre>
|
||||
<pre class="spellUsage">{{pkgSearchResult.pkg.spell.usage}} </pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--start: config-->
|
||||
<div class="heliumConfig" ng-if="configOpened(pkgSearchResult)">
|
||||
<h5>Configuration</h5>
|
||||
<table class="heliumConfigTable table table-striped">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
<tr>
|
||||
</tr>
|
||||
<tr data-ng-repeat="cfg in defaultPackageConfigs[pkgSearchResult.pkg.name]">
|
||||
<td style="vertical-align: middle;">{{cfg.name}}</td>
|
||||
<td style="vertical-align: middle;">{{cfg.type}}</td>
|
||||
<td style="vertical-align: middle;">{{cfg.description}}</td>
|
||||
<td>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" style="border-radius: 5px;"
|
||||
data-ng-model="cfg.value" placeholder="{{cfg.defaultValue}}" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div>
|
||||
<button class="btn btn-primary"
|
||||
ng-click="saveConfig(pkgSearchResult)">Save</button>
|
||||
<button class="btn btn-default"
|
||||
ng-click="toggleConfigButton(pkgSearchResult)">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
<!--end: config-->
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
19
zeppelin-web/src/app/helium/index.js
Normal file
19
zeppelin-web/src/app/helium/index.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import HeliumController from './helium.controller';
|
||||
|
||||
angular.module('zeppelinWebApp')
|
||||
.controller('HeliumCtrl', HeliumController);
|
||||
|
||||
|
|
@ -237,7 +237,7 @@ function ParagraphCtrl($scope, $rootScope, $route, $window, $routeParams, $locat
|
|||
}
|
||||
};
|
||||
|
||||
$scope.runParagraphUsingSpell = function(spell, paragraphText,
|
||||
$scope.runParagraphUsingSpell = function(paragraphText,
|
||||
magic, digestRequired, propagated) {
|
||||
$scope.paragraph.results = {};
|
||||
$scope.paragraph.errorMessage = '';
|
||||
|
|
@ -248,6 +248,8 @@ function ParagraphCtrl($scope, $rootScope, $route, $window, $routeParams, $locat
|
|||
const splited = paragraphText.split(magic);
|
||||
// remove leading spaces
|
||||
const textWithoutMagic = splited[1].replace(/^\s+/g, '');
|
||||
|
||||
const spell = heliumService.getSpellByMagic(magic);
|
||||
const spellResult = spell.interpret(textWithoutMagic);
|
||||
const parsed = spellResult.getAllParsedDataWithTypes(
|
||||
heliumService.getAllSpells(), magic, textWithoutMagic);
|
||||
|
|
@ -312,8 +314,7 @@ function ParagraphCtrl($scope, $rootScope, $route, $window, $routeParams, $locat
|
|||
const spell = heliumService.getSpellByMagic(magic);
|
||||
|
||||
if (spell) {
|
||||
$scope.runParagraphUsingSpell(
|
||||
spell, paragraphText, magic, digestRequired, propagated);
|
||||
$scope.runParagraphUsingSpell(paragraphText, magic, digestRequired, propagated);
|
||||
} else {
|
||||
$scope.runParagraphUsingBackendInterpreter(paragraphText);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export const HeliumConfFieldType = {
|
||||
NUMBER: 'number',
|
||||
JSON: 'json',
|
||||
STRING: 'string',
|
||||
};
|
||||
|
||||
/**
|
||||
* @param persisted <Object> including `type`, `description`, `defaultValue` for each conf key
|
||||
* @param spec <Object> including `value` for each conf key
|
||||
*/
|
||||
export function mergePersistedConfWithSpec(persisted, spec) {
|
||||
const confs = [];
|
||||
|
||||
for(let name in spec) {
|
||||
const specField = spec[name];
|
||||
const persistedValue = persisted[name];
|
||||
|
||||
const value = (persistedValue) ? persistedValue : specField.defaultValue;
|
||||
const merged = {
|
||||
name: name, type: specField.type, description: specField.description,
|
||||
value: value, defaultValue: specField.defaultValue,
|
||||
};
|
||||
|
||||
confs.push(merged);
|
||||
}
|
||||
|
||||
return confs;
|
||||
}
|
||||
|
||||
export function createSinglePackageConfig(pkg, persistedConf) {
|
||||
const spec = pkg.config;
|
||||
if (!spec) { return; }
|
||||
|
||||
const version = pkg.version;
|
||||
if (!version) { return; }
|
||||
|
||||
if (!persistedConf) { persistedConf = {}; }
|
||||
|
||||
return mergePersistedConfWithSpec(persistedConf, spec);
|
||||
}
|
||||
|
||||
export function createAllPackageConfigs(defaultPackages, persistedConfs) {
|
||||
let packageConfs = {};
|
||||
|
||||
for (let name in defaultPackages) {
|
||||
const pkgSearchResult = defaultPackages[name];
|
||||
|
||||
const spec = pkgSearchResult.pkg.config;
|
||||
if (!spec) { continue; }
|
||||
|
||||
const version = pkgSearchResult.pkg.version;
|
||||
if (!version) { continue; }
|
||||
|
||||
let persistedConf = {};
|
||||
if (persistedConfs[name] && persistedConfs[name][version]) {
|
||||
persistedConf = persistedConfs[name][version];
|
||||
}
|
||||
|
||||
const confs = mergePersistedConfWithSpec(persistedConf, spec);
|
||||
packageConfs[name] = confs;
|
||||
}
|
||||
|
||||
return packageConfs;
|
||||
}
|
||||
|
||||
export function parseConfigValue(type, stringified) {
|
||||
let value = stringified;
|
||||
|
||||
try {
|
||||
if (HeliumConfFieldType.NUMBER === type) {
|
||||
value = parseFloat(stringified);
|
||||
} else if (HeliumConfFieldType.JSON === type) {
|
||||
value = JSON.parse(stringified);
|
||||
}
|
||||
} catch(error) {
|
||||
// return just the stringified one
|
||||
console.error(`Failed to parse conf type ${type}, value ${value}`);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* persist key-value only
|
||||
* since other info (e.g type, desc) can be provided by default config
|
||||
*/
|
||||
export function createPersistableConfig(currentConf) {
|
||||
const filtered = currentConf.reduce((acc, c) => {
|
||||
acc[c.name] = parseConfigValue(c.type, c.value);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import { HeliumType, } from './helium-type';
|
||||
|
||||
export function createDefaultPackage(pkgSearchResult, sce) {
|
||||
for (let pkgIdx in pkgSearchResult) {
|
||||
const pkg = pkgSearchResult[pkgIdx];
|
||||
pkg.pkg.icon = sce.trustAsHtml(pkg.pkg.icon);
|
||||
if (pkg.enabled) {
|
||||
pkgSearchResult.splice(pkgIdx, 1);
|
||||
return pkg;
|
||||
}
|
||||
}
|
||||
|
||||
// show first available version if package is not enabled
|
||||
const result = pkgSearchResult[0];
|
||||
pkgSearchResult.splice(0, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* create default packages based on `enabled` field and `latest` version.
|
||||
*
|
||||
* @param pkgSearchResults
|
||||
* @param sce angular `$sce` object
|
||||
* @returns {Object} including {name, pkgInfo}
|
||||
*/
|
||||
export function createDefaultPackages(pkgSearchResults, sce) {
|
||||
const defaultPackages = {};
|
||||
// show enabled version if any version of package is enabled
|
||||
for (let name in pkgSearchResults) {
|
||||
const pkgSearchResult = pkgSearchResults[name];
|
||||
defaultPackages[name] = createDefaultPackage(pkgSearchResult, sce)
|
||||
}
|
||||
|
||||
return defaultPackages;
|
||||
}
|
||||
|
||||
export function findPackageByMagic(pkgSearchResults, magic) {
|
||||
return pkgSearchResults.find(psr => {
|
||||
psr.pkg.type === HeliumType.SPELL && psr.pkg.spell.magic === magic;
|
||||
});
|
||||
}
|
||||
|
||||
export function findPackageByVersion(singlePkgSearchResults, version) {
|
||||
return singlePkgSearchResults.find(psr => {
|
||||
return psr.pkg.version === version;
|
||||
});
|
||||
}
|
||||
|
|
@ -13,16 +13,27 @@
|
|||
*/
|
||||
|
||||
import { HeliumType, } from './helium-type';
|
||||
import {
|
||||
createAllPackageConfigs,
|
||||
createSinglePackageConfig,
|
||||
createPersistableConfig,
|
||||
} from './helium-conf';
|
||||
import {
|
||||
createDefaultPackages,
|
||||
findPackageByVersion,
|
||||
findPackageByMagic,
|
||||
} from './helium-package';
|
||||
|
||||
angular.module('zeppelinWebApp').service('heliumService', heliumService);
|
||||
|
||||
function heliumService($http, baseUrlSrv, ngToast) {
|
||||
export default function heliumService($http, $sce, baseUrlSrv) {
|
||||
'ngInject';
|
||||
|
||||
var url = baseUrlSrv.getRestApiBase() + '/helium/bundle/load';
|
||||
if (process.env.HELIUM_BUNDLE_DEV) {
|
||||
url = url + '?refresh=true';
|
||||
}
|
||||
|
||||
// name `heliumBundles` should be same as `HelumBundleFactory.HELIUM_BUNDLES_VAR`
|
||||
var heliumBundles = [];
|
||||
// map for `{ magic: interpreter }`
|
||||
|
|
@ -68,18 +79,23 @@ function heliumService($http, baseUrlSrv, ngToast) {
|
|||
return visualizationBundles;
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {Promise} which returns bundleOrder
|
||||
*/
|
||||
this.getVisualizationPackageOrder = function() {
|
||||
return $http.get(baseUrlSrv.getRestApiBase() + '/helium/order/visualization');
|
||||
return $http.get(baseUrlSrv.getRestApiBase() + '/helium/order/visualization')
|
||||
.then(function(response, status) {
|
||||
return response.data.body;
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.error('Can not get bundle order', error);
|
||||
});
|
||||
};
|
||||
|
||||
this.setVisualizationPackageOrder = function(list) {
|
||||
return $http.post(baseUrlSrv.getRestApiBase() + '/helium/order/visualization', 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);
|
||||
};
|
||||
|
|
@ -87,4 +103,127 @@ function heliumService($http, baseUrlSrv, ngToast) {
|
|||
this.disable = function(name) {
|
||||
return $http.post(baseUrlSrv.getRestApiBase() + '/helium/disable/' + name);
|
||||
};
|
||||
|
||||
this.saveConfig = function(pkgName, pkgVersion, defaultPackageConfig) {
|
||||
const filtered = createPersistableConfig(defaultPackageConfig);
|
||||
|
||||
if (!pkgName || !pkgVersion || !filtered) {
|
||||
console.error(
|
||||
`Can't save helium package '${pkgName}@${pkgVersion}' config`, filtered);
|
||||
return;
|
||||
}
|
||||
|
||||
const url = `${baseUrlSrv.getRestApiBase()}/helium/config/${pkgName}/${pkgVersion}`;
|
||||
return $http.post(url, filtered);
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {Promise<Object>} which including {name, Array<package info for version>}
|
||||
*/
|
||||
this.getAllPackageInfo = function() {
|
||||
return $http.get(`${baseUrlSrv.getRestApiBase()}/helium/package`)
|
||||
.then(function(response, status) {
|
||||
return response.data.body;
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.error('Failed to get all package infos', error);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {Promise<Array>} which including package info list for all versions
|
||||
*/
|
||||
this.getSinglePackageInfo = function(pkgName, pkgVersion) {
|
||||
return $http.get(`${baseUrlSrv.getRestApiBase()}/helium/package/${pkgName}`)
|
||||
.then(response => {
|
||||
return response.data.body;
|
||||
})
|
||||
.then(singlePkgSearchResults => {
|
||||
const found = findPackageByVersion(singlePkgSearchResults, pkgVersion);
|
||||
|
||||
if (!found) {
|
||||
throw new Error(`Could not find package info for '${pkgName}@${pkgVersion}'`);
|
||||
}
|
||||
|
||||
return found;
|
||||
});
|
||||
};
|
||||
|
||||
this.getDefaultPackages = function() {
|
||||
return this.getAllPackageInfo()
|
||||
.then(pkgSearchResults => {
|
||||
return createDefaultPackages(pkgSearchResults, $sce);
|
||||
});
|
||||
};
|
||||
|
||||
this.getAllPackageInfoAndDefaultPackages = function() {
|
||||
return this.getAllPackageInfo()
|
||||
.then(pkgSearchResults => {
|
||||
return {
|
||||
pkgSearchResults: pkgSearchResults,
|
||||
defaultPackages: createDefaultPackages(pkgSearchResults, $sce),
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* get all package configs.
|
||||
* @return Promise<{name, {version, {confKey, confVal}}}>
|
||||
*/
|
||||
this.getAllPackageConfigs = function() {
|
||||
const promisedDefaultPackages = this.getDefaultPackages();
|
||||
const promisedPersistedConfs =
|
||||
$http.get(`${baseUrlSrv.getRestApiBase()}/helium/config`)
|
||||
.then(function(response, status) {
|
||||
return response.data.body;
|
||||
});
|
||||
|
||||
return Promise.all([promisedDefaultPackages, promisedPersistedConfs])
|
||||
.then(values => {
|
||||
const defaultPackages = values[0];
|
||||
const persistedConfs = values[1];
|
||||
|
||||
return createAllPackageConfigs(defaultPackages, persistedConfs);
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.error('Failed to get all package configs', error);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* get the package config which is persisted in server.
|
||||
* @return Promise<{confKey, confVal}>
|
||||
*/
|
||||
this.getSinglePackageConfig = function(pkgName, pkgVersion) {
|
||||
const promisedPkgSearchResult = this.getSinglePackageInfo(pkgName, pkgVersion);
|
||||
|
||||
const confUrl = `${baseUrlSrv.getRestApiBase()}/helium/config/${pkgName}/${pkgVersion}`;
|
||||
const promisedConf = $http.get(confUrl)
|
||||
.then(function(response, status) {
|
||||
return response.data.body;
|
||||
});
|
||||
|
||||
return Promise.all([promisedPkgSearchResult, promisedConf])
|
||||
.then(values => {
|
||||
const pkgSearchResult = values[0];
|
||||
const persistedConf = values[1];
|
||||
|
||||
const merged = createSinglePackageConfig(pkgSearchResult.pkg, persistedConf);
|
||||
return merged;
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.error(`Failed to get package config for '${pkgName}@${pkgVersion}'`, error);
|
||||
});
|
||||
};
|
||||
|
||||
this.getSinglePackageConfigUsingMagic = function(magic) {
|
||||
this.getDefaultPackages()
|
||||
.then(defaultPackages => {
|
||||
const pkgSearchResult = findPackageByMagic(defaultPackages, magic)
|
||||
const pkgVersion = pkgSearchResult.pkg.version;
|
||||
const pkgName = pkgSearchResult.pkg.name;
|
||||
|
||||
return this.getSinglePackageConfig(pkgName, pkgVersion);
|
||||
})
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,6 +166,8 @@ function websocketEvents($rootScope, $websocket, $location, baseUrlSrv) {
|
|||
$rootScope.$broadcast('setNoteRevisionResult', data);
|
||||
} else if (op === 'PARAS_INFO') {
|
||||
$rootScope.$broadcast('updateParaInfos', data);
|
||||
} else {
|
||||
console.error(`unknown websocket op: ${op}`);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ function websocketMsgSrv($rootScope, websocketEvents) {
|
|||
|
||||
getInterpreterSettings: function() {
|
||||
websocketEvents.sendNewEvent({op: 'GET_INTERPRETER_SETTINGS'});
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import './app/home/home.controller.js';
|
|||
import './app/handsontable/handsonHelper.js';
|
||||
import './app/notebook/notebook.controller.js';
|
||||
|
||||
/** start: global variable `zeppelin` related files */
|
||||
import './app/tabledata/tabledata.js';
|
||||
import './app/tabledata/transformation.js';
|
||||
import './app/tabledata/pivot.js';
|
||||
|
|
@ -32,7 +31,6 @@ import './app/visualization/builtins/visualization-piechart.js';
|
|||
import './app/visualization/builtins/visualization-areachart.js';
|
||||
import './app/visualization/builtins/visualization-linechart.js';
|
||||
import './app/visualization/builtins/visualization-scatterchart.js';
|
||||
/** end: global variable `zeppelin` related files */
|
||||
|
||||
import './app/jobmanager/jobmanager.controller.js';
|
||||
import './app/jobmanager/jobs/job.controller.js';
|
||||
|
|
@ -45,7 +43,7 @@ import './app/notebook/paragraph/paragraph.controller.js';
|
|||
import './app/notebook/paragraph/result/result.controller.js';
|
||||
import './app/search/result-list.controller.js';
|
||||
import './app/notebookRepos/notebookRepos.controller.js';
|
||||
import './app/helium/helium.controller.js';
|
||||
import './app/helium';
|
||||
import './components/arrayOrderingSrv/arrayOrdering.service.js';
|
||||
import './components/clipboard/clipboard.controller.js';
|
||||
import './components/navbar/navbar.controller.js';
|
||||
|
|
|
|||
Loading…
Reference in a new issue