http://git-wip-us.apache.org/repos/asf/zeppelin/blob/19b0f30f/zeppelin-web/src/app/notebook/paragraph/result/result.controller.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/paragraph/result/result.controller.js b/zeppelin-web/src/app/notebook/paragraph/result/result.controller.js index 5708339..71104b5 100644 --- a/zeppelin-web/src/app/notebook/paragraph/result/result.controller.js +++ b/zeppelin-web/src/app/notebook/paragraph/result/result.controller.js @@ -12,25 +12,25 @@ * limitations under the License. */ -import TableData from '../../../tabledata/tabledata'; -import TableVisualization from '../../../visualization/builtins/visualization-table'; -import BarchartVisualization from '../../../visualization/builtins/visualization-barchart'; -import PiechartVisualization from '../../../visualization/builtins/visualization-piechart'; -import AreachartVisualization from '../../../visualization/builtins/visualization-areachart'; -import LinechartVisualization from '../../../visualization/builtins/visualization-linechart'; -import ScatterchartVisualization from '../../../visualization/builtins/visualization-scatterchart'; +import TableData from '../../../tabledata/tabledata' +import TableVisualization from '../../../visualization/builtins/visualization-table' +import BarchartVisualization from '../../../visualization/builtins/visualization-barchart' +import PiechartVisualization from '../../../visualization/builtins/visualization-piechart' +import AreachartVisualization from '../../../visualization/builtins/visualization-areachart' +import LinechartVisualization from '../../../visualization/builtins/visualization-linechart' +import ScatterchartVisualization from '../../../visualization/builtins/visualization-scatterchart' import { DefaultDisplayType, SpellResult, } from '../../../spell' -import { ParagraphStatus, } from '../paragraph.status'; +import { ParagraphStatus, } from '../paragraph.status' -angular.module('zeppelinWebApp').controller('ResultCtrl', ResultCtrl); +angular.module('zeppelinWebApp').controller('ResultCtrl', ResultCtrl) -function ResultCtrl($scope, $rootScope, $route, $window, $routeParams, $location, +function ResultCtrl ($scope, $rootScope, $route, $window, $routeParams, $location, $timeout, $compile, $http, $q, $templateRequest, $sce, websocketMsgSrv, baseUrlSrv, ngToast, saveAsService, noteVarShareService, heliumService) { - 'ngInject'; + 'ngInject' /** * Built-in visualizations @@ -70,12 +70,12 @@ function ResultCtrl($scope, $rootScope, $route, $window, $routeParams, $location name: 'Scatter Chart', icon: '<i class="cf cf-scatter-chart"></i>' } - ]; + ] /** * Holds class and actual runtime instance and related infos of built-in visualizations */ - var builtInVisualizations = { + let builtInVisualizations = { 'table': { class: TableVisualization, instance: undefined // created from setGraphMode() @@ -100,95 +100,95 @@ function ResultCtrl($scope, $rootScope, $route, $window, $routeParams, $location class: ScatterchartVisualization, instance: undefined } - }; + } // type - $scope.type; + $scope.type = null // Data of the result - var data; + let data // config - $scope.config; + $scope.config = null // resultId = paragraph.id + index - $scope.id; + $scope.id = null // referece to paragraph - var paragraph; + let paragraph // index of the result - var resultIndex; + let resultIndex // TableData instance - var tableData; + let tableData // available columns in tabledata - $scope.tableDataColumns = []; + $scope.tableDataColumns = [] // enable helium - var enableHelium = false; + let enableHelium = false // graphMode - $scope.graphMode; + $scope.graphMode = null // image data - $scope.imageData; + $scope.imageData = null // queue for append output - const textResultQueueForAppend = []; + const textResultQueueForAppend = [] - $scope.init = function(result, config, paragraph, index) { + $scope.init = function (result, config, paragraph, index) { // register helium plugin vis - var visBundles = heliumService.getVisualizationBundles(); - visBundles.forEach(function(vis) { + let visBundles = heliumService.getVisualizationBundles() + visBundles.forEach(function (vis) { $scope.builtInTableDataVisualizationList.push({ id: vis.id, name: vis.name, icon: $sce.trustAsHtml(vis.icon) - }); + }) builtInVisualizations[vis.id] = { class: vis.class - }; - }); + } + }) - updateData(result, config, paragraph, index); - renderResult($scope.type); - }; + updateData(result, config, paragraph, index) + renderResult($scope.type) + } - function isDOMLoaded(targetElemId) { - const elem = angular.element(`#${targetElemId}`); - return elem.length; + function isDOMLoaded (targetElemId) { + const elem = angular.element(`#${targetElemId}`) + return elem.length } - function retryUntilElemIsLoaded(targetElemId, callback) { - function retry() { + function retryUntilElemIsLoaded (targetElemId, callback) { + function retry () { if (!isDOMLoaded(targetElemId)) { - $timeout(retry, 10); - return; + $timeout(retry, 10) + return } - const elem = angular.element(`#${targetElemId}`); - callback(elem); + const elem = angular.element(`#${targetElemId}`) + callback(elem) } - $timeout(retry); + $timeout(retry) } - $scope.$on('updateResult', function(event, result, newConfig, paragraphRef, index) { + $scope.$on('updateResult', function (event, result, newConfig, paragraphRef, index) { if (paragraph.id !== paragraphRef.id || index !== resultIndex) { - return; + return } - var refresh = !angular.equals(newConfig, $scope.config) || + let refresh = !angular.equals(newConfig, $scope.config) || !angular.equals(result.type, $scope.type) || - !angular.equals(result.data, data); + !angular.equals(result.data, data) - updateData(result, newConfig, paragraph, resultIndex); - renderResult($scope.type, refresh); - }); + updateData(result, newConfig, paragraph, resultIndex) + renderResult($scope.type, refresh) + }) - $scope.$on('appendParagraphOutput', function(event, data) { + $scope.$on('appendParagraphOutput', function (event, data) { /* It has been observed that append events * can be errorneously called even if paragraph * execution has ended, and in that case, no append @@ -200,159 +200,158 @@ function ResultCtrl($scope, $rootScope, $route, $window, $routeParams, $location if (paragraph.id === data.paragraphId && resultIndex === data.index && (paragraph.status === ParagraphStatus.PENDING || paragraph.status === ParagraphStatus.RUNNING)) { - if (DefaultDisplayType.TEXT !== $scope.type) { - $scope.type = DefaultDisplayType.TEXT; + $scope.type = DefaultDisplayType.TEXT } - appendTextOutput(data.data); + appendTextOutput(data.data) } - }); + }) - var updateData = function(result, config, paragraphRef, index) { - data = result.data; - paragraph = paragraphRef; - resultIndex = parseInt(index); + const updateData = function (result, config, paragraphRef, index) { + data = result.data + paragraph = paragraphRef + resultIndex = parseInt(index) - $scope.id = paragraph.id + '_' + index; - $scope.type = result.type; - config = config ? config : {}; + $scope.id = paragraph.id + '_' + index + $scope.type = result.type + config = config ? config : {} // initialize default config values if (!config.graph) { - config.graph = {}; + config.graph = {} } if (!config.graph.mode) { - config.graph.mode = 'table'; + config.graph.mode = 'table' } if (!config.graph.height) { - config.graph.height = 300; + config.graph.height = 300 } if (!config.graph.optionOpen) { - config.graph.optionOpen = false; + config.graph.optionOpen = false } - $scope.graphMode = config.graph.mode; - $scope.config = angular.copy(config); + $scope.graphMode = config.graph.mode + $scope.config = angular.copy(config) // enable only when it is last result - enableHelium = (index === paragraphRef.results.msg.length - 1); + enableHelium = (index === paragraphRef.results.msg.length - 1) if ($scope.type === 'TABLE') { - tableData = new TableData(); - tableData.loadParagraphResult({type: $scope.type, msg: data}); - $scope.tableDataColumns = tableData.columns; - $scope.tableDataComment = tableData.comment; + tableData = new TableData() + tableData.loadParagraphResult({type: $scope.type, msg: data}) + $scope.tableDataColumns = tableData.columns + $scope.tableDataComment = tableData.comment } else if ($scope.type === 'IMG') { - $scope.imageData = data; + $scope.imageData = data } - }; + } - $scope.createDisplayDOMId = function(baseDOMId, type) { + $scope.createDisplayDOMId = function (baseDOMId, type) { if (type === DefaultDisplayType.TABLE) { - return `${baseDOMId}_graph`; + return `${baseDOMId}_graph` } else if (type === DefaultDisplayType.HTML) { - return `${baseDOMId}_html`; + return `${baseDOMId}_html` } else if (type === DefaultDisplayType.ANGULAR) { - return `${baseDOMId}_angular`; + return `${baseDOMId}_angular` } else if (type === DefaultDisplayType.TEXT) { - return `${baseDOMId}_text`; + return `${baseDOMId}_text` } else if (type === DefaultDisplayType.ELEMENT) { - return `${baseDOMId}_elem`; + return `${baseDOMId}_elem` } else { - console.error(`Cannot create display DOM Id due to unknown display type: ${type}`); + console.error(`Cannot create display DOM Id due to unknown display type: ${type}`) } - }; + } - $scope.renderDefaultDisplay = function(targetElemId, type, data, refresh) { + $scope.renderDefaultDisplay = function (targetElemId, type, data, refresh) { const afterLoaded = () => { if (type === DefaultDisplayType.TABLE) { - renderGraph(targetElemId, $scope.graphMode, refresh); + renderGraph(targetElemId, $scope.graphMode, refresh) } else if (type === DefaultDisplayType.HTML) { - renderHtml(targetElemId, data); + renderHtml(targetElemId, data) } else if (type === DefaultDisplayType.ANGULAR) { - renderAngular(targetElemId, data); + renderAngular(targetElemId, data) } else if (type === DefaultDisplayType.TEXT) { - renderText(targetElemId, data); + renderText(targetElemId, data) } else if (type === DefaultDisplayType.ELEMENT) { - renderElem(targetElemId, data); + renderElem(targetElemId, data) } else { - console.error(`Unknown Display Type: ${type}`); + console.error(`Unknown Display Type: ${type}`) } } - retryUntilElemIsLoaded(targetElemId, afterLoaded); + retryUntilElemIsLoaded(targetElemId, afterLoaded) // send message to parent that this result is rendered - const paragraphId = $scope.$parent.paragraph.id; - $scope.$emit('resultRendered', paragraphId); - }; + const paragraphId = $scope.$parent.paragraph.id + $scope.$emit('resultRendered', paragraphId) + } - const renderResult = function(type, refresh) { - let activeApp; + const renderResult = function (type, refresh) { + let activeApp if (enableHelium) { - getSuggestions(); - getApplicationStates(); - activeApp = _.get($scope.config, 'helium.activeApp'); + getSuggestions() + getApplicationStates() + activeApp = _.get($scope.config, 'helium.activeApp') } if (activeApp) { - const appState = _.find($scope.apps, {id: activeApp}); - renderApp(`p${appState.id}`, appState); + const appState = _.find($scope.apps, {id: activeApp}) + renderApp(`p${appState.id}`, appState) } else { if (!DefaultDisplayType[type]) { - $scope.renderCustomDisplay(type, data); + $scope.renderCustomDisplay(type, data) } else { - const targetElemId = $scope.createDisplayDOMId(`p${$scope.id}`, type); - $scope.renderDefaultDisplay(targetElemId, type, data, refresh); + const targetElemId = $scope.createDisplayDOMId(`p${$scope.id}`, type) + $scope.renderDefaultDisplay(targetElemId, type, data, refresh) } } - }; + } - $scope.isDefaultDisplay = function() { - return DefaultDisplayType[$scope.type]; - }; + $scope.isDefaultDisplay = function () { + return DefaultDisplayType[$scope.type] + } /** * Render multiple sub results for custom display */ - $scope.renderCustomDisplay = function(type, data) { + $scope.renderCustomDisplay = function (type, data) { // get result from intp if (!heliumService.getSpellByMagic(type)) { - console.error(`Can't execute spell due to unknown display type: ${type}`); - return; + console.error(`Can't execute spell due to unknown display type: ${type}`) + return } // custom display result can include multiple subset results heliumService.executeSpellAsDisplaySystem(type, data) .then(dataWithTypes => { - const containerDOMId = `p${$scope.id}_custom`; + const containerDOMId = `p${$scope.id}_custom` const afterLoaded = () => { - const containerDOM = angular.element(`#${containerDOMId}`); + const containerDOM = angular.element(`#${containerDOMId}`) // Spell.interpret() can create multiple outputs - for(let i = 0; i < dataWithTypes.length; i++) { - const dt = dataWithTypes[i]; - const data = dt.data; - const type = dt.type; + for (let i = 0; i < dataWithTypes.length; i++) { + const dt = dataWithTypes[i] + const data = dt.data + const type = dt.type // prepare each DOM to be filled - const subResultDOMId = $scope.createDisplayDOMId(`p${$scope.id}_custom_${i}`, type); - const subResultDOM = document.createElement('div'); - containerDOM.append(subResultDOM); - subResultDOM.setAttribute('id', subResultDOMId); + const subResultDOMId = $scope.createDisplayDOMId(`p${$scope.id}_custom_${i}`, type) + const subResultDOM = document.createElement('div') + containerDOM.append(subResultDOM) + subResultDOM.setAttribute('id', subResultDOMId) - $scope.renderDefaultDisplay(subResultDOMId, type, data, true); + $scope.renderDefaultDisplay(subResultDOMId, type, data, true) } - }; + } - retryUntilElemIsLoaded(containerDOMId, afterLoaded); + retryUntilElemIsLoaded(containerDOMId, afterLoaded) }) .catch(error => { - console.error(`Failed to render custom display: ${$scope.type}\n` + error); - }); - }; + console.error(`Failed to render custom display: ${$scope.type}\n` + error) + }) + } /** * generates actually object which will be consumed from `data` property @@ -364,271 +363,269 @@ function ResultCtrl($scope, $rootScope, $route, $window, $routeParams, $location * @param successCallback * @param failureCallback */ - const handleData = function(data, type, successCallback, failureCallback) { + const handleData = function (data, type, successCallback, failureCallback) { if (SpellResult.isFunction(data)) { try { - successCallback(data()); + successCallback(data()) } catch (error) { - failureCallback(error); - console.error(`Failed to handle ${type} type, function data\n`, error); + failureCallback(error) + console.error(`Failed to handle ${type} type, function data\n`, error) } } else if (SpellResult.isObject(data)) { try { - successCallback(data); + successCallback(data) } catch (error) { - console.error(`Failed to handle ${type} type, object data\n`, error); + console.error(`Failed to handle ${type} type, object data\n`, error) } } - }; + } - const renderElem = function(targetElemId, data) { - const elem = angular.element(`#${targetElemId}`); + const renderElem = function (targetElemId, data) { + const elem = angular.element(`#${targetElemId}`) handleData(() => { data(targetElemId) }, DefaultDisplayType.ELEMENT, () => {}, /** HTML element will be filled with data. thus pass empty success callback */ - (error) => { elem.html(`${error.stack}`); } - ); - }; + (error) => { elem.html(`${error.stack}`) } + ) + } - const renderHtml = function(targetElemId, data) { - const elem = angular.element(`#${targetElemId}`); + const renderHtml = function (targetElemId, data) { + const elem = angular.element(`#${targetElemId}`) handleData(data, DefaultDisplayType.HTML, (generated) => { - elem.html(generated); - elem.find('pre code').each(function(i, e) { - hljs.highlightBlock(e); - }); - /*eslint new-cap: [2, {"capIsNewExceptions": ["MathJax.Hub.Queue"]}]*/ - MathJax.Hub.Queue(['Typeset', MathJax.Hub, elem[0]]); + elem.html(generated) + elem.find('pre code').each(function (i, e) { + hljs.highlightBlock(e) + }) + /* eslint new-cap: [2, {"capIsNewExceptions": ["MathJax.Hub.Queue"]}] */ + MathJax.Hub.Queue(['Typeset', MathJax.Hub, elem[0]]) }, - (error) => { elem.html(`${error.stack}`); } - ); - }; + (error) => { elem.html(`${error.stack}`) } + ) + } - const renderAngular = function(targetElemId, data) { - const elem = angular.element(`#${targetElemId}`); - const paragraphScope = noteVarShareService.get(`${paragraph.id}_paragraphScope`); + const renderAngular = function (targetElemId, data) { + const elem = angular.element(`#${targetElemId}`) + const paragraphScope = noteVarShareService.get(`${paragraph.id}_paragraphScope`) handleData(data, DefaultDisplayType.ANGULAR, (generated) => { - elem.html(generated); - $compile(elem.contents())(paragraphScope); + elem.html(generated) + $compile(elem.contents())(paragraphScope) }, - (error) => { elem.html(`${error.stack}`); } - ); - }; + (error) => { elem.html(`${error.stack}`) } + ) + } const getTextResultElemId = function (resultId) { - return `p${resultId}_text`; - }; + return `p${resultId}_text` + } - const renderText = function(targetElemId, data) { - const elem = angular.element(`#${targetElemId}`); + const renderText = function (targetElemId, data) { + const elem = angular.element(`#${targetElemId}`) handleData(data, DefaultDisplayType.TEXT, (generated) => { // clear all lines before render - removeChildrenDOM(targetElemId); + removeChildrenDOM(targetElemId) if (generated) { - const divDOM = angular.element('<div></div>').text(generated); - elem.append(divDOM); + const divDOM = angular.element('<div></div>').text(generated) + elem.append(divDOM) } - elem.bind('mousewheel', (e) => { $scope.keepScrollDown = false; }); + elem.bind('mousewheel', (e) => { $scope.keepScrollDown = false }) }, - (error) => { elem.html(`${error.stack}`); } - ); - }; + (error) => { elem.html(`${error.stack}`) } + ) + } - const removeChildrenDOM = function(targetElemId) { - const elem = angular.element(`#${targetElemId}`); + const removeChildrenDOM = function (targetElemId) { + const elem = angular.element(`#${targetElemId}`) if (elem.length) { - elem.children().remove(); + elem.children().remove() } - }; + } - function appendTextOutput(data) { - const elemId = getTextResultElemId($scope.id); - textResultQueueForAppend.push(data); + function appendTextOutput (data) { + const elemId = getTextResultElemId($scope.id) + textResultQueueForAppend.push(data) // if DOM is not loaded, just push data and return if (!isDOMLoaded(elemId)) { - return; + return } - const elem = angular.element(`#${elemId}`); + const elem = angular.element(`#${elemId}`) // pop all stacked data and append to the DOM while (textResultQueueForAppend.length > 0) { - const line = textResultQueueForAppend.pop(); - elem.append(angular.element('<div></div>').text(line)); + const line = textResultQueueForAppend.pop() + elem.append(angular.element('<div></div>').text(line)) if ($scope.keepScrollDown) { - const doc = angular.element(`#${elemId}`); - doc[0].scrollTop = doc[0].scrollHeight; + const doc = angular.element(`#${elemId}`) + doc[0].scrollTop = doc[0].scrollHeight } } } - const getTrSettingElem = function(scopeId, graphMode) { + const getTrSettingElem = function (scopeId, graphMode) { return angular.element('#trsetting' + scopeId + '_' + graphMode) } - const getVizSettingElem = function(scopeId, graphMode) { + const getVizSettingElem = function (scopeId, graphMode) { return angular.element('#vizsetting' + scopeId + '_' + graphMode) } - const renderGraph = function(graphElemId, graphMode, refresh) { + const renderGraph = function (graphElemId, graphMode, refresh) { // set graph height - const height = $scope.config.graph.height; - const graphElem = angular.element(`#${graphElemId}`); - graphElem.height(height); + const height = $scope.config.graph.height + const graphElem = angular.element(`#${graphElemId}`) + graphElem.height(height) - if (!graphMode) { graphMode = 'table'; } + if (!graphMode) { graphMode = 'table' } - const builtInViz = builtInVisualizations[graphMode]; - if (!builtInViz) { return; } + const builtInViz = builtInVisualizations[graphMode] + if (!builtInViz) { return } // deactive previsouly active visualization for (let t in builtInVisualizations) { - const v = builtInVisualizations[t].instance; + const v = builtInVisualizations[t].instance if (t !== graphMode && v && v.isActive()) { - v.deactivate(); - break; + v.deactivate() + break } } - let afterLoaded = function() { /** will be overwritten */ }; + let afterLoaded = function () { /** will be overwritten */ } if (!builtInViz.instance) { // not instantiated yet // render when targetEl is available - afterLoaded = function(loadedElem) { + afterLoaded = function (loadedElem) { try { const transformationSettingTargetEl = getTrSettingElem($scope.id, graphMode) const visualizationSettingTargetEl = getVizSettingElem($scope.id, graphMode) // set height - loadedElem.height(height); + loadedElem.height(height) // instantiate visualization - const config = getVizConfig(graphMode); - const Visualization = builtInViz.class; - builtInViz.instance = new Visualization(loadedElem, config); + const config = getVizConfig(graphMode) + const Visualization = builtInViz.class + builtInViz.instance = new Visualization(loadedElem, config) // inject emitter, $templateRequest - const emitter = function(graphSetting) { - commitVizConfigChange(graphSetting, graphMode); - }; - builtInViz.instance._emitter = emitter; - builtInViz.instance._compile = $compile; - builtInViz.instance._createNewScope = createNewScope; - const transformation = builtInViz.instance.getTransformation(); - transformation._emitter = emitter; - transformation._templateRequest = $templateRequest; - transformation._compile = $compile; - transformation._createNewScope = createNewScope; + const emitter = function (graphSetting) { + commitVizConfigChange(graphSetting, graphMode) + } + builtInViz.instance._emitter = emitter + builtInViz.instance._compile = $compile + builtInViz.instance._createNewScope = createNewScope + const transformation = builtInViz.instance.getTransformation() + transformation._emitter = emitter + transformation._templateRequest = $templateRequest + transformation._compile = $compile + transformation._createNewScope = createNewScope // render - const transformed = transformation.transform(tableData); - transformation.renderSetting(transformationSettingTargetEl); - builtInViz.instance.render(transformed); - builtInViz.instance.renderSetting(visualizationSettingTargetEl); - builtInViz.instance.activate(); + const transformed = transformation.transform(tableData) + transformation.renderSetting(transformationSettingTargetEl) + builtInViz.instance.render(transformed) + builtInViz.instance.renderSetting(visualizationSettingTargetEl) + builtInViz.instance.activate() angular.element(window).resize(() => { - builtInViz.instance.resize(); - }); + builtInViz.instance.resize() + }) } catch (err) { - console.error('Graph drawing error %o', err); + console.error('Graph drawing error %o', err) } - }; - + } } else if (refresh) { // when graph options or data are changed - console.log('Refresh data %o', tableData); + console.log('Refresh data %o', tableData) - afterLoaded = function(loadedElem) { + afterLoaded = function (loadedElem) { const transformationSettingTargetEl = getTrSettingElem($scope.id, graphMode) const visualizationSettingTargetEl = getVizSettingElem($scope.id, graphMode) - const config = getVizConfig(graphMode); - loadedElem.height(height); - const transformation = builtInViz.instance.getTransformation(); - transformation.setConfig(config); - const transformed = transformation.transform(tableData); - transformation.renderSetting(transformationSettingTargetEl); - builtInViz.instance.setConfig(config); - builtInViz.instance.render(transformed); - builtInViz.instance.renderSetting(visualizationSettingTargetEl); - }; - + const config = getVizConfig(graphMode) + loadedElem.height(height) + const transformation = builtInViz.instance.getTransformation() + transformation.setConfig(config) + const transformed = transformation.transform(tableData) + transformation.renderSetting(transformationSettingTargetEl) + builtInViz.instance.setConfig(config) + builtInViz.instance.render(transformed) + builtInViz.instance.renderSetting(visualizationSettingTargetEl) + } } else { - afterLoaded = function(loadedElem) { - loadedElem.height(height); - builtInViz.instance.activate(); - }; + afterLoaded = function (loadedElem) { + loadedElem.height(height) + builtInViz.instance.activate() + } } - const tableElemId = `p${$scope.id}_${graphMode}`; - retryUntilElemIsLoaded(tableElemId, afterLoaded); - }; + const tableElemId = `p${$scope.id}_${graphMode}` + retryUntilElemIsLoaded(tableElemId, afterLoaded) + } - $scope.switchViz = function(newMode) { - var newConfig = angular.copy($scope.config); - var newParams = angular.copy(paragraph.settings.params); + $scope.switchViz = function (newMode) { + let newConfig = angular.copy($scope.config) + let newParams = angular.copy(paragraph.settings.params) // graph options - newConfig.graph.mode = newMode; + newConfig.graph.mode = newMode // see switchApp() - _.set(newConfig, 'helium.activeApp', undefined); + _.set(newConfig, 'helium.activeApp', undefined) - commitParagraphResult(paragraph.title, paragraph.text, newConfig, newParams); - }; + commitParagraphResult(paragraph.title, paragraph.text, newConfig, newParams) + } - var createNewScope = function() { - return $rootScope.$new(true); - }; + const createNewScope = function () { + return $rootScope.$new(true) + } - var commitParagraphResult = function(title, text, config, params) { - var newParagraphConfig = angular.copy(paragraph.config); - newParagraphConfig.results = newParagraphConfig.results || []; - newParagraphConfig.results[resultIndex] = config; + const commitParagraphResult = function (title, text, config, params) { + let newParagraphConfig = angular.copy(paragraph.config) + newParagraphConfig.results = newParagraphConfig.results || [] + newParagraphConfig.results[resultIndex] = config if ($scope.revisionView === true) { // local update without commit updateData({ type: $scope.type, data: data - }, newParagraphConfig.results[resultIndex], paragraph, resultIndex); - renderResult($scope.type, true); + }, newParagraphConfig.results[resultIndex], paragraph, resultIndex) + renderResult($scope.type, true) } else { - websocketMsgSrv.commitParagraph(paragraph.id, title, text, newParagraphConfig, params); + websocketMsgSrv.commitParagraph(paragraph.id, title, text, newParagraphConfig, params) } - }; + } - $scope.toggleGraphSetting = function() { - var newConfig = angular.copy($scope.config); + $scope.toggleGraphSetting = function () { + let newConfig = angular.copy($scope.config) if (newConfig.graph.optionOpen) { - newConfig.graph.optionOpen = false; + newConfig.graph.optionOpen = false } else { - newConfig.graph.optionOpen = true; + newConfig.graph.optionOpen = true } - var newParams = angular.copy(paragraph.settings.params); + let newParams = angular.copy(paragraph.settings.params) - commitParagraphResult(paragraph.title, paragraph.text, newConfig, newParams); - }; + commitParagraphResult(paragraph.title, paragraph.text, newConfig, newParams) + } - var getVizConfig = function(vizId) { - var config; - var graph = $scope.config.graph; + const getVizConfig = function (vizId) { + let config + let graph = $scope.config.graph if (graph) { // copy setting for vizId if (graph.setting) { - config = angular.copy(graph.setting[vizId]); + config = angular.copy(graph.setting[vizId]) } if (!config) { - config = {}; + config = {} } // copy common setting - config.common = angular.copy(graph.commonSetting) || {}; + config.common = angular.copy(graph.commonSetting) || {} // copy pivot setting if (graph.keys) { @@ -636,300 +633,300 @@ function ResultCtrl($scope, $rootScope, $route, $window, $routeParams, $location keys: angular.copy(graph.keys), groups: angular.copy(graph.groups), values: angular.copy(graph.values) - }; + } } } - console.log('getVizConfig', config); - return config; - }; + console.log('getVizConfig', config) + return config + } - var commitVizConfigChange = function(config, vizId) { - var newConfig = angular.copy($scope.config); + const commitVizConfigChange = function (config, vizId) { + let newConfig = angular.copy($scope.config) if (!newConfig.graph) { - newConfig.graph = {}; + newConfig.graph = {} } // copy setting for vizId if (!newConfig.graph.setting) { - newConfig.graph.setting = {}; + newConfig.graph.setting = {} } - newConfig.graph.setting[vizId] = angular.copy(config); + newConfig.graph.setting[vizId] = angular.copy(config) // copy common setting if (newConfig.graph.setting[vizId]) { - newConfig.graph.commonSetting = newConfig.graph.setting[vizId].common; - delete newConfig.graph.setting[vizId].common; + newConfig.graph.commonSetting = newConfig.graph.setting[vizId].common + delete newConfig.graph.setting[vizId].common } // copy pivot setting if (newConfig.graph.commonSetting && newConfig.graph.commonSetting.pivot) { - newConfig.graph.keys = newConfig.graph.commonSetting.pivot.keys; - newConfig.graph.groups = newConfig.graph.commonSetting.pivot.groups; - newConfig.graph.values = newConfig.graph.commonSetting.pivot.values; - delete newConfig.graph.commonSetting.pivot; - } - console.log('committVizConfig', newConfig); - var newParams = angular.copy(paragraph.settings.params); - commitParagraphResult(paragraph.title, paragraph.text, newConfig, newParams); - }; + newConfig.graph.keys = newConfig.graph.commonSetting.pivot.keys + newConfig.graph.groups = newConfig.graph.commonSetting.pivot.groups + newConfig.graph.values = newConfig.graph.commonSetting.pivot.values + delete newConfig.graph.commonSetting.pivot + } + console.log('committVizConfig', newConfig) + let newParams = angular.copy(paragraph.settings.params) + commitParagraphResult(paragraph.title, paragraph.text, newConfig, newParams) + } - $scope.$on('paragraphResized', function(event, paragraphId) { + $scope.$on('paragraphResized', function (event, paragraphId) { // paragraph col width changed if (paragraphId === paragraph.id) { - var builtInViz = builtInVisualizations[$scope.graphMode]; + let builtInViz = builtInVisualizations[$scope.graphMode] if (builtInViz && builtInViz.instance) { - builtInViz.instance.resize(); + builtInViz.instance.resize() } } - }); + }) - $scope.resize = function(width, height) { - $timeout(function() { - changeHeight(width, height); - }, 200); - }; + $scope.resize = function (width, height) { + $timeout(function () { + changeHeight(width, height) + }, 200) + } - var changeHeight = function(width, height) { - var newParams = angular.copy(paragraph.settings.params); - var newConfig = angular.copy($scope.config); + const changeHeight = function (width, height) { + let newParams = angular.copy(paragraph.settings.params) + let newConfig = angular.copy($scope.config) - newConfig.graph.height = height; - paragraph.config.colWidth = width; + newConfig.graph.height = height + paragraph.config.colWidth = width - commitParagraphResult(paragraph.title, paragraph.text, newConfig, newParams); - }; + commitParagraphResult(paragraph.title, paragraph.text, newConfig, newParams) + } - $scope.exportToDSV = function(delimiter) { - var dsv = ''; - var dateFinished = moment(paragraph.dateFinished).format('YYYY-MM-DD hh:mm:ss A'); - var exportedFileName = paragraph.title ? paragraph.title + '_' + dateFinished : 'data_' + dateFinished; + $scope.exportToDSV = function (delimiter) { + let dsv = '' + let dateFinished = moment(paragraph.dateFinished).format('YYYY-MM-DD hh:mm:ss A') + let exportedFileName = paragraph.title ? paragraph.title + '_' + dateFinished : 'data_' + dateFinished - for (var titleIndex in tableData.columns) { - dsv += tableData.columns[titleIndex].name + delimiter; + for (let titleIndex in tableData.columns) { + dsv += tableData.columns[titleIndex].name + delimiter } - dsv = dsv.substring(0, dsv.length - 1) + '\n'; - for (var r in tableData.rows) { - var row = tableData.rows[r]; - var dsvRow = ''; - for (var index in row) { - var stringValue = (row[index]).toString(); + dsv = dsv.substring(0, dsv.length - 1) + '\n' + for (let r in tableData.rows) { + let row = tableData.rows[r] + let dsvRow = '' + for (let index in row) { + let stringValue = (row[index]).toString() if (stringValue.indexOf(delimiter) > -1) { - dsvRow += '"' + stringValue + '"' + delimiter; + dsvRow += '"' + stringValue + '"' + delimiter } else { - dsvRow += row[index] + delimiter; + dsvRow += row[index] + delimiter } } - dsv += dsvRow.substring(0, dsvRow.length - 1) + '\n'; + dsv += dsvRow.substring(0, dsvRow.length - 1) + '\n' } - var extension = ''; + let extension = '' if (delimiter === '\t') { - extension = 'tsv'; + extension = 'tsv' } else if (delimiter === ',') { - extension = 'csv'; + extension = 'csv' } - saveAsService.saveAs(dsv, exportedFileName, extension); - }; + saveAsService.saveAs(dsv, exportedFileName, extension) + } - $scope.getBase64ImageSrc = function(base64Data) { - return 'data:image/png;base64,' + base64Data; - }; + $scope.getBase64ImageSrc = function (base64Data) { + return 'data:image/png;base64,' + base64Data + } // Helium ---------------- - var ANGULAR_FUNCTION_OBJECT_NAME_PREFIX = '_Z_ANGULAR_FUNC_'; + let ANGULAR_FUNCTION_OBJECT_NAME_PREFIX = '_Z_ANGULAR_FUNC_' // app states - $scope.apps = []; + $scope.apps = [] // suggested apps - $scope.suggestion = {}; + $scope.suggestion = {} - $scope.switchApp = function(appId) { - var newConfig = angular.copy($scope.config); - var newParams = angular.copy(paragraph.settings.params); + $scope.switchApp = function (appId) { + let newConfig = angular.copy($scope.config) + let newParams = angular.copy(paragraph.settings.params) // 'helium.activeApp' can be cleared by switchViz() - _.set(newConfig, 'helium.activeApp', appId); + _.set(newConfig, 'helium.activeApp', appId) - commitConfig(newConfig, newParams); - }; + commitConfig(newConfig, newParams) + } - $scope.loadApp = function(heliumPackage) { - var noteId = $route.current.pathParams.noteId; + $scope.loadApp = function (heliumPackage) { + let noteId = $route.current.pathParams.noteId $http.post(baseUrlSrv.getRestApiBase() + '/helium/load/' + noteId + '/' + paragraph.id, heliumPackage) - .success(function(data, status, headers, config) { - console.log('Load app %o', data); + .success(function (data, status, headers, config) { + console.log('Load app %o', data) + }) + .error(function (err, status, headers, config) { + console.log('Error %o', err) }) - .error(function(err, status, headers, config) { - console.log('Error %o', err); - }); - }; + } - var commitConfig = function(config, params) { - commitParagraphResult(paragraph.title, paragraph.text, config, params); - }; + const commitConfig = function (config, params) { + commitParagraphResult(paragraph.title, paragraph.text, config, params) + } - var getApplicationStates = function() { - var appStates = []; + const getApplicationStates = function () { + let appStates = [] // Display ApplicationState if (paragraph.apps) { - _.forEach(paragraph.apps, function(app) { + _.forEach(paragraph.apps, function (app) { appStates.push({ id: app.id, pkg: app.pkg, status: app.status, output: app.output - }); - }); + }) + }) } // update or remove app states no longer exists - _.forEach($scope.apps, function(currentAppState, idx) { - var newAppState = _.find(appStates, {id: currentAppState.id}); + _.forEach($scope.apps, function (currentAppState, idx) { + let newAppState = _.find(appStates, {id: currentAppState.id}) if (newAppState) { - angular.extend($scope.apps[idx], newAppState); + angular.extend($scope.apps[idx], newAppState) } else { - $scope.apps.splice(idx, 1); + $scope.apps.splice(idx, 1) } - }); + }) // add new app states - _.forEach(appStates, function(app, idx) { + _.forEach(appStates, function (app, idx) { if ($scope.apps.length <= idx || $scope.apps[idx].id !== app.id) { - $scope.apps.splice(idx, 0, app); + $scope.apps.splice(idx, 0, app) } - }); - }; + }) + } - var getSuggestions = function() { + const getSuggestions = function () { // Get suggested apps - var noteId = $route.current.pathParams.noteId; + let noteId = $route.current.pathParams.noteId if (!noteId) { - return; + return } $http.get(baseUrlSrv.getRestApiBase() + '/helium/suggest/' + noteId + '/' + paragraph.id) - .success(function(data, status, headers, config) { - $scope.suggestion = data.body; + .success(function (data, status, headers, config) { + $scope.suggestion = data.body }) - .error(function(err, status, headers, config) { - console.log('Error %o', err); - }); - }; + .error(function (err, status, headers, config) { + console.log('Error %o', err) + }) + } - const renderApp = function(targetElemId, appState) { + const renderApp = function (targetElemId, appState) { const afterLoaded = (loadedElem) => { try { - console.log('renderApp %o', appState); - loadedElem.html(appState.output); - $compile(loadedElem.contents())(getAppScope(appState)); + console.log('renderApp %o', appState) + loadedElem.html(appState.output) + $compile(loadedElem.contents())(getAppScope(appState)) } catch (err) { - console.log('App rendering error %o', err); + console.log('App rendering error %o', err) } - }; - retryUntilElemIsLoaded(targetElemId, afterLoaded); - }; + } + retryUntilElemIsLoaded(targetElemId, afterLoaded) + } /* ** $scope.$on functions below */ - $scope.$on('appendAppOutput', function(event, data) { + $scope.$on('appendAppOutput', function (event, data) { if (paragraph.id === data.paragraphId) { - var app = _.find($scope.apps, {id: data.appId}); + let app = _.find($scope.apps, {id: data.appId}) if (app) { - app.output += data.data; + app.output += data.data - var paragraphAppState = _.find(paragraph.apps, {id: data.appId}); - paragraphAppState.output = app.output; + let paragraphAppState = _.find(paragraph.apps, {id: data.appId}) + paragraphAppState.output = app.output - var targetEl = angular.element(document.getElementById('p' + app.id)); - targetEl.html(app.output); - $compile(targetEl.contents())(getAppScope(app)); - console.log('append app output %o', $scope.apps); + let targetEl = angular.element(document.getElementById('p' + app.id)) + targetEl.html(app.output) + $compile(targetEl.contents())(getAppScope(app)) + console.log('append app output %o', $scope.apps) } } - }); + }) - $scope.$on('updateAppOutput', function(event, data) { + $scope.$on('updateAppOutput', function (event, data) { if (paragraph.id === data.paragraphId) { - var app = _.find($scope.apps, {id: data.appId}); + let app = _.find($scope.apps, {id: data.appId}) if (app) { - app.output = data.data; + app.output = data.data - var paragraphAppState = _.find(paragraph.apps, {id: data.appId}); - paragraphAppState.output = app.output; + let paragraphAppState = _.find(paragraph.apps, {id: data.appId}) + paragraphAppState.output = app.output - var targetEl = angular.element(document.getElementById('p' + app.id)); - targetEl.html(app.output); - $compile(targetEl.contents())(getAppScope(app)); - console.log('append app output'); + let targetEl = angular.element(document.getElementById('p' + app.id)) + targetEl.html(app.output) + $compile(targetEl.contents())(getAppScope(app)) + console.log('append app output') } } - }); + }) - $scope.$on('appLoad', function(event, data) { + $scope.$on('appLoad', function (event, data) { if (paragraph.id === data.paragraphId) { - var app = _.find($scope.apps, {id: data.appId}); + let app = _.find($scope.apps, {id: data.appId}) if (!app) { app = { id: data.appId, pkg: data.pkg, status: 'UNLOADED', output: '' - }; + } - $scope.apps.push(app); - paragraph.apps.push(app); - $scope.switchApp(app.id); + $scope.apps.push(app) + paragraph.apps.push(app) + $scope.switchApp(app.id) } } - }); + }) - $scope.$on('appStatusChange', function(event, data) { + $scope.$on('appStatusChange', function (event, data) { if (paragraph.id === data.paragraphId) { - var app = _.find($scope.apps, {id: data.appId}); + let app = _.find($scope.apps, {id: data.appId}) if (app) { - app.status = data.status; - var paragraphAppState = _.find(paragraph.apps, {id: data.appId}); - paragraphAppState.status = app.status; + app.status = data.status + let paragraphAppState = _.find(paragraph.apps, {id: data.appId}) + paragraphAppState.status = app.status } } - }); + }) - var getAppRegistry = function(appState) { + let getAppRegistry = function (appState) { if (!appState.registry) { - appState.registry = {}; + appState.registry = {} } - return appState.registry; - }; + return appState.registry + } - var getAppScope = function(appState) { + const getAppScope = function (appState) { if (!appState.scope) { - appState.scope = $rootScope.$new(true, $rootScope); + appState.scope = $rootScope.$new(true, $rootScope) } - return appState.scope; - }; + return appState.scope + } - $scope.$on('angularObjectUpdate', function(event, data) { - var noteId = $route.current.pathParams.noteId; + $scope.$on('angularObjectUpdate', function (event, data) { + let noteId = $route.current.pathParams.noteId if (!data.noteId || data.noteId === noteId) { - var scope; - var registry; + let scope + let registry - var app = _.find($scope.apps, {id: data.paragraphId}); + let app = _.find($scope.apps, {id: data.paragraphId}) if (app) { - scope = getAppScope(app); - registry = getAppRegistry(app); + scope = getAppScope(app) + registry = getAppRegistry(app) } else { // no matching app in this paragraph - return; + return } - var varName = data.angularObject.name; + let varName = data.angularObject.name if (angular.equals(data.angularObject.object, scope[varName])) { // return when update has no change - return; + return } if (!registry[varName]) { @@ -937,76 +934,78 @@ function ResultCtrl($scope, $rootScope, $route, $window, $routeParams, $location interpreterGroupId: data.interpreterGroupId, noteId: data.noteId, paragraphId: data.paragraphId - }; + } } else { - registry[varName].noteId = registry[varName].noteId || data.noteId; - registry[varName].paragraphId = registry[varName].paragraphId || data.paragraphId; + registry[varName].noteId = registry[varName].noteId || data.noteId + registry[varName].paragraphId = registry[varName].paragraphId || data.paragraphId } - registry[varName].skipEmit = true; + registry[varName].skipEmit = true if (!registry[varName].clearWatcher) { - registry[varName].clearWatcher = scope.$watch(varName, function(newValue, oldValue) { - console.log('angular object (paragraph) updated %o %o', varName, registry[varName]); + registry[varName].clearWatcher = scope.$watch(varName, function (newValue, oldValue) { + console.log('angular object (paragraph) updated %o %o', varName, registry[varName]) if (registry[varName].skipEmit) { - registry[varName].skipEmit = false; - return; + registry[varName].skipEmit = false + return } websocketMsgSrv.updateAngularObject( registry[varName].noteId, registry[varName].paragraphId, varName, newValue, - registry[varName].interpreterGroupId); - }); + registry[varName].interpreterGroupId) + }) } - console.log('angular object (paragraph) created %o', varName); - scope[varName] = data.angularObject.object; + console.log('angular object (paragraph) created %o', varName) + scope[varName] = data.angularObject.object // create proxy for AngularFunction if (varName.indexOf(ANGULAR_FUNCTION_OBJECT_NAME_PREFIX) === 0) { - var funcName = varName.substring((ANGULAR_FUNCTION_OBJECT_NAME_PREFIX).length); - scope[funcName] = function() { - scope[varName] = arguments; - console.log('angular function (paragraph) invoked %o', arguments); - }; + let funcName = varName.substring((ANGULAR_FUNCTION_OBJECT_NAME_PREFIX).length) + scope[funcName] = function () { + // eslint-disable-next-line prefer-rest-params + scope[varName] = arguments + // eslint-disable-next-line prefer-rest-params + console.log('angular function (paragraph) invoked %o', arguments) + } - console.log('angular function (paragraph) created %o', scope[funcName]); + console.log('angular function (paragraph) created %o', scope[funcName]) } } - }); + }) - $scope.$on('angularObjectRemove', function(event, data) { - var noteId = $route.current.pathParams.noteId; + $scope.$on('angularObjectRemove', function (event, data) { + let noteId = $route.current.pathParams.noteId if (!data.noteId || data.noteId === noteId) { - var scope; - var registry; + let scope + let registry - var app = _.find($scope.apps, {id: data.paragraphId}); + let app = _.find($scope.apps, {id: data.paragraphId}) if (app) { - scope = getAppScope(app); - registry = getAppRegistry(app); + scope = getAppScope(app) + registry = getAppRegistry(app) } else { // no matching app in this paragraph - return; + return } - var varName = data.name; + let varName = data.name // clear watcher if (registry[varName]) { - registry[varName].clearWatcher(); - registry[varName] = undefined; + registry[varName].clearWatcher() + registry[varName] = undefined } // remove scope variable - scope[varName] = undefined; + scope[varName] = undefined // remove proxy for AngularFunction if (varName.indexOf(ANGULAR_FUNCTION_OBJECT_NAME_PREFIX) === 0) { - var funcName = varName.substring((ANGULAR_FUNCTION_OBJECT_NAME_PREFIX).length); - scope[funcName] = undefined; + let funcName = varName.substring((ANGULAR_FUNCTION_OBJECT_NAME_PREFIX).length) + scope[funcName] = undefined } } - }); + }) }
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/19b0f30f/zeppelin-web/src/app/notebookRepos/notebookRepos.controller.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebookRepos/notebookRepos.controller.js b/zeppelin-web/src/app/notebookRepos/notebookRepos.controller.js index 14357fd..2e35338 100644 --- a/zeppelin-web/src/app/notebookRepos/notebookRepos.controller.js +++ b/zeppelin-web/src/app/notebookRepos/notebookRepos.controller.js @@ -12,77 +12,76 @@ * limitations under the License. */ -angular.module('zeppelinWebApp').controller('NotebookReposCtrl', NotebookReposCtrl); +angular.module('zeppelinWebApp').controller('NotebookReposCtrl', NotebookReposCtrl) -function NotebookReposCtrl($http, baseUrlSrv, ngToast) { - 'ngInject'; +function NotebookReposCtrl ($http, baseUrlSrv, ngToast) { + 'ngInject' - var vm = this; - vm.notebookRepos = []; - vm.showDropdownSelected = showDropdownSelected; - vm.saveNotebookRepo = saveNotebookRepo; + let vm = this + vm.notebookRepos = [] + vm.showDropdownSelected = showDropdownSelected + vm.saveNotebookRepo = saveNotebookRepo - _init(); + _init() // Public functions - function saveNotebookRepo(valueform, repo, data) { - console.log('data %o', data); + function saveNotebookRepo (valueform, repo, data) { + console.log('data %o', data) $http.put(baseUrlSrv.getRestApiBase() + '/notebook-repositories', { 'name': repo.className, 'settings': data - }).success(function(data) { - var index = _.findIndex(vm.notebookRepos, {'className': repo.className}); + }).success(function (data) { + let index = _.findIndex(vm.notebookRepos, {'className': repo.className}) if (index >= 0) { - vm.notebookRepos[index] = data.body; - console.log('repos %o, data %o', vm.notebookRepos, data.body); + vm.notebookRepos[index] = data.body + console.log('repos %o, data %o', vm.notebookRepos, data.body) } - valueform.$show(); - }).error(function() { + valueform.$show() + }).error(function () { ngToast.danger({ content: 'We couldn\'t save that NotebookRepo\'s settings', verticalPosition: 'bottom', timeout: '3000' - }); - valueform.$show(); - }); + }) + valueform.$show() + }) - return 'manual'; + return 'manual' } - function showDropdownSelected(setting) { - var index = _.findIndex(setting.value, {'value': setting.selected}); + function showDropdownSelected (setting) { + let index = _.findIndex(setting.value, {'value': setting.selected}) if (index < 0) { - return 'No value'; + return 'No value' } else { - return setting.value[index].name; + return setting.value[index].name } } // Private functions - function _getInterpreterSettings() { + function _getInterpreterSettings () { $http.get(baseUrlSrv.getRestApiBase() + '/notebook-repositories') - .success(function(data, status, headers, config) { - vm.notebookRepos = data.body; - console.log('ya notebookRepos %o', vm.notebookRepos); - }).error(function(data, status, headers, config) { - if (status === 401) { - ngToast.danger({ - content: 'You don\'t have permission on this page', - verticalPosition: 'bottom', - timeout: '3000' - }); - setTimeout(function() { - window.location.replace('/'); - }, 3000); - } - console.log('Error %o %o', status, data.message); - }); + .success(function (data, status, headers, config) { + vm.notebookRepos = data.body + console.log('ya notebookRepos %o', vm.notebookRepos) + }).error(function (data, status, headers, config) { + if (status === 401) { + ngToast.danger({ + content: 'You don\'t have permission on this page', + verticalPosition: 'bottom', + timeout: '3000' + }) + setTimeout(function () { + window.location.replace('/') + }, 3000) + } + console.log('Error %o %o', status, data.message) + }) } - function _init() { - _getInterpreterSettings(); - }; + function _init () { + _getInterpreterSettings() + } } - http://git-wip-us.apache.org/repos/asf/zeppelin/blob/19b0f30f/zeppelin-web/src/app/search/result-list.controller.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/search/result-list.controller.js b/zeppelin-web/src/app/search/result-list.controller.js index f3ceb6a..cd7542d 100644 --- a/zeppelin-web/src/app/search/result-list.controller.js +++ b/zeppelin-web/src/app/search/result-list.controller.js @@ -12,108 +12,107 @@ * limitations under the License. */ -angular.module('zeppelinWebApp').controller('SearchResultCtrl', SearchResultCtrl); +angular.module('zeppelinWebApp').controller('SearchResultCtrl', SearchResultCtrl) -function SearchResultCtrl($scope, $routeParams, searchService) { - 'ngInject'; +function SearchResultCtrl ($scope, $routeParams, searchService) { + 'ngInject' - $scope.isResult = true ; - $scope.searchTerm = $routeParams.searchTerm; - var results = searchService.search({'q': $routeParams.searchTerm}).query(); + $scope.isResult = true + $scope.searchTerm = $routeParams.searchTerm + let results = searchService.search({'q': $routeParams.searchTerm}).query() - results.$promise.then(function(result) { - $scope.notes = result.body.map(function(note) { + results.$promise.then(function (result) { + $scope.notes = result.body.map(function (note) { // redirect to notebook when search result is a notebook itself, // not a paragraph if (!/\/paragraph\//.test(note.id)) { - return note; + return note } note.id = note.id.replace('paragraph/', '?paragraph=') + - '&term=' + $routeParams.searchTerm; + '&term=' + $routeParams.searchTerm - return note; - }); + return note + }) if ($scope.notes.length === 0) { - $scope.isResult = false; + $scope.isResult = false } else { - $scope.isResult = true; + $scope.isResult = true } - $scope.$on('$routeChangeStart', function(event, next, current) { + $scope.$on('$routeChangeStart', function (event, next, current) { if (next.originalPath !== '/search/:searchTerm') { - searchService.searchTerm = ''; + searchService.searchTerm = '' } - }); - }); + }) + }) - $scope.page = 0; - $scope.allResults = false; + $scope.page = 0 + $scope.allResults = false - $scope.highlightSearchResults = function(note) { - return function(_editor) { - function getEditorMode(text) { - var editorModes = { + $scope.highlightSearchResults = function (note) { + return function (_editor) { + function getEditorMode (text) { + let editorModes = { 'ace/mode/scala': /^%(\w*\.)?spark/, 'ace/mode/python': /^%(\w*\.)?(pyspark|python)/, 'ace/mode/r': /^%(\w*\.)?(r|sparkr|knitr)/, 'ace/mode/sql': /^%(\w*\.)?\wql/, 'ace/mode/markdown': /^%md/, 'ace/mode/sh': /^%sh/ - }; + } - return Object.keys(editorModes).reduce(function(res, mode) { - return editorModes[mode].test(text) ? mode : res; - }, 'ace/mode/scala'); + return Object.keys(editorModes).reduce(function (res, mode) { + return editorModes[mode].test(text) ? mode : res + }, 'ace/mode/scala') } - var Range = ace.require('ace/range').Range; + let Range = ace.require('ace/range').Range - _editor.setOption('highlightActiveLine', false); - _editor.$blockScrolling = Infinity; - _editor.setReadOnly(true); - _editor.renderer.setShowGutter(false); - _editor.setTheme('ace/theme/chrome'); - _editor.getSession().setMode(getEditorMode(note.text)); + _editor.setOption('highlightActiveLine', false) + _editor.$blockScrolling = Infinity + _editor.setReadOnly(true) + _editor.renderer.setShowGutter(false) + _editor.setTheme('ace/theme/chrome') + _editor.getSession().setMode(getEditorMode(note.text)) - function getIndeces(term) { - return function(str) { - var indeces = []; - var i = -1; + function getIndeces (term) { + return function (str) { + let indeces = [] + let i = -1 while ((i = str.indexOf(term, i + 1)) >= 0) { - indeces.push(i); + indeces.push(i) } - return indeces; - }; + return indeces + } } - var result = ''; + let result = '' if (note.header !== '') { - result = note.header + '\n\n' + note.snippet; + result = note.header + '\n\n' + note.snippet } else { - result = note.snippet; + result = note.snippet } - var lines = result + let lines = result .split('\n') - .map(function(line, row) { - - var match = line.match(/<B>(.+?)<\/B>/); + .map(function (line, row) { + let match = line.match(/<B>(.+?)<\/B>/) // return early if nothing to highlight if (!match) { - return line; + return line } - var term = match[1]; - var __line = line + let term = match[1] + let __line = line .replace(/<B>/g, '') - .replace(/<\/B>/g, ''); + .replace(/<\/B>/g, '') - var indeces = getIndeces(term)(__line); + let indeces = getIndeces(term)(__line) - indeces.forEach(function(start) { - var end = start + term.length; + indeces.forEach(function (start) { + let end = start + term.length if (note.header !== '' && row === 0) { _editor .getSession() @@ -121,14 +120,14 @@ function SearchResultCtrl($scope, $routeParams, searchService) { new Range(row, 0, row, line.length), 'search-results-highlight-header', 'background' - ); + ) _editor .getSession() .addMarker( new Range(row, start, row, end), 'search-results-highlight', 'line' - ); + ) } else { _editor .getSession() @@ -136,21 +135,19 @@ function SearchResultCtrl($scope, $routeParams, searchService) { new Range(row, start, row, end), 'search-results-highlight', 'line' - ); + ) } - }); - return __line; - }); + }) + return __line + }) // resize editor based on content length _editor.setOption( 'maxLines', - lines.reduce(function(len, line) {return len + line.length;}, 0) - ); - - _editor.getSession().setValue(lines.join('\n')); + lines.reduce(function (len, line) { return len + line.length }, 0) + ) - }; - }; + _editor.getSession().setValue(lines.join('\n')) + } + } } - http://git-wip-us.apache.org/repos/asf/zeppelin/blob/19b0f30f/zeppelin-web/src/app/spell/index.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/spell/index.js b/zeppelin-web/src/app/spell/index.js index 8ec4753..ac4343c 100644 --- a/zeppelin-web/src/app/spell/index.js +++ b/zeppelin-web/src/app/spell/index.js @@ -18,8 +18,8 @@ export { DefaultDisplayType, SpellResult, -} from './spell-result'; +} from './spell-result' export { SpellBase, -} from './spell-base'; +} from './spell-base' http://git-wip-us.apache.org/repos/asf/zeppelin/blob/19b0f30f/zeppelin-web/src/app/spell/spell-base.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/spell/spell-base.js b/zeppelin-web/src/app/spell/spell-base.js index 6dcb576..0b4216f 100644 --- a/zeppelin-web/src/app/spell/spell-base.js +++ b/zeppelin-web/src/app/spell/spell-base.js @@ -15,16 +15,16 @@ * limitations under the License. */ -/*eslint-disable no-unused-vars */ +/* eslint-disable no-unused-vars */ import { DefaultDisplayType, SpellResult, -} from './spell-result'; -/*eslint-enable no-unused-vars */ +} from './spell-result' +/* eslint-enable no-unused-vars */ export class SpellBase { - constructor(magic) { - this.magic = magic; + constructor (magic) { + this.magic = magic } /** @@ -34,8 +34,8 @@ export class SpellBase { * @param config {Object} * @return {SpellResult} */ - interpret(paragraphText, config) { - throw new Error('SpellBase.interpret() should be overrided'); + interpret (paragraphText, config) { + throw new Error('SpellBase.interpret() should be overrided') } /** @@ -43,7 +43,7 @@ export class SpellBase { * (e.g `%flowchart`) * @return {string} */ - getMagic() { - return this.magic; + getMagic () { + return this.magic } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/19b0f30f/zeppelin-web/src/app/spell/spell-result.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/spell/spell-result.js b/zeppelin-web/src/app/spell/spell-result.js index d62e97a..e8e2a0a 100644 --- a/zeppelin-web/src/app/spell/spell-result.js +++ b/zeppelin-web/src/app/spell/spell-result.js @@ -21,7 +21,7 @@ export const DefaultDisplayType = { HTML: 'HTML', ANGULAR: 'ANGULAR', TEXT: 'TEXT', -}; +} export const DefaultDisplayMagic = { '%element': DefaultDisplayType.ELEMENT, @@ -29,12 +29,12 @@ export const DefaultDisplayMagic = { '%html': DefaultDisplayType.HTML, '%angular': DefaultDisplayType.ANGULAR, '%text': DefaultDisplayType.TEXT, -}; +} export class DataWithType { - constructor(data, type, magic, text) { - this.data = data; - this.type = type; + constructor (data, type, magic, text) { + this.data = data + this.type = type /** * keep for `DefaultDisplayType.ELEMENT` (function data type) @@ -44,29 +44,29 @@ export class DataWithType { * since they don't have context where they are created. */ - this.magic = magic; - this.text = text; + this.magic = magic + this.text = text } - static handleDefaultMagic(m) { + static handleDefaultMagic (m) { // let's use default display type instead of magic in case of default // to keep consistency with backend interpreter if (DefaultDisplayMagic[m]) { - return DefaultDisplayMagic[m]; + return DefaultDisplayMagic[m] } else { - return m; + return m } } - static createPropagable(dataWithType) { + static createPropagable (dataWithType) { if (!SpellResult.isFunction(dataWithType.data)) { - return dataWithType; + return dataWithType } - const data = dataWithType.getText(); - const type = dataWithType.getMagic(); + const data = dataWithType.getText() + const type = dataWithType.getMagic() - return new DataWithType(data, type); + return new DataWithType(data, type) } /** @@ -75,45 +75,45 @@ export class DataWithType { * @param customDisplayType * @return {Array<DataWithType>} */ - static parseStringData(data, customDisplayMagic) { - function availableMagic(magic) { - return magic && (DefaultDisplayMagic[magic] || customDisplayMagic[magic]); + static parseStringData (data, customDisplayMagic) { + function availableMagic (magic) { + return magic && (DefaultDisplayMagic[magic] || customDisplayMagic[magic]) } - const splited = data.split('\n'); + const splited = data.split('\n') - const gensWithTypes = []; - let mergedGens = []; - let previousMagic = DefaultDisplayType.TEXT; + const gensWithTypes = [] + let mergedGens = [] + let previousMagic = DefaultDisplayType.TEXT // create `DataWithType` whenever see available display type. - for(let i = 0; i < splited.length; i++) { - const g = splited[i]; - const magic = SpellResult.extractMagic(g); + for (let i = 0; i < splited.length; i++) { + const g = splited[i] + const magic = SpellResult.extractMagic(g) // create `DataWithType` only if see new magic if (availableMagic(magic) && mergedGens.length > 0) { - gensWithTypes.push(new DataWithType(mergedGens.join(''), previousMagic)); - mergedGens = []; + gensWithTypes.push(new DataWithType(mergedGens.join(''), previousMagic)) + mergedGens = [] } // accumulate `data` to mergedGens if (availableMagic(magic)) { - const withoutMagic = g.split(magic)[1]; - mergedGens.push(`${withoutMagic}\n`); - previousMagic = DataWithType.handleDefaultMagic(magic); + const withoutMagic = g.split(magic)[1] + mergedGens.push(`${withoutMagic}\n`) + previousMagic = DataWithType.handleDefaultMagic(magic) } else { - mergedGens.push(`${g}\n`); + mergedGens.push(`${g}\n`) } } // cleanup the last `DataWithType` if (mergedGens.length > 0) { - previousMagic = DataWithType.handleDefaultMagic(previousMagic); - gensWithTypes.push(new DataWithType(mergedGens.join(''), previousMagic)); + previousMagic = DataWithType.handleDefaultMagic(previousMagic) + gensWithTypes.push(new DataWithType(mergedGens.join(''), previousMagic)) } - return gensWithTypes; + return gensWithTypes } /** @@ -126,45 +126,44 @@ export class DataWithType { * @param textWithoutMagic * @return {Promise<Array<DataWithType>>} */ - static produceMultipleData(dataWithType, customDisplayType, + static produceMultipleData (dataWithType, customDisplayType, magic, textWithoutMagic) { - const data = dataWithType.getData(); - const type = dataWithType.getType(); + const data = dataWithType.getData() + const type = dataWithType.getType() // if the type is specified, just return it // handle non-specified dataWithTypes only if (type) { - return new Promise((resolve) => { resolve([dataWithType]); }); + return new Promise((resolve) => { resolve([dataWithType]) }) } - let wrapped; + let wrapped if (SpellResult.isFunction(data)) { // if data is a function, we consider it as ELEMENT type. wrapped = new Promise((resolve) => { const dt = new DataWithType( - data, DefaultDisplayType.ELEMENT, magic, textWithoutMagic); - const result = [dt]; - return resolve(result); - }); + data, DefaultDisplayType.ELEMENT, magic, textWithoutMagic) + const result = [dt] + return resolve(result) + }) } else if (SpellResult.isPromise(data)) { // if data is a promise, wrapped = data.then(generated => { const result = - DataWithType.parseStringData(generated, customDisplayType); - return result; + DataWithType.parseStringData(generated, customDisplayType) + return result }) - } else { // if data is a object, parse it to multiples wrapped = new Promise((resolve) => { const result = - DataWithType.parseStringData(data, customDisplayType); - return resolve(result); - }); + DataWithType.parseStringData(data, customDisplayType) + return resolve(result) + }) } - return wrapped; + return wrapped } /** @@ -176,8 +175,8 @@ export class DataWithType { * will be called in `then()` of this promise. * @returns {*} `data` which can be object, function or promise. */ - getData() { - return this.data; + getData () { + return this.data } /** @@ -186,66 +185,66 @@ export class DataWithType { * by `SpellResult.parseStringData()` * @returns {string} */ - getType() { - return this.type; + getType () { + return this.type } - getMagic() { - return this.magic; + getMagic () { + return this.magic } - getText() { - return this.text; + getText () { + return this.text } } export class SpellResult { - constructor(resultData, resultType) { - this.dataWithTypes = []; - this.add(resultData, resultType); + constructor (resultData, resultType) { + this.dataWithTypes = [] + this.add(resultData, resultType) } - static isFunction(data) { - return (data && typeof data === 'function'); + static isFunction (data) { + return (data && typeof data === 'function') } - static isPromise(data) { - return (data && typeof data.then === 'function'); + static isPromise (data) { + return (data && typeof data.then === 'function') } - static isObject(data) { + static isObject (data) { return (data && !SpellResult.isFunction(data) && - !SpellResult.isPromise(data)); + !SpellResult.isPromise(data)) } - static extractMagic(allParagraphText) { - const pattern = /^\s*%(\S+)\s*/g; + static extractMagic (allParagraphText) { + const pattern = /^\s*%(\S+)\s*/g try { - let match = pattern.exec(allParagraphText); + let match = pattern.exec(allParagraphText) if (match) { - return `%${match[1].trim()}`; + return `%${match[1].trim()}` } } catch (error) { // failed to parse, ignore } - return undefined; + return undefined } - static createPropagable(resultMsg) { + static createPropagable (resultMsg) { return resultMsg.map(dt => { - return DataWithType.createPropagable(dt); + return DataWithType.createPropagable(dt) }) } - add(resultData, resultType) { + add (resultData, resultType) { if (resultData) { this.dataWithTypes.push( - new DataWithType(resultData, resultType)); + new DataWithType(resultData, resultType)) } - return this; + return this } /** @@ -253,23 +252,23 @@ export class SpellResult { * @param textWithoutMagic * @return {Promise<Array<DataWithType>>} */ - getAllParsedDataWithTypes(customDisplayType, magic, textWithoutMagic) { + getAllParsedDataWithTypes (customDisplayType, magic, textWithoutMagic) { const promises = this.dataWithTypes.map(dt => { return DataWithType.produceMultipleData( - dt, customDisplayType, magic, textWithoutMagic); - }); + dt, customDisplayType, magic, textWithoutMagic) + }) // some promises can include an array so we need to flatten them const flatten = Promise.all(promises).then(values => { return values.reduce((acc, cur) => { if (Array.isArray(cur)) { - return acc.concat(cur); + return acc.concat(cur) } else { - return acc.concat([cur]); + return acc.concat([cur]) } }) - }); + }) - return flatten; + return flatten } }