You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by ku...@apache.org on 2017/07/14 16:07:06 UTC
[1/5] zeppelin git commit: [ZEPPELIN-2749] Use scalable file
structure for zeppelin web
Repository: zeppelin
Updated Branches:
refs/heads/master ebb6591d8 -> 6bd6c7088
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/websocket/websocket-message.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/websocket/websocket-message.service.js b/zeppelin-web/src/components/websocket/websocket-message.service.js
new file mode 100644
index 0000000..9ca631b
--- /dev/null
+++ b/zeppelin-web/src/components/websocket/websocket-message.service.js
@@ -0,0 +1,343 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').service('websocketMsgSrv', WebsocketMessageService)
+
+function WebsocketMessageService ($rootScope, websocketEvents) {
+ 'ngInject'
+
+ return {
+
+ getHomeNote: function () {
+ websocketEvents.sendNewEvent({op: 'GET_HOME_NOTE'})
+ },
+
+ createNotebook: function (noteName, defaultInterpreterId) {
+ websocketEvents.sendNewEvent({
+ op: 'NEW_NOTE',
+ data: {
+ name: noteName,
+ defaultInterpreterId: defaultInterpreterId
+ }
+ })
+ },
+
+ moveNoteToTrash: function (noteId) {
+ websocketEvents.sendNewEvent({op: 'MOVE_NOTE_TO_TRASH', data: {id: noteId}})
+ },
+
+ moveFolderToTrash: function (folderId) {
+ websocketEvents.sendNewEvent({op: 'MOVE_FOLDER_TO_TRASH', data: {id: folderId}})
+ },
+
+ restoreNote: function (noteId) {
+ websocketEvents.sendNewEvent({op: 'RESTORE_NOTE', data: {id: noteId}})
+ },
+
+ restoreFolder: function (folderId) {
+ websocketEvents.sendNewEvent({op: 'RESTORE_FOLDER', data: {id: folderId}})
+ },
+
+ restoreAll: function () {
+ websocketEvents.sendNewEvent({op: 'RESTORE_ALL'})
+ },
+
+ deleteNote: function (noteId) {
+ websocketEvents.sendNewEvent({op: 'DEL_NOTE', data: {id: noteId}})
+ },
+
+ removeFolder: function (folderId) {
+ websocketEvents.sendNewEvent({op: 'REMOVE_FOLDER', data: {id: folderId}})
+ },
+
+ emptyTrash: function () {
+ websocketEvents.sendNewEvent({op: 'EMPTY_TRASH'})
+ },
+
+ cloneNote: function (noteIdToClone, newNoteName) {
+ websocketEvents.sendNewEvent({op: 'CLONE_NOTE', data: {id: noteIdToClone, name: newNoteName}})
+ },
+
+ getNoteList: function () {
+ websocketEvents.sendNewEvent({op: 'LIST_NOTES'})
+ },
+
+ reloadAllNotesFromRepo: function () {
+ websocketEvents.sendNewEvent({op: 'RELOAD_NOTES_FROM_REPO'})
+ },
+
+ getNote: function (noteId) {
+ websocketEvents.sendNewEvent({op: 'GET_NOTE', data: {id: noteId}})
+ },
+
+ updateNote: function (noteId, noteName, noteConfig) {
+ websocketEvents.sendNewEvent({op: 'NOTE_UPDATE', data: {id: noteId, name: noteName, config: noteConfig}})
+ },
+
+ updatePersonalizedMode: function (noteId, modeValue) {
+ websocketEvents.sendNewEvent({op: 'UPDATE_PERSONALIZED_MODE', data: {id: noteId, personalized: modeValue}})
+ },
+
+ renameNote: function (noteId, noteName) {
+ websocketEvents.sendNewEvent({op: 'NOTE_RENAME', data: {id: noteId, name: noteName}})
+ },
+
+ renameFolder: function (folderId, folderName) {
+ websocketEvents.sendNewEvent({op: 'FOLDER_RENAME', data: {id: folderId, name: folderName}})
+ },
+
+ moveParagraph: function (paragraphId, newIndex) {
+ websocketEvents.sendNewEvent({op: 'MOVE_PARAGRAPH', data: {id: paragraphId, index: newIndex}})
+ },
+
+ insertParagraph: function (newIndex) {
+ websocketEvents.sendNewEvent({op: 'INSERT_PARAGRAPH', data: {index: newIndex}})
+ },
+
+ copyParagraph: function (newIndex, paragraphTitle, paragraphData,
+ paragraphConfig, paragraphParams) {
+ websocketEvents.sendNewEvent({
+ op: 'COPY_PARAGRAPH',
+ data: {
+ index: newIndex,
+ title: paragraphTitle,
+ paragraph: paragraphData,
+ config: paragraphConfig,
+ params: paragraphParams
+ }
+ })
+ },
+
+ updateAngularObject: function (noteId, paragraphId, name, value, interpreterGroupId) {
+ websocketEvents.sendNewEvent({
+ op: 'ANGULAR_OBJECT_UPDATED',
+ data: {
+ noteId: noteId,
+ paragraphId: paragraphId,
+ name: name,
+ value: value,
+ interpreterGroupId: interpreterGroupId
+ }
+ })
+ },
+
+ clientBindAngularObject: function (noteId, name, value, paragraphId) {
+ websocketEvents.sendNewEvent({
+ op: 'ANGULAR_OBJECT_CLIENT_BIND',
+ data: {
+ noteId: noteId,
+ name: name,
+ value: value,
+ paragraphId: paragraphId
+ }
+ })
+ },
+
+ clientUnbindAngularObject: function (noteId, name, paragraphId) {
+ websocketEvents.sendNewEvent({
+ op: 'ANGULAR_OBJECT_CLIENT_UNBIND',
+ data: {
+ noteId: noteId,
+ name: name,
+ paragraphId: paragraphId
+ }
+ })
+ },
+
+ cancelParagraphRun: function (paragraphId) {
+ websocketEvents.sendNewEvent({op: 'CANCEL_PARAGRAPH', data: {id: paragraphId}})
+ },
+
+ paragraphExecutedBySpell: function (paragraphId, paragraphTitle,
+ paragraphText, paragraphResultsMsg,
+ paragraphStatus, paragraphErrorMessage,
+ paragraphConfig, paragraphParams,
+ paragraphDateStarted, paragraphDateFinished) {
+ websocketEvents.sendNewEvent({
+ op: 'PARAGRAPH_EXECUTED_BY_SPELL',
+ data: {
+ id: paragraphId,
+ title: paragraphTitle,
+ paragraph: paragraphText,
+ results: {
+ code: paragraphStatus,
+ msg: paragraphResultsMsg.map(dataWithType => {
+ let serializedData = dataWithType.data
+ return { type: dataWithType.type, data: serializedData, }
+ })
+ },
+ status: paragraphStatus,
+ errorMessage: paragraphErrorMessage,
+ config: paragraphConfig,
+ params: paragraphParams,
+ dateStarted: paragraphDateStarted,
+ dateFinished: paragraphDateFinished,
+ }
+ })
+ },
+
+ runParagraph: function (paragraphId, paragraphTitle, paragraphData, paragraphConfig, paragraphParams) {
+ websocketEvents.sendNewEvent({
+ op: 'RUN_PARAGRAPH',
+ data: {
+ id: paragraphId,
+ title: paragraphTitle,
+ paragraph: paragraphData,
+ config: paragraphConfig,
+ params: paragraphParams
+ }
+ })
+ },
+
+ runAllParagraphs: function (noteId, paragraphs) {
+ websocketEvents.sendNewEvent({
+ op: 'RUN_ALL_PARAGRAPHS',
+ data: {
+ noteId: noteId,
+ paragraphs: JSON.stringify(paragraphs)
+ }
+ })
+ },
+
+ removeParagraph: function (paragraphId) {
+ websocketEvents.sendNewEvent({op: 'PARAGRAPH_REMOVE', data: {id: paragraphId}})
+ },
+
+ clearParagraphOutput: function (paragraphId) {
+ websocketEvents.sendNewEvent({op: 'PARAGRAPH_CLEAR_OUTPUT', data: {id: paragraphId}})
+ },
+
+ clearAllParagraphOutput: function (noteId) {
+ websocketEvents.sendNewEvent({op: 'PARAGRAPH_CLEAR_ALL_OUTPUT', data: {id: noteId}})
+ },
+
+ completion: function (paragraphId, buf, cursor) {
+ websocketEvents.sendNewEvent({
+ op: 'COMPLETION',
+ data: {
+ id: paragraphId,
+ buf: buf,
+ cursor: cursor
+ }
+ })
+ },
+
+ commitParagraph: function (paragraphId, paragraphTitle, paragraphData, paragraphConfig, paragraphParams) {
+ websocketEvents.sendNewEvent({
+ op: 'COMMIT_PARAGRAPH',
+ data: {
+ id: paragraphId,
+ title: paragraphTitle,
+ paragraph: paragraphData,
+ config: paragraphConfig,
+ params: paragraphParams
+ }
+ })
+ },
+
+ importNote: function (note) {
+ websocketEvents.sendNewEvent({
+ op: 'IMPORT_NOTE',
+ data: {
+ note: note
+ }
+ })
+ },
+
+ checkpointNote: function (noteId, commitMessage) {
+ websocketEvents.sendNewEvent({
+ op: 'CHECKPOINT_NOTE',
+ data: {
+ noteId: noteId,
+ commitMessage: commitMessage
+ }
+ })
+ },
+
+ setNoteRevision: function (noteId, revisionId) {
+ websocketEvents.sendNewEvent({
+ op: 'SET_NOTE_REVISION',
+ data: {
+ noteId: noteId,
+ revisionId: revisionId
+ }
+ })
+ },
+
+ listRevisionHistory: function (noteId) {
+ websocketEvents.sendNewEvent({
+ op: 'LIST_REVISION_HISTORY',
+ data: {
+ noteId: noteId
+ }
+ })
+ },
+
+ getNoteByRevision: function (noteId, revisionId) {
+ websocketEvents.sendNewEvent({
+ op: 'NOTE_REVISION',
+ data: {
+ noteId: noteId,
+ revisionId: revisionId
+ }
+ })
+ },
+
+ getEditorSetting: function (paragraphId, replName) {
+ websocketEvents.sendNewEvent({
+ op: 'EDITOR_SETTING',
+ data: {
+ paragraphId: paragraphId,
+ magic: replName
+ }
+ })
+ },
+
+ isConnected: function () {
+ return websocketEvents.isConnected()
+ },
+
+ getNoteJobsList: function () {
+ websocketEvents.sendNewEvent({op: 'LIST_NOTE_JOBS'})
+ },
+
+ getUpdateNoteJobsList: function (lastUpdateServerUnixTime) {
+ websocketEvents.sendNewEvent(
+ {op: 'LIST_UPDATE_NOTE_JOBS', data: {lastUpdateUnixTime: lastUpdateServerUnixTime * 1}}
+ )
+ },
+
+ unsubscribeJobManager: function () {
+ websocketEvents.sendNewEvent({op: 'UNSUBSCRIBE_UPDATE_NOTE_JOBS'})
+ },
+
+ getInterpreterBindings: function (noteId) {
+ websocketEvents.sendNewEvent({op: 'GET_INTERPRETER_BINDINGS', data: {noteId: noteId}})
+ },
+
+ saveInterpreterBindings: function (noteId, selectedSettingIds) {
+ websocketEvents.sendNewEvent({op: 'SAVE_INTERPRETER_BINDINGS',
+ data: {noteId: noteId, selectedSettingIds: selectedSettingIds}})
+ },
+
+ listConfigurations: function () {
+ websocketEvents.sendNewEvent({op: 'LIST_CONFIGURATIONS'})
+ },
+
+ getInterpreterSettings: function () {
+ websocketEvents.sendNewEvent({op: 'GET_INTERPRETER_SETTINGS'})
+ },
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js b/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js
deleted file mode 100644
index 16b3f7a..0000000
--- a/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').factory('websocketEvents', websocketEvents)
-
-function websocketEvents ($rootScope, $websocket, $location, baseUrlSrv) {
- 'ngInject'
-
- let websocketCalls = {}
- let pingIntervalId
-
- websocketCalls.ws = $websocket(baseUrlSrv.getWebsocketUrl())
- websocketCalls.ws.reconnectIfNotNormalClose = true
-
- websocketCalls.ws.onOpen(function () {
- console.log('Websocket created')
- $rootScope.$broadcast('setConnectedStatus', true)
- pingIntervalId = setInterval(function () {
- websocketCalls.sendNewEvent({op: 'PING'})
- }, 10000)
- })
-
- websocketCalls.sendNewEvent = function (data) {
- if ($rootScope.ticket !== undefined) {
- data.principal = $rootScope.ticket.principal
- data.ticket = $rootScope.ticket.ticket
- data.roles = $rootScope.ticket.roles
- } else {
- data.principal = ''
- data.ticket = ''
- data.roles = ''
- }
- console.log('Send >> %o, %o, %o, %o, %o', data.op, data.principal, data.ticket, data.roles, data)
- websocketCalls.ws.send(JSON.stringify(data))
- }
-
- websocketCalls.isConnected = function () {
- return (websocketCalls.ws.socket.readyState === 1)
- }
-
- websocketCalls.ws.onMessage(function (event) {
- let payload
- if (event.data) {
- payload = angular.fromJson(event.data)
- }
-
- console.log('Receive << %o, %o', payload.op, payload)
-
- let op = payload.op
- let data = payload.data
- if (op === 'NOTE') {
- $rootScope.$broadcast('setNoteContent', data.note)
- } else if (op === 'NEW_NOTE') {
- $location.path('/notebook/' + data.note.id)
- } else if (op === 'NOTES_INFO') {
- $rootScope.$broadcast('setNoteMenu', data.notes)
- } else if (op === 'LIST_NOTE_JOBS') {
- $rootScope.$broadcast('setNoteJobs', data.noteJobs)
- } else if (op === 'LIST_UPDATE_NOTE_JOBS') {
- $rootScope.$broadcast('setUpdateNoteJobs', data.noteRunningJobs)
- } else if (op === 'AUTH_INFO') {
- let btn = []
- if ($rootScope.ticket.roles === '[]') {
- btn = [{
- label: 'Close',
- action: function (dialog) {
- dialog.close()
- }
- }]
- } else {
- btn = [{
- label: 'Login',
- action: function (dialog) {
- dialog.close()
- angular.element('#loginModal').modal({
- show: 'true'
- })
- }
- }, {
- label: 'Cancel',
- action: function (dialog) {
- dialog.close()
- // using $rootScope.apply to trigger angular digest cycle
- // changing $location.path inside bootstrap modal wont trigger digest
- $rootScope.$apply(function () {
- $location.path('/')
- })
- }
- }]
- }
-
- BootstrapDialog.show({
- closable: false,
- closeByBackdrop: false,
- closeByKeyboard: false,
- title: 'Insufficient privileges',
- message: data.info.toString(),
- buttons: btn
- })
- } else if (op === 'PARAGRAPH') {
- $rootScope.$broadcast('updateParagraph', data)
- } else if (op === 'RUN_PARAGRAPH_USING_SPELL') {
- $rootScope.$broadcast('runParagraphUsingSpell', data)
- } else if (op === 'PARAGRAPH_APPEND_OUTPUT') {
- $rootScope.$broadcast('appendParagraphOutput', data)
- } else if (op === 'PARAGRAPH_UPDATE_OUTPUT') {
- $rootScope.$broadcast('updateParagraphOutput', data)
- } else if (op === 'PROGRESS') {
- $rootScope.$broadcast('updateProgress', data)
- } else if (op === 'COMPLETION_LIST') {
- $rootScope.$broadcast('completionList', data)
- } else if (op === 'EDITOR_SETTING') {
- $rootScope.$broadcast('editorSetting', data)
- } else if (op === 'ANGULAR_OBJECT_UPDATE') {
- $rootScope.$broadcast('angularObjectUpdate', data)
- } else if (op === 'ANGULAR_OBJECT_REMOVE') {
- $rootScope.$broadcast('angularObjectRemove', data)
- } else if (op === 'APP_APPEND_OUTPUT') {
- $rootScope.$broadcast('appendAppOutput', data)
- } else if (op === 'APP_UPDATE_OUTPUT') {
- $rootScope.$broadcast('updateAppOutput', data)
- } else if (op === 'APP_LOAD') {
- $rootScope.$broadcast('appLoad', data)
- } else if (op === 'APP_STATUS_CHANGE') {
- $rootScope.$broadcast('appStatusChange', data)
- } else if (op === 'LIST_REVISION_HISTORY') {
- $rootScope.$broadcast('listRevisionHistory', data)
- } else if (op === 'NOTE_REVISION') {
- $rootScope.$broadcast('noteRevision', data)
- } else if (op === 'INTERPRETER_BINDINGS') {
- $rootScope.$broadcast('interpreterBindings', data)
- } else if (op === 'ERROR_INFO') {
- BootstrapDialog.show({
- closable: false,
- closeByBackdrop: false,
- closeByKeyboard: false,
- title: 'Details',
- message: data.info.toString(),
- buttons: [{
- // close all the dialogs when there are error on running all paragraphs
- label: 'Close',
- action: function () {
- BootstrapDialog.closeAll()
- }
- }]
- })
- } else if (op === 'SESSION_LOGOUT') {
- $rootScope.$broadcast('session_logout', data)
- } else if (op === 'CONFIGURATIONS_INFO') {
- $rootScope.$broadcast('configurationsInfo', data)
- } else if (op === 'INTERPRETER_SETTINGS') {
- $rootScope.$broadcast('interpreterSettings', data)
- } else if (op === 'PARAGRAPH_ADDED') {
- $rootScope.$broadcast('addParagraph', data.paragraph, data.index)
- } else if (op === 'PARAGRAPH_REMOVED') {
- $rootScope.$broadcast('removeParagraph', data.id)
- } else if (op === 'PARAGRAPH_MOVED') {
- $rootScope.$broadcast('moveParagraph', data.id, data.index)
- } else if (op === 'NOTE_UPDATED') {
- $rootScope.$broadcast('updateNote', data.name, data.config, data.info)
- } else if (op === 'SET_NOTE_REVISION') {
- $rootScope.$broadcast('setNoteRevisionResult', data)
- } else if (op === 'PARAS_INFO') {
- $rootScope.$broadcast('updateParaInfos', data)
- } else {
- console.error(`unknown websocket op: ${op}`)
- }
- })
-
- websocketCalls.ws.onError(function (event) {
- console.log('error message: ', event)
- $rootScope.$broadcast('setConnectedStatus', false)
- })
-
- websocketCalls.ws.onClose(function (event) {
- console.log('close message: ', event)
- if (pingIntervalId !== undefined) {
- clearInterval(pingIntervalId)
- pingIntervalId = undefined
- }
- $rootScope.$broadcast('setConnectedStatus', false)
- })
-
- return websocketCalls
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js b/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js
deleted file mode 100644
index 3fa56f3..0000000
--- a/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').service('websocketMsgSrv', websocketMsgSrv)
-
-function websocketMsgSrv ($rootScope, websocketEvents) {
- 'ngInject'
-
- return {
-
- getHomeNote: function () {
- websocketEvents.sendNewEvent({op: 'GET_HOME_NOTE'})
- },
-
- createNotebook: function (noteName, defaultInterpreterId) {
- websocketEvents.sendNewEvent({
- op: 'NEW_NOTE',
- data: {
- name: noteName,
- defaultInterpreterId: defaultInterpreterId
- }
- })
- },
-
- moveNoteToTrash: function (noteId) {
- websocketEvents.sendNewEvent({op: 'MOVE_NOTE_TO_TRASH', data: {id: noteId}})
- },
-
- moveFolderToTrash: function (folderId) {
- websocketEvents.sendNewEvent({op: 'MOVE_FOLDER_TO_TRASH', data: {id: folderId}})
- },
-
- restoreNote: function (noteId) {
- websocketEvents.sendNewEvent({op: 'RESTORE_NOTE', data: {id: noteId}})
- },
-
- restoreFolder: function (folderId) {
- websocketEvents.sendNewEvent({op: 'RESTORE_FOLDER', data: {id: folderId}})
- },
-
- restoreAll: function () {
- websocketEvents.sendNewEvent({op: 'RESTORE_ALL'})
- },
-
- deleteNote: function (noteId) {
- websocketEvents.sendNewEvent({op: 'DEL_NOTE', data: {id: noteId}})
- },
-
- removeFolder: function (folderId) {
- websocketEvents.sendNewEvent({op: 'REMOVE_FOLDER', data: {id: folderId}})
- },
-
- emptyTrash: function () {
- websocketEvents.sendNewEvent({op: 'EMPTY_TRASH'})
- },
-
- cloneNote: function (noteIdToClone, newNoteName) {
- websocketEvents.sendNewEvent({op: 'CLONE_NOTE', data: {id: noteIdToClone, name: newNoteName}})
- },
-
- getNoteList: function () {
- websocketEvents.sendNewEvent({op: 'LIST_NOTES'})
- },
-
- reloadAllNotesFromRepo: function () {
- websocketEvents.sendNewEvent({op: 'RELOAD_NOTES_FROM_REPO'})
- },
-
- getNote: function (noteId) {
- websocketEvents.sendNewEvent({op: 'GET_NOTE', data: {id: noteId}})
- },
-
- updateNote: function (noteId, noteName, noteConfig) {
- websocketEvents.sendNewEvent({op: 'NOTE_UPDATE', data: {id: noteId, name: noteName, config: noteConfig}})
- },
-
- updatePersonalizedMode: function (noteId, modeValue) {
- websocketEvents.sendNewEvent({op: 'UPDATE_PERSONALIZED_MODE', data: {id: noteId, personalized: modeValue}})
- },
-
- renameNote: function (noteId, noteName) {
- websocketEvents.sendNewEvent({op: 'NOTE_RENAME', data: {id: noteId, name: noteName}})
- },
-
- renameFolder: function (folderId, folderName) {
- websocketEvents.sendNewEvent({op: 'FOLDER_RENAME', data: {id: folderId, name: folderName}})
- },
-
- moveParagraph: function (paragraphId, newIndex) {
- websocketEvents.sendNewEvent({op: 'MOVE_PARAGRAPH', data: {id: paragraphId, index: newIndex}})
- },
-
- insertParagraph: function (newIndex) {
- websocketEvents.sendNewEvent({op: 'INSERT_PARAGRAPH', data: {index: newIndex}})
- },
-
- copyParagraph: function (newIndex, paragraphTitle, paragraphData,
- paragraphConfig, paragraphParams) {
- websocketEvents.sendNewEvent({
- op: 'COPY_PARAGRAPH',
- data: {
- index: newIndex,
- title: paragraphTitle,
- paragraph: paragraphData,
- config: paragraphConfig,
- params: paragraphParams
- }
- })
- },
-
- updateAngularObject: function (noteId, paragraphId, name, value, interpreterGroupId) {
- websocketEvents.sendNewEvent({
- op: 'ANGULAR_OBJECT_UPDATED',
- data: {
- noteId: noteId,
- paragraphId: paragraphId,
- name: name,
- value: value,
- interpreterGroupId: interpreterGroupId
- }
- })
- },
-
- clientBindAngularObject: function (noteId, name, value, paragraphId) {
- websocketEvents.sendNewEvent({
- op: 'ANGULAR_OBJECT_CLIENT_BIND',
- data: {
- noteId: noteId,
- name: name,
- value: value,
- paragraphId: paragraphId
- }
- })
- },
-
- clientUnbindAngularObject: function (noteId, name, paragraphId) {
- websocketEvents.sendNewEvent({
- op: 'ANGULAR_OBJECT_CLIENT_UNBIND',
- data: {
- noteId: noteId,
- name: name,
- paragraphId: paragraphId
- }
- })
- },
-
- cancelParagraphRun: function (paragraphId) {
- websocketEvents.sendNewEvent({op: 'CANCEL_PARAGRAPH', data: {id: paragraphId}})
- },
-
- paragraphExecutedBySpell: function (paragraphId, paragraphTitle,
- paragraphText, paragraphResultsMsg,
- paragraphStatus, paragraphErrorMessage,
- paragraphConfig, paragraphParams,
- paragraphDateStarted, paragraphDateFinished) {
- websocketEvents.sendNewEvent({
- op: 'PARAGRAPH_EXECUTED_BY_SPELL',
- data: {
- id: paragraphId,
- title: paragraphTitle,
- paragraph: paragraphText,
- results: {
- code: paragraphStatus,
- msg: paragraphResultsMsg.map(dataWithType => {
- let serializedData = dataWithType.data
- return { type: dataWithType.type, data: serializedData, }
- })
- },
- status: paragraphStatus,
- errorMessage: paragraphErrorMessage,
- config: paragraphConfig,
- params: paragraphParams,
- dateStarted: paragraphDateStarted,
- dateFinished: paragraphDateFinished,
- }
- })
- },
-
- runParagraph: function (paragraphId, paragraphTitle, paragraphData, paragraphConfig, paragraphParams) {
- websocketEvents.sendNewEvent({
- op: 'RUN_PARAGRAPH',
- data: {
- id: paragraphId,
- title: paragraphTitle,
- paragraph: paragraphData,
- config: paragraphConfig,
- params: paragraphParams
- }
- })
- },
-
- runAllParagraphs: function (noteId, paragraphs) {
- websocketEvents.sendNewEvent({
- op: 'RUN_ALL_PARAGRAPHS',
- data: {
- noteId: noteId,
- paragraphs: JSON.stringify(paragraphs)
- }
- })
- },
-
- removeParagraph: function (paragraphId) {
- websocketEvents.sendNewEvent({op: 'PARAGRAPH_REMOVE', data: {id: paragraphId}})
- },
-
- clearParagraphOutput: function (paragraphId) {
- websocketEvents.sendNewEvent({op: 'PARAGRAPH_CLEAR_OUTPUT', data: {id: paragraphId}})
- },
-
- clearAllParagraphOutput: function (noteId) {
- websocketEvents.sendNewEvent({op: 'PARAGRAPH_CLEAR_ALL_OUTPUT', data: {id: noteId}})
- },
-
- completion: function (paragraphId, buf, cursor) {
- websocketEvents.sendNewEvent({
- op: 'COMPLETION',
- data: {
- id: paragraphId,
- buf: buf,
- cursor: cursor
- }
- })
- },
-
- commitParagraph: function (paragraphId, paragraphTitle, paragraphData, paragraphConfig, paragraphParams) {
- websocketEvents.sendNewEvent({
- op: 'COMMIT_PARAGRAPH',
- data: {
- id: paragraphId,
- title: paragraphTitle,
- paragraph: paragraphData,
- config: paragraphConfig,
- params: paragraphParams
- }
- })
- },
-
- importNote: function (note) {
- websocketEvents.sendNewEvent({
- op: 'IMPORT_NOTE',
- data: {
- note: note
- }
- })
- },
-
- checkpointNote: function (noteId, commitMessage) {
- websocketEvents.sendNewEvent({
- op: 'CHECKPOINT_NOTE',
- data: {
- noteId: noteId,
- commitMessage: commitMessage
- }
- })
- },
-
- setNoteRevision: function (noteId, revisionId) {
- websocketEvents.sendNewEvent({
- op: 'SET_NOTE_REVISION',
- data: {
- noteId: noteId,
- revisionId: revisionId
- }
- })
- },
-
- listRevisionHistory: function (noteId) {
- websocketEvents.sendNewEvent({
- op: 'LIST_REVISION_HISTORY',
- data: {
- noteId: noteId
- }
- })
- },
-
- getNoteByRevision: function (noteId, revisionId) {
- websocketEvents.sendNewEvent({
- op: 'NOTE_REVISION',
- data: {
- noteId: noteId,
- revisionId: revisionId
- }
- })
- },
-
- getEditorSetting: function (paragraphId, replName) {
- websocketEvents.sendNewEvent({
- op: 'EDITOR_SETTING',
- data: {
- paragraphId: paragraphId,
- magic: replName
- }
- })
- },
-
- isConnected: function () {
- return websocketEvents.isConnected()
- },
-
- getNoteJobsList: function () {
- websocketEvents.sendNewEvent({op: 'LIST_NOTE_JOBS'})
- },
-
- getUpdateNoteJobsList: function (lastUpdateServerUnixTime) {
- websocketEvents.sendNewEvent(
- {op: 'LIST_UPDATE_NOTE_JOBS', data: {lastUpdateUnixTime: lastUpdateServerUnixTime * 1}}
- )
- },
-
- unsubscribeJobManager: function () {
- websocketEvents.sendNewEvent({op: 'UNSUBSCRIBE_UPDATE_NOTE_JOBS'})
- },
-
- getInterpreterBindings: function (noteId) {
- websocketEvents.sendNewEvent({op: 'GET_INTERPRETER_BINDINGS', data: {noteId: noteId}})
- },
-
- saveInterpreterBindings: function (noteId, selectedSettingIds) {
- websocketEvents.sendNewEvent({op: 'SAVE_INTERPRETER_BINDINGS',
- data: {noteId: noteId, selectedSettingIds: selectedSettingIds}})
- },
-
- listConfigurations: function () {
- websocketEvents.sendNewEvent({op: 'LIST_CONFIGURATIONS'})
- },
-
- getInterpreterSettings: function () {
- websocketEvents.sendNewEvent({op: 'GET_INTERPRETER_SETTINGS'})
- },
-
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/index.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/index.html b/zeppelin-web/src/index.html
index 547fd3a..90631eb 100644
--- a/zeppelin-web/src/index.html
+++ b/zeppelin-web/src/index.html
@@ -62,7 +62,6 @@ limitations under the License.
<link rel="stylesheet" href="app/helium/helium.css" />
<link rel="stylesheet" href="app/credential/credential.css" />
<link rel="stylesheet" href="app/configuration/configuration.css" />
- <link rel="stylesheet" href="components/expandCollapse/expandCollapse.css" />
<link rel="stylesheet" href="fonts/font-awesome.min.css" />
<link rel="stylesheet" href="fonts/simple-line-icons.css" />
<link rel="stylesheet" href="fonts/custom-font.css" />
@@ -81,19 +80,19 @@ limitations under the License.
<div id="main" class="container">
<div ng-view></div>
</div>
- <!-- Modal :: Keyboard shortcuts -->
- <div ng-include src="'components/modal-shortcut/modal-shortcut.html'"></div>
- <div ng-controller="NotenameCtrl as notenamectrl">
- <div id="note-modal-container" ng-include src="'components/noteName-create/note-name-dialog.html'"></div>
+ <!-- global :: dialogs -->
+ <div ng-include src="'app/notebook/shortcut.html'"></div>
+ <div ng-controller="NoteCreateCtrl as noteCreateCtrl">
+ <div id="note-modal-container" ng-include src="'components/note-create/note-create.html'"></div>
</div>
- <div ng-controller="NoteImportCtrl as noteimportctrl">
- <div id="note-import-container" ng-include src="'components/noteName-import/note-import-dialog.html'"></div>
+ <div ng-controller="NoteImportCtrl as noteImportCtrl">
+ <div id="note-import-container" ng-include src="'components/note-import/note-import.html'"></div>
</div>
- <div ng-controller="LoginCtrl as noteimportctrl">
+ <div ng-controller="LoginCtrl">
<div id="login-container" ng-include src="'components/login/login.html'"></div>
</div>
- <div ng-controller="RenameCtrl">
- <div ng-include src="'components/rename/rename.html'"></div>
+ <div ng-controller="NoteRenameCtrl">
+ <div ng-include src="'components/note-rename/note-rename.html'"></div>
</div>
<!-- build:js(.) scripts/oldieshim.js -->
<!--[if lt IE 9]>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/index.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/index.js b/zeppelin-web/src/index.js
index de77686..75faca0 100644
--- a/zeppelin-web/src/index.js
+++ b/zeppelin-web/src/index.js
@@ -40,38 +40,38 @@ import './app/jobmanager/jobs/job.controller.js'
import './app/jobmanager/jobmanager.filter.js'
import './app/interpreter/interpreter.controller.js'
import './app/interpreter/interpreter.filter.js'
+import './app/interpreter/interpreter-item.directive.js'
+import './app/interpreter/widget/number-widget.directive.js'
import './app/credential/credential.controller.js'
import './app/configuration/configuration.controller.js'
import './app/notebook/paragraph/paragraph.controller.js'
+import './app/notebook/paragraph/clipboard.controller.js'
+import './app/notebook/paragraph/resizable.directive.js'
import './app/notebook/paragraph/result/result.controller.js'
+import './app/notebook/paragraph/code-editor/code-editor.directive.js'
+import './app/notebook/save-as/save-as.service.js'
+import './app/notebook/save-as/browser-detect.service.js'
+import './app/notebook/elastic-input/elastic-input.controller.js'
+import './app/notebook/dropdown-input/dropdown-input.directive.js'
+import './app/notebook/note-var-share.service.js'
+import './app/notebook-repository/notebook-repository.controller.js'
import './app/search/result-list.controller.js'
-import './app/notebookRepos/notebookRepos.controller.js'
+import './app/search/search.service.js'
import './app/helium'
-import './components/arrayOrderingSrv/arrayOrdering.service.js'
-import './components/clipboard/clipboard.controller.js'
+import './app/helium/helium.service.js'
+import './components/array-ordering/array-ordering.service.js'
import './components/navbar/navbar.controller.js'
-import './components/ngescape/ngescape.directive.js'
-import './components/interpreter/interpreter.directive.js'
-import './components/interpreter/widget/widget.number.directive.js'
-import './components/expandCollapse/expandCollapse.directive.js'
-import './components/noteName-create/notename.controller.js'
-import './components/noteName-import/notenameImport.controller.js'
-import './components/editor/codeEditor.directive.js'
-import './components/ngenter/ngenter.directive.js'
-import './components/dropdowninput/dropdowninput.directive.js'
-import './components/resizable/resizable.directive.js'
-import './components/noteName-create/visible.directive.js'
-import './components/websocketEvents/websocketMsg.service.js'
-import './components/websocketEvents/websocketEvents.factory.js'
-import './components/noteListDataFactory/noteList.datafactory.js'
-import './components/baseUrl/baseUrl.service.js'
-import './components/browser-detect/browserDetect.service.js'
-import './components/saveAs/saveAs.service.js'
-import './components/searchService/search.service.js'
+import './components/navbar/expand-collapse/expand-collapse.directive.js'
+import './components/note-create/note-create.controller.js'
+import './components/note-create/visible.directive.js'
+import './components/note-import/note-import.controller.js'
+import './components/ng-enter/ng-enter.directive.js'
+import './components/ng-escape/ng-escape.directive.js'
+import './components/websocket/websocket-message.service.js'
+import './components/websocket/websocket-event.factory.js'
+import './components/note-list/note-list.factory.js'
+import './components/base-url/base-url.service.js'
import './components/login/login.controller.js'
-import './components/elasticInputCtrl/elasticInput.controller.js'
-import './components/noteAction/noteAction.service.js'
-import './components/notevarshareService/notevarshare.service.js'
-import './components/rename/rename.controller.js'
-import './components/rename/rename.service.js'
-import './components/helium/helium.service.js'
+import './components/note-action/note-action.service.js'
+import './components/note-rename/note-rename.controller.js'
+import './components/note-rename/note-rename.service.js'
[3/5] zeppelin git commit: [ZEPPELIN-2749] Use scalable file
structure for zeppelin web
Posted by ku...@apache.org.
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/elasticInputCtrl/elasticInput.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/elasticInputCtrl/elasticInput.controller.js b/zeppelin-web/src/components/elasticInputCtrl/elasticInput.controller.js
deleted file mode 100644
index 507b2f6..0000000
--- a/zeppelin-web/src/components/elasticInputCtrl/elasticInput.controller.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').controller('ElasticInputCtrl', ElasticInputCtrl)
-
-function ElasticInputCtrl () {
- let vm = this
- vm.showEditor = false
- vm.value = ''
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/expandCollapse/expandCollapse.css
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/expandCollapse/expandCollapse.css b/zeppelin-web/src/components/expandCollapse/expandCollapse.css
deleted file mode 100644
index b1a60d8..0000000
--- a/zeppelin-web/src/components/expandCollapse/expandCollapse.css
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * 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.
- */
-
- .expandable {
- display: none;
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/expandCollapse/expandCollapse.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/expandCollapse/expandCollapse.directive.js b/zeppelin-web/src/components/expandCollapse/expandCollapse.directive.js
deleted file mode 100644
index c71fae0..0000000
--- a/zeppelin-web/src/components/expandCollapse/expandCollapse.directive.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').directive('expandCollapse', expandCollapse)
-
-function expandCollapse () {
- return {
- restrict: 'EA',
- link: function (scope, element, attrs) {
- angular.element(element).click(function (event) {
- if (angular.element(element).find('.expandable:visible').length > 1) {
- angular.element(element).find('.expandable:visible').slideUp('slow')
- angular.element(element).find('i.fa-folder-open').toggleClass('fa-folder fa-folder-open')
- } else {
- angular.element(element).find('.expandable').first().slideToggle('200', function () {
- // do not toggle trash folder
- if (angular.element(element).find('.fa-trash-o').length === 0) {
- angular.element(element).find('i').first().toggleClass('fa-folder fa-folder-open')
- }
- })
- }
-
- let target = event.target
-
- // add note
- if (target.classList !== undefined && target.classList.contains('fa-plus') &&
- target.tagName.toLowerCase() === 'i') {
- return
- }
-
- event.stopPropagation()
- })
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/filterNoteNames/filter-note-names.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/filterNoteNames/filter-note-names.html b/zeppelin-web/src/components/filterNoteNames/filter-note-names.html
deleted file mode 100644
index 071cba4..0000000
--- a/zeppelin-web/src/components/filterNoteNames/filter-note-names.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!--
-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.
--->
-<input type="text"
- class="note-name-query form-control"
- ng-click="$event.stopPropagation()"
- placeholder=" Filter"
- ng-model="$parent.query.q"
- ng-model-options="{ updateOn: 'default blur', debounce: { 'default': 300, 'blur': 0 } }" />
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/helium/helium-conf.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/helium/helium-conf.js b/zeppelin-web/src/components/helium/helium-conf.js
deleted file mode 100644
index 10ca18a..0000000
--- a/zeppelin-web/src/components/helium/helium-conf.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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 createAllPackageConfigs (defaultPackages, persistedConfs) {
- let packageConfs = {}
-
- for (let name in defaultPackages) {
- const pkgSearchResult = defaultPackages[name]
-
- const spec = pkgSearchResult.pkg.config
- if (!spec) { continue }
-
- const artifact = pkgSearchResult.pkg.artifact
- if (!artifact) { continue }
-
- let persistedConf = {}
- if (persistedConfs[artifact]) {
- persistedConf = persistedConfs[artifact]
- }
-
- 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 (currentConfs) {
- const filtered = currentConfs.reduce((acc, c) => {
- acc[c.name] = parseConfigValue(c.type, c.value)
- return acc
- }, {})
-
- return filtered
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/helium/helium-package.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/helium/helium-package.js b/zeppelin-web/src/components/helium/helium-package.js
deleted file mode 100644
index 88d191a..0000000
--- a/zeppelin-web/src/components/helium/helium-package.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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 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
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/helium/helium-type.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/helium/helium-type.js b/zeppelin-web/src/components/helium/helium-type.js
deleted file mode 100644
index 27b34fa..0000000
--- a/zeppelin-web/src/components/helium/helium-type.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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 HeliumType = {
- VISUALIZATION: 'VISUALIZATION',
- SPELL: 'SPELL',
- INTERPRETER: 'INTERPRETER',
- APPLICATION: 'APPLICATION',
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/helium/helium.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/helium/helium.service.js b/zeppelin-web/src/components/helium/helium.service.js
deleted file mode 100644
index 46fcc85..0000000
--- a/zeppelin-web/src/components/helium/helium.service.js
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * 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'
-import {
- createAllPackageConfigs,
- createPersistableConfig,
- mergePersistedConfWithSpec,
-} from './helium-conf'
-import {
- createDefaultPackages,
-} from './helium-package'
-
-angular.module('zeppelinWebApp').service('heliumService', heliumService)
-
-export default function heliumService ($http, $sce, baseUrlSrv) {
- 'ngInject'
-
- let visualizationBundles = []
- let visualizationPackageOrder = []
- // name `heliumBundles` should be same as `HeliumBundleFactory.HELIUM_BUNDLES_VAR`
- let heliumBundles = []
- // map for `{ magic: interpreter }`
- let spellPerMagic = {}
- // map for `{ magic: package-name }`
- let pkgNamePerMagic = {}
-
- /**
- * @param magic {string} e.g `%flowchart`
- * @returns {SpellBase} undefined if magic is not registered
- */
- this.getSpellByMagic = function (magic) {
- return spellPerMagic[magic]
- }
-
- this.executeSpell = function (magic, textWithoutMagic) {
- const promisedConf = this.getSinglePackageConfigUsingMagic(magic)
- .then(confs => createPersistableConfig(confs))
-
- return promisedConf.then(conf => {
- const spell = this.getSpellByMagic(magic)
- const spellResult = spell.interpret(textWithoutMagic, conf)
- const parsed = spellResult.getAllParsedDataWithTypes(
- spellPerMagic, magic, textWithoutMagic)
-
- return parsed
- })
- }
-
- this.executeSpellAsDisplaySystem = function (magic, textWithoutMagic) {
- const promisedConf = this.getSinglePackageConfigUsingMagic(magic)
- .then(confs => createPersistableConfig(confs))
-
- return promisedConf.then(conf => {
- const spell = this.getSpellByMagic(magic)
- const spellResult = spell.interpret(textWithoutMagic.trim(), conf)
- const parsed = spellResult.getAllParsedDataWithTypes(spellPerMagic)
-
- return parsed
- })
- }
-
- this.getVisualizationCachedPackages = function () {
- return visualizationBundles
- }
-
- this.getVisualizationCachedPackageOrder = function () {
- return visualizationPackageOrder
- }
-
- /**
- * @returns {Promise} which returns bundleOrder and cache it in `visualizationPackageOrder`
- */
- this.getVisualizationPackageOrder = function () {
- return $http.get(baseUrlSrv.getRestApiBase() + '/helium/order/visualization')
- .then(function (response, status) {
- const order = response.data.body
- visualizationPackageOrder = order
- return order
- })
- .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.enable = function (name, artifact) {
- return $http.post(baseUrlSrv.getRestApiBase() + '/helium/enable/' + name, artifact)
- }
-
- this.disable = function (name) {
- return $http.post(baseUrlSrv.getRestApiBase() + '/helium/disable/' + name)
- }
-
- this.saveConfig = function (pkg, defaultPackageConfig, closeConfigPanelCallback) {
- // in case of local package, it will include `/`
- const pkgArtifact = encodeURIComponent(pkg.artifact)
- const pkgName = pkg.name
- const filtered = createPersistableConfig(defaultPackageConfig)
-
- if (!pkgName || !pkgArtifact || !filtered) {
- console.error(
- `Can't save config for helium package '${pkgArtifact}'`, filtered)
- return
- }
-
- const url = `${baseUrlSrv.getRestApiBase()}/helium/config/${pkgName}/${pkgArtifact}`
- return $http.post(url, filtered)
- .then(() => {
- if (closeConfigPanelCallback) { closeConfigPanelCallback() }
- }).catch((error) => {
- console.error(`Failed to save config for ${pkgArtifact}`, error)
- })
- }
-
- /**
- * @returns {Promise<Object>} which including {name, Array<package info for artifact>}
- */
- 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)
- })
- }
-
- this.getAllEnabledPackages = function () {
- return $http.get(`${baseUrlSrv.getRestApiBase()}/helium/enabledPackage`)
- .then(function (response, status) {
- return response.data.body
- })
- .catch(function (error) {
- console.error('Failed to get all enabled package infos', error)
- })
- }
-
- this.getSingleBundle = function (pkgName) {
- let url = `${baseUrlSrv.getRestApiBase()}/helium/bundle/load/${pkgName}`
- if (process.env.HELIUM_BUNDLE_DEV) {
- url = url + '?refresh=true'
- }
-
- return $http.get(url)
- .then(function (response, status) {
- const bundle = response.data
- if (bundle.substring(0, 'ERROR:'.length) === 'ERROR:') {
- console.error(`Failed to get bundle: ${pkgName}`, bundle)
- return '' // empty bundle will be filtered later
- }
-
- return bundle
- })
- .catch(function (error) {
- console.error(`Failed to get single bundle: ${pkgName}`, error)
- })
- }
-
- 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, Array<Object>}> }
- */
- 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<Array<Object>> }
- */
- this.getSinglePackageConfigs = function (pkg) {
- const pkgName = pkg.name
- // in case of local package, it will include `/`
- const pkgArtifact = encodeURIComponent(pkg.artifact)
-
- if (!pkgName || !pkgArtifact) {
- console.error('Failed to fetch config for\n', pkg)
- return Promise.resolve([])
- }
-
- const confUrl = `${baseUrlSrv.getRestApiBase()}/helium/config/${pkgName}/${pkgArtifact}`
- const promisedConf = $http.get(confUrl)
- .then(function (response, status) {
- return response.data.body
- })
-
- return promisedConf.then(({confSpec, confPersisted}) => {
- const merged = mergePersistedConfWithSpec(confPersisted, confSpec)
- return merged
- })
- }
-
- this.getSinglePackageConfigUsingMagic = function (magic) {
- const pkgName = pkgNamePerMagic[magic]
-
- const confUrl = `${baseUrlSrv.getRestApiBase()}/helium/spell/config/${pkgName}`
- const promisedConf = $http.get(confUrl)
- .then(function (response, status) {
- return response.data.body
- })
-
- return promisedConf.then(({confSpec, confPersisted}) => {
- const merged = mergePersistedConfWithSpec(confPersisted, confSpec)
- return merged
- })
- }
-
- const p = this.getAllEnabledPackages()
- .then(enabledPackageSearchResults => {
- const promises = enabledPackageSearchResults.map(packageSearchResult => {
- const pkgName = packageSearchResult.pkg.name
- return this.getSingleBundle(pkgName)
- })
-
- return Promise.all(promises)
- })
- .then(bundles => {
- return bundles.reduce((acc, b) => {
- // filter out empty bundle
- if (b === '') { return acc }
- acc.push(b)
- return acc
- }, [])
- })
-
- // load should be promise
- this.load = p.then(availableBundles => {
- // evaluate bundles
- availableBundles.map(b => {
- // eslint-disable-next-line no-eval
- eval(b)
- })
-
- // extract bundles by type
- heliumBundles.map(b => {
- if (b.type === HeliumType.SPELL) {
- const spell = new b.class() // eslint-disable-line new-cap
- const pkgName = b.id
- spellPerMagic[spell.getMagic()] = spell
- pkgNamePerMagic[spell.getMagic()] = pkgName
- } else if (b.type === HeliumType.VISUALIZATION) {
- visualizationBundles.push(b)
- }
- })
- })
-
- this.init = function() {
- this.getVisualizationPackageOrder()
- }
-
- // init
- this.init()
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/interpreter/interpreter.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/interpreter/interpreter.directive.js b/zeppelin-web/src/components/interpreter/interpreter.directive.js
deleted file mode 100644
index 7080760..0000000
--- a/zeppelin-web/src/components/interpreter/interpreter.directive.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').directive('interpreterDirective', interpreterDirective)
-
-function interpreterDirective ($timeout) {
- 'ngInject'
-
- return {
- restrict: 'A',
- link: function (scope, element, attr) {
- if (scope.$last === true) {
- $timeout(function () {
- let id = 'ngRenderFinished'
- scope.$emit(id)
- })
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/interpreter/widget/widget.number.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/interpreter/widget/widget.number.directive.js b/zeppelin-web/src/components/interpreter/widget/widget.number.directive.js
deleted file mode 100644
index 5d66cd1..0000000
--- a/zeppelin-web/src/components/interpreter/widget/widget.number.directive.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').directive('widgetNumber', numericOnly)
-
-function numericOnly() {
- return {
- require: 'ngModel',
- link: function (scope, element, attrs, modelCtrl) {
- modelCtrl.$parsers.push(function (inputValue) {
- let transformedInput = inputValue ? inputValue.replace(/[^\d.-]/g, '') : null
- if (transformedInput !== inputValue) {
- modelCtrl.$setViewValue(transformedInput)
- modelCtrl.$render()
- }
- return transformedInput
- })
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/login/login.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/login/login.html b/zeppelin-web/src/components/login/login.html
index cd3b604..d4a94a6 100644
--- a/zeppelin-web/src/components/login/login.html
+++ b/zeppelin-web/src/components/login/login.html
@@ -17,7 +17,7 @@ limitations under the License.
<div class="modal-dialog">
<!-- Modal content-->
- <div class="modal-content" id="NoteImportCtrl" ng-init="NoteImportInit">
+ <div id="loginModalContent" class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Login</h4>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/modal-shortcut/modal-shortcut.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/modal-shortcut/modal-shortcut.html b/zeppelin-web/src/components/modal-shortcut/modal-shortcut.html
deleted file mode 100644
index 775da4f..0000000
--- a/zeppelin-web/src/components/modal-shortcut/modal-shortcut.html
+++ /dev/null
@@ -1,312 +0,0 @@
-<!--
-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.
--->
-
-<div class="modal fade" id="shortcutModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
- <div class="modal-dialog">
- <div class="modal-content">
- <div class="shortcut-modal-header">
- <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
- <h4 class="shortcut-modal-title" id="myModalLabel">Keyboard shortcuts</h4>
- </div>
- <div class="table-scroll">
- <table class="table table-shortcut">
- <tr>
- <th style="width:70%">Note Keyboard Shortcuts</th>
- <th></th>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Run paragraph</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Shift</kbd> + <kbd class="kbd-default">Enter</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Cancel</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">C</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Move cursor Up</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">P</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Move cursor Down</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">N</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Remove paragraph</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">D</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Insert new paragraph above</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">A</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Insert new paragraph below</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">B</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Insert copy of paragraph below</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">Shift</kbd> + <kbd class="kbd-default">C</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Move paragraph Up</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">K</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Move paragraph Down</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">J</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Enable/Disable run paragraph</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt' }}</kbd> + <kbd class="kbd-default">R</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Toggle output</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">O</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Toggle editor</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">E</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Toggle line number</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">M</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Toggle title</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">T</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Clear output</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">L</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Link this paragraph</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">W</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Reduce paragraph width</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">Shift</kbd> + <kbd class="kbd-default">-</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Increase paragraph width</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">Shift</kbd> + <kbd class="kbd-default">+</kbd>
- </div>
- </td>
- </tr>
-
- <tr class="sub-title">
- <th style="width:70%">Editor Keyboard Shortcuts</th>
- <th></th>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Auto-completion</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">.</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Cut the line</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">K</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Paste the line</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">Y</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Search inside the code</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">S</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Move cursor to the beginning</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">A</kbd>
- </div>
- </td>
- </tr>
-
- <tr>
- <td>
- <div class="col-md-8">Move cursor at the end</div>
- </td>
- <td>
- <div class="keys">
- <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">E</kbd>
- </div>
- </td>
- </tr>
- </table>
- </div>
- </div>
- </div>
-</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.css
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.css b/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.css
new file mode 100644
index 0000000..b1a60d8
--- /dev/null
+++ b/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.css
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+ .expandable {
+ display: none;
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.directive.js b/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.directive.js
new file mode 100644
index 0000000..95e0681
--- /dev/null
+++ b/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.directive.js
@@ -0,0 +1,48 @@
+/*
+ * 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 './expand-collapse.css'
+
+angular.module('zeppelinWebApp').directive('expandCollapse', expandCollapseDirective)
+
+function expandCollapseDirective() {
+ return {
+ restrict: 'EA',
+ link: function (scope, element, attrs) {
+ angular.element(element).click(function (event) {
+ if (angular.element(element).find('.expandable:visible').length > 1) {
+ angular.element(element).find('.expandable:visible').slideUp('slow')
+ angular.element(element).find('i.fa-folder-open').toggleClass('fa-folder fa-folder-open')
+ } else {
+ angular.element(element).find('.expandable').first().slideToggle('200', function () {
+ // do not toggle trash folder
+ if (angular.element(element).find('.fa-trash-o').length === 0) {
+ angular.element(element).find('i').first().toggleClass('fa-folder fa-folder-open')
+ }
+ })
+ }
+
+ let target = event.target
+
+ // add note
+ if (target.classList !== undefined && target.classList.contains('fa-plus') &&
+ target.tagName.toLowerCase() === 'i') {
+ return
+ }
+
+ event.stopPropagation()
+ })
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/navbar/navbar-note-list-elem.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/navbar/navbar-note-list-elem.html b/zeppelin-web/src/components/navbar/navbar-note-list-elem.html
new file mode 100644
index 0000000..cb36cfa
--- /dev/null
+++ b/zeppelin-web/src/components/navbar/navbar-note-list-elem.html
@@ -0,0 +1,50 @@
+<!--
+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.
+-->
+
+<a class="notebook-list-item" ng-if="navbar.isFilterNote(node) && !node.children" href="#/notebook/{{node.id}}">
+ <i style="font-size: 10px; margin-right: 5px;" ng-class="query.q && node.isTrash ? 'fa fa-trash-o' : 'icon-doc'" ></i>
+ <span>{{noteName(node)}}</span>
+</a>
+
+<li ng-if="node.children">
+ <expand-collapse>
+ <div ng-mouseenter="showFolderButton=true" ng-mouseleave="showFolderButton=false">
+ <a class="notebook-list-item" href="javascript:void(0)">
+ <div ng-if="node.id !== navbar.TRASH_FOLDER_ID">
+ <i style="font-size: 10px; margin-right: 5px;" class="fa fa-folder"></i>
+ <span>{{noteName(node)}}</span>
+ <i data-toggle="modal" data-target="#noteCreateModal" ng-controller="NoteCreateCtrl as noteCreateCtrl"
+ ng-click="noteCreateCtrl.getInterpreterSettings()" data-path="{{node.id}}"
+ style="font-size: 12px; margin-left: 5px; margin-right: 5px;"
+ ng-show="showFolderButton" class="fa fa-plus"
+ uib-tooltip="Create new note"
+ tooltip-placement="{{calculateTooltipPlacement(node)}}">
+ </i>
+ </div>
+ <div ng-if="node.id === navbar.TRASH_FOLDER_ID">
+ <i style="font-size: 12px; margin-right: 5px;" class="fa fa-trash-o"></i>
+ <span>Trash</span>
+ </div>
+ </a>
+ </div>
+ <div class="expandable" style="color: black;">
+ <ul>
+ <li ng-repeat="node in node.children | orderBy:node:false:navbar.arrayOrderingSrv.noteComparator track by $index"
+ ng-class="{'active' : navbar.isActive(node.id)}"
+ ng-include="'components/navbar/navbar-note-list-elem.html'">
+ </li>
+ </ul>
+ </div>
+ </expand-collapse>
+</li>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/navbar/navbar-noteList-elem.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/navbar/navbar-noteList-elem.html b/zeppelin-web/src/components/navbar/navbar-noteList-elem.html
deleted file mode 100644
index 6cba04a..0000000
--- a/zeppelin-web/src/components/navbar/navbar-noteList-elem.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!--
-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.
--->
-
-<a class="notebook-list-item" ng-if="navbar.isFilterNote(node) && !node.children" href="#/notebook/{{node.id}}">
- <i style="font-size: 10px; margin-right: 5px;" ng-class="query.q && node.isTrash ? 'fa fa-trash-o' : 'icon-doc'" ></i>
- <span>{{noteName(node)}}</span>
-</a>
-
-<li ng-if="node.children">
- <expand-collapse>
- <div ng-mouseenter="showFolderButton=true" ng-mouseleave="showFolderButton=false">
- <a class="notebook-list-item" href="javascript:void(0)">
- <div ng-if="node.id !== navbar.TRASH_FOLDER_ID">
- <i style="font-size: 10px; margin-right: 5px;" class="fa fa-folder"></i>
- <span>{{noteName(node)}}</span>
- <i data-toggle="modal" data-target="#noteNameModal" ng-controller="NotenameCtrl as notenamectrl"
- ng-click="notenamectrl.getInterpreterSettings()" data-path="{{node.id}}"
- style="font-size: 12px; margin-left: 5px; margin-right: 5px;"
- ng-show="showFolderButton" class="fa fa-plus"
- uib-tooltip="Create new note"
- tooltip-placement="{{calculateTooltipPlacement(node)}}">
- </i>
- </div>
- <div ng-if="node.id === navbar.TRASH_FOLDER_ID">
- <i style="font-size: 12px; margin-right: 5px;" class="fa fa-trash-o"></i>
- <span>Trash</span>
- </div>
- </a>
- </div>
- <div class="expandable" style="color: black;">
- <ul>
- <li ng-repeat="node in node.children | orderBy:node:false:navbar.arrayOrderingSrv.noteComparator track by $index"
- ng-class="{'active' : navbar.isActive(node.id)}"
- ng-include="'components/navbar/navbar-noteList-elem.html'">
- </li>
- </ul>
- </div>
- </expand-collapse>
-</li>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/navbar/navbar.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/navbar/navbar.controller.js b/zeppelin-web/src/components/navbar/navbar.controller.js
index 28a900e..0ac2f18 100644
--- a/zeppelin-web/src/components/navbar/navbar.controller.js
+++ b/zeppelin-web/src/components/navbar/navbar.controller.js
@@ -15,7 +15,7 @@
angular.module('zeppelinWebApp').controller('NavCtrl', NavCtrl)
function NavCtrl ($scope, $rootScope, $http, $routeParams, $location,
- noteListDataFactory, baseUrlSrv, websocketMsgSrv,
+ noteListFactory, baseUrlSrv, websocketMsgSrv,
arrayOrderingSrv, searchService, TRASH_FOLDER_ID) {
'ngInject'
@@ -24,7 +24,7 @@ function NavCtrl ($scope, $rootScope, $http, $routeParams, $location,
vm.connected = websocketMsgSrv.isConnected()
vm.isActive = isActive
vm.logout = logout
- vm.notes = noteListDataFactory
+ vm.notes = noteListFactory
vm.search = search
vm.searchForm = searchService
vm.showLoginWindow = showLoginWindow
@@ -123,7 +123,7 @@ function NavCtrl ($scope, $rootScope, $http, $routeParams, $location,
*/
$scope.$on('setNoteMenu', function (event, notes) {
- noteListDataFactory.setNotes(notes)
+ noteListFactory.setNotes(notes)
initNotebookListEventListener()
})
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/navbar/navbar.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/navbar/navbar.html b/zeppelin-web/src/components/navbar/navbar.html
index d5e6668..597ed51 100644
--- a/zeppelin-web/src/components/navbar/navbar.html
+++ b/zeppelin-web/src/components/navbar/navbar.html
@@ -37,23 +37,23 @@ limitations under the License.
<span>Notebook</span>
<span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
- <li ng-controller="NotenameCtrl as notenamectrl">
- <a href="" data-toggle="modal" data-target="#noteNameModal" ng-click="notenamectrl.getInterpreterSettings()">
+ <li ng-controller="NoteCreateCtrl as noteCreateCtrl">
+ <a href="" data-toggle="modal" data-target="#noteCreateModal" ng-click="noteCreateCtrl.getInterpreterSettings()">
<i class="fa fa-plus"></i>
Create new note
</a>
</li>
<li class="divider hidden-xs"></li>
<div id="notebook-list" class="scrollbar-container" ng-if="isDrawNavbarNoteList">
- <li class="filter-names" ng-include="'components/filterNoteNames/filter-note-names.html'"></li>
+ <li class="filter-names" ng-include="'components/note-name-filter/note-name-filter.html'"></li>
<div ng-if="!query.q || query.q === ''">
<li ng-repeat="node in navbar.notes.root.children | orderBy:node:false:navbar.arrayOrderingSrv.noteComparator track by node.id"
- ng-class="{'active' : navbar.isActive(node.id)}" ng-include="'components/navbar/navbar-noteList-elem.html'">
+ ng-class="{'active' : navbar.isActive(node.id)}" ng-include="'components/navbar/navbar-note-list-elem.html'">
</li>
</div>
<div ng-if="query.q">
<li ng-repeat="node in navbar.notes.flatList | filter : query.q | orderBy:navbar.arrayOrderingSrv.noteFlatListOrdering track by node.id"
- ng-class="{'active' : navbar.isActive(node.id)}" ng-include="'components/navbar/navbar-noteList-elem.html'">
+ ng-class="{'active' : navbar.isActive(node.id)}" ng-include="'components/navbar/navbar-note-list-elem.html'">
</li>
</div>
</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/ng-enter/ng-enter.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/ng-enter/ng-enter.directive.js b/zeppelin-web/src/components/ng-enter/ng-enter.directive.js
new file mode 100644
index 0000000..98bc067
--- /dev/null
+++ b/zeppelin-web/src/components/ng-enter/ng-enter.directive.js
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').directive('ngEnter', NgEnterDirective)
+
+function NgEnterDirective() {
+ return function (scope, element, attrs) {
+ element.bind('keydown keypress', function (event) {
+ if (event.which === 13) {
+ if (!event.shiftKey) {
+ scope.$apply(function () {
+ scope.$eval(attrs.ngEnter)
+ })
+ }
+ event.preventDefault()
+ }
+ })
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/ng-enter/ng-enter.directive.test.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/ng-enter/ng-enter.directive.test.js b/zeppelin-web/src/components/ng-enter/ng-enter.directive.test.js
new file mode 100644
index 0000000..49f97cc
--- /dev/null
+++ b/zeppelin-web/src/components/ng-enter/ng-enter.directive.test.js
@@ -0,0 +1,24 @@
+describe('Directive: ngEnter', function () {
+ // load the directive's module
+ beforeEach(angular.mock.module('zeppelinWebApp'))
+
+ let element
+ let scope
+
+ beforeEach(inject(function ($rootScope) {
+ scope = $rootScope.$new()
+ }))
+
+ it('should be define', inject(function ($compile) {
+ element = angular.element('<ng-enter></ng-enter>')
+ element = $compile(element)(scope)
+ expect(element.text()).toBeDefined()
+ }))
+
+ // Test the rest of function in ngEnter
+ /* it('should make hidden element visible', inject(function ($compile) {
+ element = angular.element('<ng-enter></ng-enter>');
+ element = $compile(element)(scope);
+ expect(element.text()).toBe('this is the ngEnter directive');
+ })); */
+})
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/ng-escape/ng-escape.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/ng-escape/ng-escape.directive.js b/zeppelin-web/src/components/ng-escape/ng-escape.directive.js
new file mode 100644
index 0000000..a3d35ea
--- /dev/null
+++ b/zeppelin-web/src/components/ng-escape/ng-escape.directive.js
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').directive('ngEscape', NgEscapeDirective)
+
+function NgEscapeDirective() {
+ return function (scope, element, attrs) {
+ element.bind('keydown keyup', function (event) {
+ if (event.which === 27) {
+ scope.$apply(function () {
+ scope.$eval(attrs.ngEscape)
+ })
+ event.preventDefault()
+ }
+ })
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/ngenter/ngenter.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/ngenter/ngenter.directive.js b/zeppelin-web/src/components/ngenter/ngenter.directive.js
deleted file mode 100644
index 57ec01c..0000000
--- a/zeppelin-web/src/components/ngenter/ngenter.directive.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').directive('ngEnter', ngEnter)
-
-function ngEnter () {
- return function (scope, element, attrs) {
- element.bind('keydown keypress', function (event) {
- if (event.which === 13) {
- if (!event.shiftKey) {
- scope.$apply(function () {
- scope.$eval(attrs.ngEnter)
- })
- }
- event.preventDefault()
- }
- })
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/ngenter/ngenter.directive.test.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/ngenter/ngenter.directive.test.js b/zeppelin-web/src/components/ngenter/ngenter.directive.test.js
deleted file mode 100644
index 49f97cc..0000000
--- a/zeppelin-web/src/components/ngenter/ngenter.directive.test.js
+++ /dev/null
@@ -1,24 +0,0 @@
-describe('Directive: ngEnter', function () {
- // load the directive's module
- beforeEach(angular.mock.module('zeppelinWebApp'))
-
- let element
- let scope
-
- beforeEach(inject(function ($rootScope) {
- scope = $rootScope.$new()
- }))
-
- it('should be define', inject(function ($compile) {
- element = angular.element('<ng-enter></ng-enter>')
- element = $compile(element)(scope)
- expect(element.text()).toBeDefined()
- }))
-
- // Test the rest of function in ngEnter
- /* it('should make hidden element visible', inject(function ($compile) {
- element = angular.element('<ng-enter></ng-enter>');
- element = $compile(element)(scope);
- expect(element.text()).toBe('this is the ngEnter directive');
- })); */
-})
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/ngescape/ngescape.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/ngescape/ngescape.directive.js b/zeppelin-web/src/components/ngescape/ngescape.directive.js
deleted file mode 100644
index b52a7a7..0000000
--- a/zeppelin-web/src/components/ngescape/ngescape.directive.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').directive('ngEscape', ngEscape)
-
-function ngEscape () {
- return function (scope, element, attrs) {
- element.bind('keydown keyup', function (event) {
- if (event.which === 27) {
- scope.$apply(function () {
- scope.$eval(attrs.ngEscape)
- })
- event.preventDefault()
- }
- })
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-action/note-action.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-action/note-action.service.js b/zeppelin-web/src/components/note-action/note-action.service.js
new file mode 100644
index 0000000..8e00c0f
--- /dev/null
+++ b/zeppelin-web/src/components/note-action/note-action.service.js
@@ -0,0 +1,183 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').service('noteActionService', noteActionService)
+
+function noteActionService(websocketMsgSrv, $location, noteRenameService, noteListFactory) {
+ 'ngInject'
+
+ this.moveNoteToTrash = function (noteId, redirectToHome) {
+ BootstrapDialog.confirm({
+ closable: true,
+ title: 'Move this note to trash?',
+ message: 'This note will be moved to <strong>trash</strong>.',
+ callback: function (result) {
+ if (result) {
+ websocketMsgSrv.moveNoteToTrash(noteId)
+ if (redirectToHome) {
+ $location.path('/')
+ }
+ }
+ }
+ })
+ }
+
+ this.moveFolderToTrash = function (folderId) {
+ BootstrapDialog.confirm({
+ closable: true,
+ title: 'Move this folder to trash?',
+ message: 'This folder will be moved to <strong>trash</strong>.',
+ callback: function (result) {
+ if (result) {
+ websocketMsgSrv.moveFolderToTrash(folderId)
+ }
+ }
+ })
+ }
+
+ this.removeNote = function (noteId, redirectToHome) {
+ BootstrapDialog.confirm({
+ type: BootstrapDialog.TYPE_WARNING,
+ closable: true,
+ title: 'WARNING! This note will be removed permanently',
+ message: 'This cannot be undone. Are you sure?',
+ callback: function (result) {
+ if (result) {
+ websocketMsgSrv.deleteNote(noteId)
+ if (redirectToHome) {
+ $location.path('/')
+ }
+ }
+ }
+ })
+ }
+
+ this.removeFolder = function (folderId) {
+ BootstrapDialog.confirm({
+ type: BootstrapDialog.TYPE_WARNING,
+ closable: true,
+ title: 'WARNING! This folder will be removed permanently',
+ message: 'This cannot be undone. Are you sure?',
+ callback: function (result) {
+ if (result) {
+ websocketMsgSrv.removeFolder(folderId)
+ }
+ }
+ })
+ }
+
+ this.restoreAll = function () {
+ BootstrapDialog.confirm({
+ closable: true,
+ title: 'Are you sure want to restore all notes in the trash?',
+ message: 'Folders and notes in the trash will be ' +
+ '<strong>merged</strong> into their original position.',
+ callback: function (result) {
+ if (result) {
+ websocketMsgSrv.restoreAll()
+ }
+ }
+ })
+ }
+
+ this.emptyTrash = function () {
+ BootstrapDialog.confirm({
+ type: BootstrapDialog.TYPE_WARNING,
+ closable: true,
+ title: 'WARNING! Notes under trash will be removed permanently',
+ message: 'This cannot be undone. Are you sure?',
+ callback: function (result) {
+ if (result) {
+ websocketMsgSrv.emptyTrash()
+ }
+ }
+ })
+ }
+
+ this.clearAllParagraphOutput = function (noteId) {
+ BootstrapDialog.confirm({
+ closable: true,
+ title: '',
+ message: 'Do you want to clear all output?',
+ callback: function (result) {
+ if (result) {
+ websocketMsgSrv.clearAllParagraphOutput(noteId)
+ }
+ }
+ })
+ }
+
+ this.renameNote = function (noteId, notePath) {
+ noteRenameService.openRenameModal({
+ title: 'Rename note',
+ oldName: notePath,
+ callback: function (newName) {
+ websocketMsgSrv.renameNote(noteId, newName)
+ }
+ })
+ }
+
+ this.renameFolder = function (folderId) {
+ noteRenameService.openRenameModal({
+ title: 'Rename folder',
+ oldName: folderId,
+ callback: function (newName) {
+ let newFolderId = normalizeFolderId(newName)
+ if (_.has(noteListFactory.flatFolderMap, newFolderId)) {
+ BootstrapDialog.confirm({
+ type: BootstrapDialog.TYPE_WARNING,
+ closable: true,
+ title: 'WARNING! The folder will be MERGED',
+ message: 'The folder will be merged into <strong>' + newFolderId + '</strong>. Are you sure?',
+ callback: function (result) {
+ if (result) {
+ websocketMsgSrv.renameFolder(folderId, newFolderId)
+ }
+ }
+ })
+ } else {
+ websocketMsgSrv.renameFolder(folderId, newFolderId)
+ }
+ }
+ })
+ }
+
+ function normalizeFolderId (folderId) {
+ folderId = folderId.trim()
+
+ while (folderId.indexOf('\\') > -1) {
+ folderId = folderId.replace('\\', '/')
+ }
+
+ while (folderId.indexOf('///') > -1) {
+ folderId = folderId.replace('///', '/')
+ }
+
+ folderId = folderId.replace('//', '/')
+
+ if (folderId === '/') {
+ return '/'
+ }
+
+ if (folderId[0] === '/') {
+ folderId = folderId.substring(1)
+ }
+
+ if (folderId.slice(-1) === '/') {
+ folderId = folderId.slice(0, -1)
+ }
+
+ return folderId
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-create/note-create.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-create/note-create.controller.js b/zeppelin-web/src/components/note-create/note-create.controller.js
new file mode 100644
index 0000000..c999c20
--- /dev/null
+++ b/zeppelin-web/src/components/note-create/note-create.controller.js
@@ -0,0 +1,106 @@
+/*
+ * 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 './note-create.css'
+
+angular.module('zeppelinWebApp').controller('NoteCreateCtrl', NoteCreateCtrl)
+
+function NoteCreateCtrl ($scope, noteListFactory, $routeParams, websocketMsgSrv) {
+ 'ngInject'
+
+ let vm = this
+ vm.clone = false
+ vm.notes = noteListFactory
+ vm.websocketMsgSrv = websocketMsgSrv
+ $scope.note = {}
+ $scope.interpreterSettings = {}
+ $scope.note.defaultInterpreter = null
+
+ vm.createNote = function () {
+ if (!vm.clone) {
+ let defaultInterpreterId = ''
+ if ($scope.note.defaultInterpreter !== null) {
+ defaultInterpreterId = $scope.note.defaultInterpreter.id
+ }
+ vm.websocketMsgSrv.createNotebook($scope.note.notename, defaultInterpreterId)
+ $scope.note.defaultInterpreter = $scope.interpreterSettings[0]
+ } else {
+ let noteId = $routeParams.noteId
+ vm.websocketMsgSrv.cloneNote(noteId, $scope.note.notename)
+ }
+ }
+
+ vm.handleNameEnter = function () {
+ angular.element('#noteCreateModal').modal('toggle')
+ vm.createNote()
+ }
+
+ vm.preVisible = function(clone, sourceNoteName, path) {
+ vm.clone = clone
+ vm.sourceNoteName = sourceNoteName
+ $scope.note.notename = vm.clone ? vm.cloneNoteName() : vm.newNoteName(path)
+ $scope.$apply()
+ }
+
+ vm.newNoteName = function(path) {
+ let newCount = 1
+ angular.forEach(vm.notes.flatList, function (noteName) {
+ noteName = noteName.name
+ if (noteName.match(/^Untitled Note [0-9]*$/)) {
+ let lastCount = noteName.substr(14) * 1
+ if (newCount <= lastCount) {
+ newCount = lastCount + 1
+ }
+ }
+ })
+ return (path ? path + '/' : '') + 'Untitled Note ' + newCount
+ }
+
+ vm.cloneNoteName = function () {
+ let copyCount = 1
+ let newCloneName = ''
+ let lastIndex = vm.sourceNoteName.lastIndexOf(' ')
+ let endsWithNumber = !!vm.sourceNoteName.match('^.+?\\s\\d$')
+ let noteNamePrefix = endsWithNumber ? vm.sourceNoteName.substr(0, lastIndex) : vm.sourceNoteName
+ let regexp = new RegExp('^' + noteNamePrefix + ' .+')
+
+ angular.forEach(vm.notes.flatList, function (noteName) {
+ noteName = noteName.name
+ if (noteName.match(regexp)) {
+ let lastCopyCount = noteName.substr(lastIndex).trim()
+ newCloneName = noteNamePrefix
+ lastCopyCount = parseInt(lastCopyCount)
+ if (copyCount <= lastCopyCount) {
+ copyCount = lastCopyCount + 1
+ }
+ }
+ })
+
+ if (!newCloneName) {
+ newCloneName = vm.sourceNoteName
+ }
+ return newCloneName + ' ' + copyCount
+ }
+
+ vm.getInterpreterSettings = function () {
+ vm.websocketMsgSrv.getInterpreterSettings()
+ }
+
+ $scope.$on('interpreterSettings', function (event, data) {
+ $scope.interpreterSettings = data.interpreterSettings
+
+ // initialize default interpreter with Spark interpreter
+ $scope.note.defaultInterpreter = data.interpreterSettings[0]
+ })
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-create/note-create.controller.test.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-create/note-create.controller.test.js b/zeppelin-web/src/components/note-create/note-create.controller.test.js
new file mode 100644
index 0000000..d409a14
--- /dev/null
+++ b/zeppelin-web/src/components/note-create/note-create.controller.test.js
@@ -0,0 +1,39 @@
+describe('Controller: NoteCreateCtrl', function () {
+ beforeEach(angular.mock.module('zeppelinWebApp'))
+
+ let scope
+ let ctrl
+ let noteList
+
+ beforeEach(inject(function ($injector, $rootScope, $controller) {
+ noteList = $injector.get('noteListFactory')
+ scope = $rootScope.$new()
+ ctrl = $controller('NoteCreateCtrl', {
+ $scope: scope,
+ noteListFactory: noteList
+ })
+ }))
+
+ it('should create a new name from current name when cloneNoteName is called', function () {
+ let notesList = [
+ {name: 'dsds 1', id: '1'},
+ {name: 'dsds 2', id: '2'},
+ {name: 'test name', id: '3'},
+ {name: 'aa bb cc', id: '4'},
+ {name: 'Untitled Note 6', id: '4'}
+ ]
+
+ noteList.setNotes(notesList)
+
+ ctrl.sourceNoteName = 'test name'
+ expect(ctrl.cloneNoteName()).toEqual('test name 1')
+ ctrl.sourceNoteName = 'aa bb cc'
+ expect(ctrl.cloneNoteName()).toEqual('aa bb cc 1')
+ ctrl.sourceNoteName = 'Untitled Note 6'
+ expect(ctrl.cloneNoteName()).toEqual('Untitled Note 7')
+ ctrl.sourceNoteName = 'My_note'
+ expect(ctrl.cloneNoteName()).toEqual('My_note 1')
+ ctrl.sourceNoteName = 'dsds 2'
+ expect(ctrl.cloneNoteName()).toEqual('dsds 3')
+ })
+})
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-create/note-create.css
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-create/note-create.css b/zeppelin-web/src/components/note-create/note-create.css
new file mode 100644
index 0000000..22249ad
--- /dev/null
+++ b/zeppelin-web/src/components/note-create/note-create.css
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+.modal-header-note-name {
+ background-color: #3071a9;
+ border: 2px solid #3071a9;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+
+.modal-header-note-name > .modal-title {
+ font-weight: 300;
+ font-size: 20px;
+ color: white;
+}
+
+.modal-header-note-name > .close {
+ color: #cfcfcf;
+ opacity: 1;
+}
+
+.modal-body-note-name label {
+ font-size: 17px;
+ font-weight: 400;
+}
+
+.note-name-create-input {
+ margin-top: 5px;
+}
+
+.note-name-desc-panel {
+ margin-top: 20px;
+ margin-bottom: 4px;
+}
+
+.default-interpreter-select {
+ margin-top: 12px;
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-create/note-create.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-create/note-create.html b/zeppelin-web/src/components/note-create/note-create.html
new file mode 100644
index 0000000..dbfb9e2
--- /dev/null
+++ b/zeppelin-web/src/components/note-create/note-create.html
@@ -0,0 +1,66 @@
+<!--
+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.
+-->
+<div id="noteCreateModal" class="modal fade" role="dialog"
+ modalvisible previsiblecallback="noteCreateCtrl.preVisible"
+ targetinput="noteName" tabindex="-1">
+ <div class="modal-dialog">
+
+ <!-- modal content-->
+ <div class="modal-content" id="NoteCreateCtrl">
+ <!-- modal header -->
+ <div class="modal-header modal-header-note-name">
+ <button type="button" class="close" data-dismiss="modal">×</button>
+ <h4 class="modal-title" ng-show="!noteCreateCtrl.clone">Create New Note</h4>
+ <h4 class="modal-title" ng-show="noteCreateCtrl.clone">Clone Note</h4>
+ </div>
+
+ <!-- modal body-->
+ <div class="modal-body modal-body-note-name">
+ <div class="form-group">
+ <!-- note name -->
+ <div>
+ <label for="noteName">Note Name</label>
+ <input placeholder="Insert Note Name" type="text"
+ class="form-control note-name-create-input"
+ id="noteName" ng-model="note.notename"
+ ng-enter="noteCreateCtrl.handleNameEnter()" />
+ </div>
+ <!-- default interpreter -->
+ <div class="btn-group default-interpreter-select" ng-show="!noteCreateCtrl.clone">
+ <label for="defaultInterpreter">Default Interpreter</label>
+ <select id="defaultInterpreter"
+ name="defaultInterpreter"
+ class="form-control"
+ ng-model="note.defaultInterpreter"
+ ng-options="option.name for option in interpreterSettings">
+ </select>
+ </div>
+ </div> <!-- end: form-group -->
+ <div class="panel panel-default note-name-desc-panel">
+ <div class="panel-heading">
+ Use '/' to create folders. Example: /NoteDirA/Note1
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button type="button" id="createNoteButton"
+ class="btn btn-primary"
+ data-dismiss="modal" ng-click="noteCreateCtrl.createNote()">
+ <span ng-show="!noteCreateCtrl.clone">Create</span>
+ <span ng-show="noteCreateCtrl.clone">Clone</span>
+ </button>
+ </div>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-create/visible.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-create/visible.directive.js b/zeppelin-web/src/components/note-create/visible.directive.js
new file mode 100644
index 0000000..48c170f
--- /dev/null
+++ b/zeppelin-web/src/components/note-create/visible.directive.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').directive('modalvisible', modalvisible)
+
+function modalvisible () {
+ return {
+ restrict: 'A',
+ scope: {
+ preVisibleCallback: '&previsiblecallback',
+ postVisibleCallback: '&postvisiblecallback',
+ targetinput: '@targetinput'
+ },
+ link: function (scope, element, attrs) {
+ // Add some listeners
+ let previsibleMethod = scope.preVisibleCallback
+ let postVisibleMethod = scope.postVisibleCallback
+ element.on('show.bs.modal', function (e) {
+ let relatedTarget = angular.element(e.relatedTarget)
+ let clone = relatedTarget.data('clone')
+ let sourceNoteName = relatedTarget.data('source-note-name')
+ let path = relatedTarget.data('path')
+ let cloneNote = clone ? true : false
+ previsibleMethod()(cloneNote, sourceNoteName, path)
+ })
+ element.on('shown.bs.modal', function (e) {
+ if (scope.targetinput) {
+ angular.element(e.target).find('input#' + scope.targetinput).select()
+ }
+ postVisibleMethod()
+ })
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-import/note-import.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-import/note-import.controller.js b/zeppelin-web/src/components/note-import/note-import.controller.js
new file mode 100644
index 0000000..8cec890
--- /dev/null
+++ b/zeppelin-web/src/components/note-import/note-import.controller.js
@@ -0,0 +1,138 @@
+/*
+ * 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 './note-import.css'
+
+angular.module('zeppelinWebApp').controller('NoteImportCtrl', NoteImportCtrl)
+
+function NoteImportCtrl ($scope, $timeout, websocketMsgSrv) {
+ 'ngInject'
+
+ let vm = this
+ $scope.note = {}
+ $scope.note.step1 = true
+ $scope.note.step2 = false
+ $scope.maxLimit = ''
+ let limit = 0
+
+ websocketMsgSrv.listConfigurations()
+ $scope.$on('configurationsInfo', function (scope, event) {
+ limit = event.configurations['zeppelin.websocket.max.text.message.size']
+ $scope.maxLimit = Math.round(limit / 1048576)
+ })
+
+ vm.resetFlags = function () {
+ $scope.note = {}
+ $scope.note.step1 = true
+ $scope.note.step2 = false
+ angular.element('#noteImportFile').val('')
+ }
+
+ $scope.uploadFile = function () {
+ angular.element('#noteImportFile').click()
+ }
+
+ $scope.importFile = function (element) {
+ $scope.note.errorText = ''
+ $scope.note.importFile = element.files[0]
+ let file = $scope.note.importFile
+ let reader = new FileReader()
+
+ if (file.size > limit) {
+ $scope.note.errorText = 'File size limit Exceeded!'
+ $scope.$apply()
+ return
+ }
+
+ reader.onloadend = function () {
+ vm.processImportJson(reader.result)
+ }
+
+ if (file) {
+ reader.readAsText(file)
+ }
+ }
+
+ $scope.uploadURL = function () {
+ $scope.note.errorText = ''
+ $scope.note.step1 = false
+ $timeout(function () {
+ $scope.note.step2 = true
+ }, 400)
+ }
+
+ vm.importBack = function () {
+ $scope.note.errorText = ''
+ $timeout(function () {
+ $scope.note.step1 = true
+ }, 400)
+ $scope.note.step2 = false
+ }
+
+ vm.importNote = function () {
+ $scope.note.errorText = ''
+ if ($scope.note.importUrl) {
+ jQuery.ajax({
+ url: $scope.note.importUrl,
+ type: 'GET',
+ dataType: 'json',
+ jsonp: false,
+ xhrFields: {
+ withCredentials: false
+ },
+ error: function (xhr, ajaxOptions, thrownError) {
+ $scope.note.errorText = 'Unable to Fetch URL'
+ $scope.$apply()
+ }}).done(function (data) {
+ vm.processImportJson(data)
+ })
+ } else {
+ $scope.note.errorText = 'Enter URL'
+ $scope.$apply()
+ }
+ }
+
+ vm.processImportJson = function (result) {
+ if (typeof result !== 'object') {
+ try {
+ result = JSON.parse(result)
+ } catch (e) {
+ $scope.note.errorText = 'JSON parse exception'
+ $scope.$apply()
+ return
+ }
+ }
+ if (result.paragraphs && result.paragraphs.length > 0) {
+ if (!$scope.note.noteImportName) {
+ $scope.note.noteImportName = result.name
+ } else {
+ result.name = $scope.note.noteImportName
+ }
+ websocketMsgSrv.importNote(result)
+ // angular.element('#noteImportModal').modal('hide');
+ } else {
+ $scope.note.errorText = 'Invalid JSON'
+ }
+ $scope.$apply()
+ }
+
+ /*
+ ** $scope.$on functions below
+ */
+
+ $scope.$on('setNoteMenu', function (event, notes) {
+ vm.resetFlags()
+ angular.element('#noteImportModal').modal('hide')
+ })
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-import/note-import.css
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-import/note-import.css b/zeppelin-web/src/components/note-import/note-import.css
new file mode 100644
index 0000000..81e276a
--- /dev/null
+++ b/zeppelin-web/src/components/note-import/note-import.css
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+.modal-header-import {
+ background-color: #3071a9;
+ border: 2px solid #3071a9;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+
+.modal-header-import .close {
+ color: #cfcfcf;
+ opacity: 1;
+}
+
+.modal-header-import .modal-title {
+ color: white;
+ font-size: 20px;
+ font-weight: 300;
+}
+
+.modal-body-import .note-name-input {
+ margin-left: 7px;
+ margin-right: 7px;
+}
+
+.modal-body-import label {
+ font-size: 15px;
+ font-weight: 400;
+ margin-bottom: 10px;
+ margin-top: 15px;
+}
+
+.modal-body-import {
+ min-height: 420px;
+ overflow: hidden;
+}
+
+.modal-body-import .import-btn-image-group {
+ margin-top: 4px;
+}
+
+.modal-body-import .import-btn-image {
+ display: inline-block;
+ margin-left: 8px;
+}
+
+.modal-body-import .import-btn-image a {
+ background: #fff;
+ border: 1px solid #e6e6e6;
+ /*border-radius: 20px;*/
+ border-radius: 20%;
+ color: #7c828e;
+ cursor: pointer;
+ display: block;
+ float: left;
+ font-size: 98px;
+ text-align: center;
+ text-decoration: none;
+ height: 240px;
+ padding-top: 60px;
+ margin: 0 10px 0px 10px;
+ width: 250px;
+}
+
+.modal-body-import .import-btn-image a:hover {
+ background: #eee;
+}
+
+.modal-body-import .modal-body-import-desc {
+ font-size: 15px;
+ font-weight: 400;
+ margin-top: 30px;
+ color: black;
+ font-family: 'Roboto', sans-serif;
+}
+
+.modal-footer-import {
+ min-height: 65px;
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-import/note-import.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-import/note-import.html b/zeppelin-web/src/components/note-import/note-import.html
new file mode 100644
index 0000000..848a93b
--- /dev/null
+++ b/zeppelin-web/src/components/note-import/note-import.html
@@ -0,0 +1,80 @@
+<!--
+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.
+-->
+<div id="noteImportModal" class="modal fade" role="dialog" tabindex="-1"
+ data-backdrop="static" data-keyboard="false">
+
+ <div class="modal-dialog">
+ <div class="modal-content" id="NoteImportCtrl" ng-init="NoteImportInit">
+
+ <!-- modal-header -->
+ <div class="modal-header modal-header-import">
+ <button type="button" class="close" data-dismiss="modal"
+ ng-click="noteImportCtrl.resetFlags()">×</button>
+ <h4 class="modal-title">Import New Note</h4>
+ </div>
+
+ <!-- modal-body -->
+ <div class="modal-body modal-body-import">
+ <div class="form-group">
+ <label for="noteImportName">Import As</label>
+ <input class="form-control note-name-input" id="noteImportName"
+ placeholder="Insert Note Name" type="text"
+ ng-model="note.noteImportName" />
+ </div>
+
+ <div class="form-group" ng-show="note.errorText">
+ <div class="alert alert-danger">{{note.errorText}}</div>
+ </div>
+
+ <label>JSON file size cannot exceed {{maxLimit}} MB</label>
+
+ <div class="form-group slide-left import-btn-image-group" ng-show="note.step1">
+ <div class="import-btn-image">
+ <a class="fa fa-cloud-upload import-file-upload" ng-click="uploadFile()">
+ <p class="modal-body-import-desc">Select JSON File </p>
+ </a>
+ <div style="display: none">
+ <input class="form-control note-name-input" id="noteImportFile"
+ placeholder="Note name" type="file"
+ ng-model="note.importFile" onchange="angular.element(this).scope().importFile(this)" />
+ </div>
+ </div>
+ <div class="import-btn-image">
+ <a href="javascript:void(0);" ng-click="uploadURL()" class="fa fa-link">
+ <p class="modal-body-import-desc">Add from URL</p>
+ </a>
+ </div>
+ </div>
+
+ <div class="form-group slide-right" ng-show="note.step2">
+
+ <label for="noteImportUrl">URL</label>
+ <input placeholder="Note URL" type="text" class="form-control" id="noteImportUrl"
+ ng-model="note.importUrl" />
+ </div>
+
+ </div>
+ <div class="modal-footer modal-footer-import" ng-show="note.step2">
+ <button type="button" id="importBackButton"
+ class="btn btn-default"
+ ng-click="noteImportCtrl.importBack()">Back
+ </button>
+ <button type="button" id="importNoteButton"
+ class="btn btn-default"
+ ng-click="noteImportCtrl.importNote()">Import Note
+ </button>
+ </div>
+ </div>
+ </div>
+</div>
[2/5] zeppelin git commit: [ZEPPELIN-2749] Use scalable file
structure for zeppelin web
Posted by ku...@apache.org.
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-list/note-list.factory.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-list/note-list.factory.js b/zeppelin-web/src/components/note-list/note-list.factory.js
new file mode 100644
index 0000000..21abbc0
--- /dev/null
+++ b/zeppelin-web/src/components/note-list/note-list.factory.js
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').factory('noteListFactory', NoteListFactory)
+
+function NoteListFactory(TRASH_FOLDER_ID) {
+ 'ngInject'
+
+ const notes = {
+ root: {children: []},
+ flatList: [],
+ flatFolderMap: {},
+
+ setNotes: function (notesList) {
+ // a flat list to boost searching
+ notes.flatList = _.map(notesList, (note) => {
+ note.isTrash = note.name
+ ? note.name.split('/')[0] === TRASH_FOLDER_ID : false
+ return note
+ })
+
+ // construct the folder-based tree
+ notes.root = {children: []}
+ notes.flatFolderMap = {}
+ _.reduce(notesList, function (root, note) {
+ let noteName = note.name || note.id
+ let nodes = noteName.match(/([^\/][^\/]*)/g)
+
+ // recursively add nodes
+ addNode(root, nodes, note.id)
+
+ return root
+ }, notes.root)
+ }
+ }
+
+ const addNode = function (curDir, nodes, noteId) {
+ if (nodes.length === 1) { // the leaf
+ curDir.children.push({
+ name: nodes[0],
+ id: noteId,
+ path: curDir.id ? curDir.id + '/' + nodes[0] : nodes[0],
+ isTrash: curDir.id ? curDir.id.split('/')[0] === TRASH_FOLDER_ID : false
+ })
+ } else { // a folder node
+ let node = nodes.shift()
+ let dir = _.find(curDir.children,
+ function (c) { return c.name === node && c.children !== undefined })
+ if (dir !== undefined) { // found an existing dir
+ addNode(dir, nodes, noteId)
+ } else {
+ let newDir = {
+ id: curDir.id ? curDir.id + '/' + node : node,
+ name: node,
+ hidden: true,
+ children: [],
+ isTrash: curDir.id ? curDir.id.split('/')[0] === TRASH_FOLDER_ID : false
+ }
+
+ // add the folder to flat folder map
+ notes.flatFolderMap[newDir.id] = newDir
+
+ curDir.children.push(newDir)
+ addNode(newDir, nodes, noteId)
+ }
+ }
+ }
+
+ return notes
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-list/note-list.factory.test.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-list/note-list.factory.test.js b/zeppelin-web/src/components/note-list/note-list.factory.test.js
new file mode 100644
index 0000000..58d5d42
--- /dev/null
+++ b/zeppelin-web/src/components/note-list/note-list.factory.test.js
@@ -0,0 +1,75 @@
+describe('Factory: NoteList', function () {
+ let noteList
+
+ beforeEach(function () {
+ angular.mock.module('zeppelinWebApp')
+
+ inject(function ($injector) {
+ noteList = $injector.get('noteListFactory')
+ })
+ })
+
+ it('should generate both flat list and folder-based list properly', function () {
+ let notesList = [
+ {name: 'A', id: '000001'},
+ {name: 'B', id: '000002'},
+ {id: '000003'}, // note without name
+ {name: '/C/CA', id: '000004'},
+ {name: '/C/CB', id: '000005'},
+ {name: '/C/CB/CBA', id: '000006'}, // same name with a dir
+ {name: '/C/CB/CBA', id: '000007'}, // same name with another note
+ {name: 'C///CB//CBB', id: '000008'},
+ {name: 'D/D[A/DA]B', id: '000009'} // check if '[' and ']' considered as folder seperator
+ ]
+ noteList.setNotes(notesList)
+
+ let flatList = noteList.flatList
+ expect(flatList.length).toBe(9)
+ expect(flatList[0].name).toBe('A')
+ expect(flatList[0].id).toBe('000001')
+ expect(flatList[1].name).toBe('B')
+ expect(flatList[2].name).toBeUndefined()
+ expect(flatList[3].name).toBe('/C/CA')
+ expect(flatList[4].name).toBe('/C/CB')
+ expect(flatList[5].name).toBe('/C/CB/CBA')
+ expect(flatList[6].name).toBe('/C/CB/CBA')
+ expect(flatList[7].name).toBe('C///CB//CBB')
+ expect(flatList[8].name).toBe('D/D[A/DA]B')
+
+ let folderList = noteList.root.children
+ expect(folderList.length).toBe(5)
+ expect(folderList[0].name).toBe('A')
+ expect(folderList[0].id).toBe('000001')
+ expect(folderList[1].name).toBe('B')
+ expect(folderList[2].name).toBe('000003')
+ expect(folderList[3].name).toBe('C')
+ expect(folderList[3].id).toBe('C')
+ expect(folderList[3].children.length).toBe(3)
+ expect(folderList[3].children[0].name).toBe('CA')
+ expect(folderList[3].children[0].id).toBe('000004')
+ expect(folderList[3].children[0].children).toBeUndefined()
+ expect(folderList[3].children[1].name).toBe('CB')
+ expect(folderList[3].children[1].id).toBe('000005')
+ expect(folderList[3].children[1].children).toBeUndefined()
+ expect(folderList[3].children[2].name).toBe('CB')
+ expect(folderList[3].children[2].id).toBe('C/CB')
+ expect(folderList[3].children[2].children.length).toBe(3)
+ expect(folderList[3].children[2].children[0].name).toBe('CBA')
+ expect(folderList[3].children[2].children[0].id).toBe('000006')
+ expect(folderList[3].children[2].children[0].children).toBeUndefined()
+ expect(folderList[3].children[2].children[1].name).toBe('CBA')
+ expect(folderList[3].children[2].children[1].id).toBe('000007')
+ expect(folderList[3].children[2].children[1].children).toBeUndefined()
+ expect(folderList[3].children[2].children[2].name).toBe('CBB')
+ expect(folderList[3].children[2].children[2].id).toBe('000008')
+ expect(folderList[3].children[2].children[2].children).toBeUndefined()
+ expect(folderList[4].name).toBe('D')
+ expect(folderList[4].id).toBe('D')
+ expect(folderList[4].children.length).toBe(1)
+ expect(folderList[4].children[0].name).toBe('D[A')
+ expect(folderList[4].children[0].id).toBe('D/D[A')
+ expect(folderList[4].children[0].children[0].name).toBe('DA]B')
+ expect(folderList[4].children[0].children[0].id).toBe('000009')
+ expect(folderList[4].children[0].children[0].children).toBeUndefined()
+ })
+})
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-name-filter/note-name-filter.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-name-filter/note-name-filter.html b/zeppelin-web/src/components/note-name-filter/note-name-filter.html
new file mode 100644
index 0000000..071cba4
--- /dev/null
+++ b/zeppelin-web/src/components/note-name-filter/note-name-filter.html
@@ -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.
+-->
+<input type="text"
+ class="note-name-query form-control"
+ ng-click="$event.stopPropagation()"
+ placeholder=" Filter"
+ ng-model="$parent.query.q"
+ ng-model-options="{ updateOn: 'default blur', debounce: { 'default': 300, 'blur': 0 } }" />
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-rename/note-rename.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-rename/note-rename.controller.js b/zeppelin-web/src/components/note-rename/note-rename.controller.js
new file mode 100644
index 0000000..b950d2b
--- /dev/null
+++ b/zeppelin-web/src/components/note-rename/note-rename.controller.js
@@ -0,0 +1,48 @@
+/*
+ * 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 './note-rename.css'
+
+angular.module('zeppelinWebApp').controller('NoteRenameCtrl', NoteRenameController)
+
+function NoteRenameController($scope) {
+ 'ngInject'
+
+ let self = this
+
+ $scope.params = {newName: ''}
+ $scope.isValid = true
+
+ $scope.rename = function () {
+ angular.element('#noteRenameModal').modal('hide')
+ self.callback($scope.params.newName)
+ }
+
+ $scope.$on('openRenameModal', function (event, options) {
+ self.validator = options.validator || defaultValidator
+ self.callback = options.callback || function () {}
+
+ $scope.title = options.title || 'Rename'
+ $scope.params.newName = options.oldName || ''
+ $scope.validate = function () {
+ $scope.isValid = self.validator($scope.params.newName)
+ }
+
+ angular.element('#noteRenameModal').modal('show')
+ })
+
+ function defaultValidator (str) {
+ return !!str.trim()
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-rename/note-rename.css
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-rename/note-rename.css b/zeppelin-web/src/components/note-rename/note-rename.css
new file mode 100644
index 0000000..45d4710
--- /dev/null
+++ b/zeppelin-web/src/components/note-rename/note-rename.css
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+.modal-header-rename {
+ background-color: #3071a9;
+ border: 2px solid #3071a9;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+
+.modal-header-rename .close {
+ color: #cfcfcf;
+ opacity: 1;
+}
+
+.modal-header-rename .modal-title {
+ color: white;
+ font-size: 20px;
+ font-weight: 300;
+}
+
+.modal-body-rename label {
+ font-size: 17px;
+ font-weight: 400;
+ margin-top: 5px;
+ margin-bottom: 15px;
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-rename/note-rename.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-rename/note-rename.html b/zeppelin-web/src/components/note-rename/note-rename.html
new file mode 100644
index 0000000..2f3a8c1
--- /dev/null
+++ b/zeppelin-web/src/components/note-rename/note-rename.html
@@ -0,0 +1,43 @@
+<!--
+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.
+-->
+<div id="noteRenameModal" class="modal fade" role="dialog" tabindex="-1">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <!-- modal-header -->
+ <div class="modal-header modal-header-rename">
+ <button type="button" class="close" data-dismiss="modal">×</button>
+ <h4 class="modal-title">{{title}}</h4>
+ </div>
+
+ <!-- modal-body -->
+ <div class="modal-body modal-body-rename">
+ <label ng-if="isValid">Please enter a new name</label>
+ <label ng-if="!isValid" class="text-danger">Please enter a valid name</label>
+ <div class="form-group" ng-class="{'has-error': !isValid}">
+ <input type="text" class="form-control"
+ ng-model="params.newName" ng-change="validate()"
+ ng-enter="isValid && rename()" />
+ </div>
+ </div>
+ <div class="modal-footer">
+ <div>
+ <button type="button" class="btn btn-default btn-primary"
+ ng-click="rename()" ng-class="{'disabled': !isValid}">
+ Rename
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/note-rename/note-rename.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-rename/note-rename.service.js b/zeppelin-web/src/components/note-rename/note-rename.service.js
new file mode 100644
index 0000000..64df82f
--- /dev/null
+++ b/zeppelin-web/src/components/note-rename/note-rename.service.js
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').service('noteRenameService', NoteRenameService)
+
+function NoteRenameService($rootScope) {
+ 'ngInject'
+
+ let self = this
+
+ /**
+ * <options schema>
+ * title: string - Modal title
+ * oldName: string - name to initialize input
+ * callback: (newName: string)=>void - callback onButtonClick
+ * validator: (str: string)=>boolean - input validator
+ */
+ self.openRenameModal = function (options) {
+ $rootScope.$broadcast('openRenameModal', options)
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/noteAction/noteAction.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/noteAction/noteAction.service.js b/zeppelin-web/src/components/noteAction/noteAction.service.js
deleted file mode 100644
index f925975..0000000
--- a/zeppelin-web/src/components/noteAction/noteAction.service.js
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').service('noteActionSrv', noteActionSrv)
-
-function noteActionSrv (websocketMsgSrv, $location, renameSrv, noteListDataFactory) {
- 'ngInject'
-
- this.moveNoteToTrash = function (noteId, redirectToHome) {
- BootstrapDialog.confirm({
- closable: true,
- title: 'Move this note to trash?',
- message: 'This note will be moved to <strong>trash</strong>.',
- callback: function (result) {
- if (result) {
- websocketMsgSrv.moveNoteToTrash(noteId)
- if (redirectToHome) {
- $location.path('/')
- }
- }
- }
- })
- }
-
- this.moveFolderToTrash = function (folderId) {
- BootstrapDialog.confirm({
- closable: true,
- title: 'Move this folder to trash?',
- message: 'This folder will be moved to <strong>trash</strong>.',
- callback: function (result) {
- if (result) {
- websocketMsgSrv.moveFolderToTrash(folderId)
- }
- }
- })
- }
-
- this.removeNote = function (noteId, redirectToHome) {
- BootstrapDialog.confirm({
- type: BootstrapDialog.TYPE_WARNING,
- closable: true,
- title: 'WARNING! This note will be removed permanently',
- message: 'This cannot be undone. Are you sure?',
- callback: function (result) {
- if (result) {
- websocketMsgSrv.deleteNote(noteId)
- if (redirectToHome) {
- $location.path('/')
- }
- }
- }
- })
- }
-
- this.removeFolder = function (folderId) {
- BootstrapDialog.confirm({
- type: BootstrapDialog.TYPE_WARNING,
- closable: true,
- title: 'WARNING! This folder will be removed permanently',
- message: 'This cannot be undone. Are you sure?',
- callback: function (result) {
- if (result) {
- websocketMsgSrv.removeFolder(folderId)
- }
- }
- })
- }
-
- this.restoreAll = function () {
- BootstrapDialog.confirm({
- closable: true,
- title: 'Are you sure want to restore all notes in the trash?',
- message: 'Folders and notes in the trash will be ' +
- '<strong>merged</strong> into their original position.',
- callback: function (result) {
- if (result) {
- websocketMsgSrv.restoreAll()
- }
- }
- })
- }
-
- this.emptyTrash = function () {
- BootstrapDialog.confirm({
- type: BootstrapDialog.TYPE_WARNING,
- closable: true,
- title: 'WARNING! Notes under trash will be removed permanently',
- message: 'This cannot be undone. Are you sure?',
- callback: function (result) {
- if (result) {
- websocketMsgSrv.emptyTrash()
- }
- }
- })
- }
-
- this.clearAllParagraphOutput = function (noteId) {
- BootstrapDialog.confirm({
- closable: true,
- title: '',
- message: 'Do you want to clear all output?',
- callback: function (result) {
- if (result) {
- websocketMsgSrv.clearAllParagraphOutput(noteId)
- }
- }
- })
- }
-
- this.renameNote = function (noteId, notePath) {
- renameSrv.openRenameModal({
- title: 'Rename note',
- oldName: notePath,
- callback: function (newName) {
- websocketMsgSrv.renameNote(noteId, newName)
- }
- })
- }
-
- this.renameFolder = function (folderId) {
- renameSrv.openRenameModal({
- title: 'Rename folder',
- oldName: folderId,
- callback: function (newName) {
- let newFolderId = normalizeFolderId(newName)
- if (_.has(noteListDataFactory.flatFolderMap, newFolderId)) {
- BootstrapDialog.confirm({
- type: BootstrapDialog.TYPE_WARNING,
- closable: true,
- title: 'WARNING! The folder will be MERGED',
- message: 'The folder will be merged into <strong>' + newFolderId + '</strong>. Are you sure?',
- callback: function (result) {
- if (result) {
- websocketMsgSrv.renameFolder(folderId, newFolderId)
- }
- }
- })
- } else {
- websocketMsgSrv.renameFolder(folderId, newFolderId)
- }
- }
- })
- }
-
- function normalizeFolderId (folderId) {
- folderId = folderId.trim()
-
- while (folderId.indexOf('\\') > -1) {
- folderId = folderId.replace('\\', '/')
- }
-
- while (folderId.indexOf('///') > -1) {
- folderId = folderId.replace('///', '/')
- }
-
- folderId = folderId.replace('//', '/')
-
- if (folderId === '/') {
- return '/'
- }
-
- if (folderId[0] === '/') {
- folderId = folderId.substring(1)
- }
-
- if (folderId.slice(-1) === '/') {
- folderId = folderId.slice(0, -1)
- }
-
- return folderId
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/noteListDataFactory/noteList.datafactory.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/noteListDataFactory/noteList.datafactory.js b/zeppelin-web/src/components/noteListDataFactory/noteList.datafactory.js
deleted file mode 100644
index ab6956a..0000000
--- a/zeppelin-web/src/components/noteListDataFactory/noteList.datafactory.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').factory('noteListDataFactory', noteListDataFactory)
-
-function noteListDataFactory (TRASH_FOLDER_ID) {
- 'ngInject'
-
- const notes = {
- root: {children: []},
- flatList: [],
- flatFolderMap: {},
-
- setNotes: function (notesList) {
- // a flat list to boost searching
- notes.flatList = _.map(notesList, (note) => {
- note.isTrash = note.name
- ? note.name.split('/')[0] === TRASH_FOLDER_ID : false
- return note
- })
-
- // construct the folder-based tree
- notes.root = {children: []}
- notes.flatFolderMap = {}
- _.reduce(notesList, function (root, note) {
- let noteName = note.name || note.id
- let nodes = noteName.match(/([^\/][^\/]*)/g)
-
- // recursively add nodes
- addNode(root, nodes, note.id)
-
- return root
- }, notes.root)
- }
- }
-
- const addNode = function (curDir, nodes, noteId) {
- if (nodes.length === 1) { // the leaf
- curDir.children.push({
- name: nodes[0],
- id: noteId,
- path: curDir.id ? curDir.id + '/' + nodes[0] : nodes[0],
- isTrash: curDir.id ? curDir.id.split('/')[0] === TRASH_FOLDER_ID : false
- })
- } else { // a folder node
- let node = nodes.shift()
- let dir = _.find(curDir.children,
- function (c) { return c.name === node && c.children !== undefined })
- if (dir !== undefined) { // found an existing dir
- addNode(dir, nodes, noteId)
- } else {
- let newDir = {
- id: curDir.id ? curDir.id + '/' + node : node,
- name: node,
- hidden: true,
- children: [],
- isTrash: curDir.id ? curDir.id.split('/')[0] === TRASH_FOLDER_ID : false
- }
-
- // add the folder to flat folder map
- notes.flatFolderMap[newDir.id] = newDir
-
- curDir.children.push(newDir)
- addNode(newDir, nodes, noteId)
- }
- }
- }
-
- return notes
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/noteListDataFactory/noteList.datafactory.test.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/noteListDataFactory/noteList.datafactory.test.js b/zeppelin-web/src/components/noteListDataFactory/noteList.datafactory.test.js
deleted file mode 100644
index d1acc5d..0000000
--- a/zeppelin-web/src/components/noteListDataFactory/noteList.datafactory.test.js
+++ /dev/null
@@ -1,75 +0,0 @@
-describe('Factory: NoteList', function () {
- let noteList
-
- beforeEach(function () {
- angular.mock.module('zeppelinWebApp')
-
- inject(function ($injector) {
- noteList = $injector.get('noteListDataFactory')
- })
- })
-
- it('should generate both flat list and folder-based list properly', function () {
- let notesList = [
- {name: 'A', id: '000001'},
- {name: 'B', id: '000002'},
- {id: '000003'}, // note without name
- {name: '/C/CA', id: '000004'},
- {name: '/C/CB', id: '000005'},
- {name: '/C/CB/CBA', id: '000006'}, // same name with a dir
- {name: '/C/CB/CBA', id: '000007'}, // same name with another note
- {name: 'C///CB//CBB', id: '000008'},
- {name: 'D/D[A/DA]B', id: '000009'} // check if '[' and ']' considered as folder seperator
- ]
- noteList.setNotes(notesList)
-
- let flatList = noteList.flatList
- expect(flatList.length).toBe(9)
- expect(flatList[0].name).toBe('A')
- expect(flatList[0].id).toBe('000001')
- expect(flatList[1].name).toBe('B')
- expect(flatList[2].name).toBeUndefined()
- expect(flatList[3].name).toBe('/C/CA')
- expect(flatList[4].name).toBe('/C/CB')
- expect(flatList[5].name).toBe('/C/CB/CBA')
- expect(flatList[6].name).toBe('/C/CB/CBA')
- expect(flatList[7].name).toBe('C///CB//CBB')
- expect(flatList[8].name).toBe('D/D[A/DA]B')
-
- let folderList = noteList.root.children
- expect(folderList.length).toBe(5)
- expect(folderList[0].name).toBe('A')
- expect(folderList[0].id).toBe('000001')
- expect(folderList[1].name).toBe('B')
- expect(folderList[2].name).toBe('000003')
- expect(folderList[3].name).toBe('C')
- expect(folderList[3].id).toBe('C')
- expect(folderList[3].children.length).toBe(3)
- expect(folderList[3].children[0].name).toBe('CA')
- expect(folderList[3].children[0].id).toBe('000004')
- expect(folderList[3].children[0].children).toBeUndefined()
- expect(folderList[3].children[1].name).toBe('CB')
- expect(folderList[3].children[1].id).toBe('000005')
- expect(folderList[3].children[1].children).toBeUndefined()
- expect(folderList[3].children[2].name).toBe('CB')
- expect(folderList[3].children[2].id).toBe('C/CB')
- expect(folderList[3].children[2].children.length).toBe(3)
- expect(folderList[3].children[2].children[0].name).toBe('CBA')
- expect(folderList[3].children[2].children[0].id).toBe('000006')
- expect(folderList[3].children[2].children[0].children).toBeUndefined()
- expect(folderList[3].children[2].children[1].name).toBe('CBA')
- expect(folderList[3].children[2].children[1].id).toBe('000007')
- expect(folderList[3].children[2].children[1].children).toBeUndefined()
- expect(folderList[3].children[2].children[2].name).toBe('CBB')
- expect(folderList[3].children[2].children[2].id).toBe('000008')
- expect(folderList[3].children[2].children[2].children).toBeUndefined()
- expect(folderList[4].name).toBe('D')
- expect(folderList[4].id).toBe('D')
- expect(folderList[4].children.length).toBe(1)
- expect(folderList[4].children[0].name).toBe('D[A')
- expect(folderList[4].children[0].id).toBe('D/D[A')
- expect(folderList[4].children[0].children[0].name).toBe('DA]B')
- expect(folderList[4].children[0].children[0].id).toBe('000009')
- expect(folderList[4].children[0].children[0].children).toBeUndefined()
- })
-})
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/noteName-create/note-name-dialog.css
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/noteName-create/note-name-dialog.css b/zeppelin-web/src/components/noteName-create/note-name-dialog.css
deleted file mode 100644
index 22249ad..0000000
--- a/zeppelin-web/src/components/noteName-create/note-name-dialog.css
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.
- */
-
-.modal-header-note-name {
- background-color: #3071a9;
- border: 2px solid #3071a9;
- border-top-left-radius: 4px;
- border-top-right-radius: 4px;
-}
-
-.modal-header-note-name > .modal-title {
- font-weight: 300;
- font-size: 20px;
- color: white;
-}
-
-.modal-header-note-name > .close {
- color: #cfcfcf;
- opacity: 1;
-}
-
-.modal-body-note-name label {
- font-size: 17px;
- font-weight: 400;
-}
-
-.note-name-create-input {
- margin-top: 5px;
-}
-
-.note-name-desc-panel {
- margin-top: 20px;
- margin-bottom: 4px;
-}
-
-.default-interpreter-select {
- margin-top: 12px;
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/noteName-create/note-name-dialog.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/noteName-create/note-name-dialog.html b/zeppelin-web/src/components/noteName-create/note-name-dialog.html
deleted file mode 100644
index 6b20d3a..0000000
--- a/zeppelin-web/src/components/noteName-create/note-name-dialog.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!--
-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.
--->
-<div id="noteNameModal" class="modal fade" role="dialog"
- modalvisible previsiblecallback="notenamectrl.preVisible"
- targetinput="noteName" tabindex="-1">
- <div class="modal-dialog">
-
- <!-- modal content-->
- <div class="modal-content" id="NotenameCtrl">
- <!-- modal header -->
- <div class="modal-header modal-header-note-name">
- <button type="button" class="close" data-dismiss="modal">×</button>
- <h4 class="modal-title" ng-show="!notenamectrl.clone">Create New Note</h4>
- <h4 class="modal-title" ng-show="notenamectrl.clone">Clone Note</h4>
- </div>
-
- <!-- modal body-->
- <div class="modal-body modal-body-note-name">
- <div class="form-group">
- <!-- note name -->
- <div>
- <label for="noteName">Note Name</label>
- <input placeholder="Insert Note Name" type="text"
- class="form-control note-name-create-input"
- id="noteName" ng-model="note.notename"
- ng-enter="notenamectrl.handleNameEnter()" />
- </div>
- <!-- default interpreter -->
- <div class="btn-group default-interpreter-select" ng-show="!notenamectrl.clone">
- <label for="defaultInterpreter">Default Interpreter</label>
- <select id="defaultInterpreter"
- name="defaultInterpreter"
- class="form-control"
- ng-model="note.defaultInterpreter"
- ng-options="option.name for option in interpreterSettings">
- </select>
- </div>
- </div> <!-- end: form-group -->
- <div class="panel panel-default note-name-desc-panel">
- <div class="panel-heading">
- Use '/' to create folders. Example: /NoteDirA/Note1
- </div>
- </div>
- </div>
- <div class="modal-footer">
- <button type="button" id="createNoteButton"
- class="btn btn-primary"
- data-dismiss="modal" ng-click="notenamectrl.createNote()">
- <span ng-show="!notenamectrl.clone">Create</span>
- <span ng-show="notenamectrl.clone">Clone</span>
- </button>
- </div>
- </div>
- </div>
-</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/noteName-create/notename.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/noteName-create/notename.controller.js b/zeppelin-web/src/components/noteName-create/notename.controller.js
deleted file mode 100644
index 80bceb8..0000000
--- a/zeppelin-web/src/components/noteName-create/notename.controller.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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 './note-name-dialog.css'
-
-angular.module('zeppelinWebApp').controller('NotenameCtrl', NotenameCtrl)
-
-function NotenameCtrl ($scope, noteListDataFactory, $routeParams, websocketMsgSrv) {
- 'ngInject'
-
- let vm = this
- vm.clone = false
- vm.notes = noteListDataFactory
- vm.websocketMsgSrv = websocketMsgSrv
- $scope.note = {}
- $scope.interpreterSettings = {}
- $scope.note.defaultInterpreter = null
-
- vm.createNote = function () {
- if (!vm.clone) {
- let defaultInterpreterId = ''
- if ($scope.note.defaultInterpreter !== null) {
- defaultInterpreterId = $scope.note.defaultInterpreter.id
- }
- vm.websocketMsgSrv.createNotebook($scope.note.notename, defaultInterpreterId)
- $scope.note.defaultInterpreter = $scope.interpreterSettings[0]
- } else {
- let noteId = $routeParams.noteId
- vm.websocketMsgSrv.cloneNote(noteId, $scope.note.notename)
- }
- }
-
- vm.handleNameEnter = function () {
- angular.element('#noteNameModal').modal('toggle')
- vm.createNote()
- }
-
- vm.preVisible = function(clone, sourceNoteName, path) {
- vm.clone = clone
- vm.sourceNoteName = sourceNoteName
- $scope.note.notename = vm.clone ? vm.cloneNoteName() : vm.newNoteName(path)
- $scope.$apply()
- }
-
- vm.newNoteName = function(path) {
- let newCount = 1
- angular.forEach(vm.notes.flatList, function (noteName) {
- noteName = noteName.name
- if (noteName.match(/^Untitled Note [0-9]*$/)) {
- let lastCount = noteName.substr(14) * 1
- if (newCount <= lastCount) {
- newCount = lastCount + 1
- }
- }
- })
- return (path ? path + '/' : '') + 'Untitled Note ' + newCount
- }
-
- vm.cloneNoteName = function () {
- let copyCount = 1
- let newCloneName = ''
- let lastIndex = vm.sourceNoteName.lastIndexOf(' ')
- let endsWithNumber = !!vm.sourceNoteName.match('^.+?\\s\\d$')
- let noteNamePrefix = endsWithNumber ? vm.sourceNoteName.substr(0, lastIndex) : vm.sourceNoteName
- let regexp = new RegExp('^' + noteNamePrefix + ' .+')
-
- angular.forEach(vm.notes.flatList, function (noteName) {
- noteName = noteName.name
- if (noteName.match(regexp)) {
- let lastCopyCount = noteName.substr(lastIndex).trim()
- newCloneName = noteNamePrefix
- lastCopyCount = parseInt(lastCopyCount)
- if (copyCount <= lastCopyCount) {
- copyCount = lastCopyCount + 1
- }
- }
- })
-
- if (!newCloneName) {
- newCloneName = vm.sourceNoteName
- }
- return newCloneName + ' ' + copyCount
- }
-
- vm.getInterpreterSettings = function () {
- vm.websocketMsgSrv.getInterpreterSettings()
- }
-
- $scope.$on('interpreterSettings', function (event, data) {
- $scope.interpreterSettings = data.interpreterSettings
-
- // initialize default interpreter with Spark interpreter
- $scope.note.defaultInterpreter = data.interpreterSettings[0]
- })
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/noteName-create/notename.controller.test.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/noteName-create/notename.controller.test.js b/zeppelin-web/src/components/noteName-create/notename.controller.test.js
deleted file mode 100644
index 61bce14..0000000
--- a/zeppelin-web/src/components/noteName-create/notename.controller.test.js
+++ /dev/null
@@ -1,39 +0,0 @@
-describe('Controller: NotenameCtrl', function () {
- beforeEach(angular.mock.module('zeppelinWebApp'))
-
- let scope
- let ctrl
- let noteList
-
- beforeEach(inject(function ($injector, $rootScope, $controller) {
- noteList = $injector.get('noteListDataFactory')
- scope = $rootScope.$new()
- ctrl = $controller('NotenameCtrl', {
- $scope: scope,
- noteListDataFactory: noteList
- })
- }))
-
- it('should create a new name from current name when cloneNoteName is called', function () {
- let notesList = [
- {name: 'dsds 1', id: '1'},
- {name: 'dsds 2', id: '2'},
- {name: 'test name', id: '3'},
- {name: 'aa bb cc', id: '4'},
- {name: 'Untitled Note 6', id: '4'}
- ]
-
- noteList.setNotes(notesList)
-
- ctrl.sourceNoteName = 'test name'
- expect(ctrl.cloneNoteName()).toEqual('test name 1')
- ctrl.sourceNoteName = 'aa bb cc'
- expect(ctrl.cloneNoteName()).toEqual('aa bb cc 1')
- ctrl.sourceNoteName = 'Untitled Note 6'
- expect(ctrl.cloneNoteName()).toEqual('Untitled Note 7')
- ctrl.sourceNoteName = 'My_note'
- expect(ctrl.cloneNoteName()).toEqual('My_note 1')
- ctrl.sourceNoteName = 'dsds 2'
- expect(ctrl.cloneNoteName()).toEqual('dsds 3')
- })
-})
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/noteName-create/visible.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/noteName-create/visible.directive.js b/zeppelin-web/src/components/noteName-create/visible.directive.js
deleted file mode 100644
index 48c170f..0000000
--- a/zeppelin-web/src/components/noteName-create/visible.directive.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').directive('modalvisible', modalvisible)
-
-function modalvisible () {
- return {
- restrict: 'A',
- scope: {
- preVisibleCallback: '&previsiblecallback',
- postVisibleCallback: '&postvisiblecallback',
- targetinput: '@targetinput'
- },
- link: function (scope, element, attrs) {
- // Add some listeners
- let previsibleMethod = scope.preVisibleCallback
- let postVisibleMethod = scope.postVisibleCallback
- element.on('show.bs.modal', function (e) {
- let relatedTarget = angular.element(e.relatedTarget)
- let clone = relatedTarget.data('clone')
- let sourceNoteName = relatedTarget.data('source-note-name')
- let path = relatedTarget.data('path')
- let cloneNote = clone ? true : false
- previsibleMethod()(cloneNote, sourceNoteName, path)
- })
- element.on('shown.bs.modal', function (e) {
- if (scope.targetinput) {
- angular.element(e.target).find('input#' + scope.targetinput).select()
- }
- postVisibleMethod()
- })
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/noteName-import/note-import-dialog.css
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/noteName-import/note-import-dialog.css b/zeppelin-web/src/components/noteName-import/note-import-dialog.css
deleted file mode 100644
index 81e276a..0000000
--- a/zeppelin-web/src/components/noteName-import/note-import-dialog.css
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-.modal-header-import {
- background-color: #3071a9;
- border: 2px solid #3071a9;
- border-top-left-radius: 4px;
- border-top-right-radius: 4px;
-}
-
-.modal-header-import .close {
- color: #cfcfcf;
- opacity: 1;
-}
-
-.modal-header-import .modal-title {
- color: white;
- font-size: 20px;
- font-weight: 300;
-}
-
-.modal-body-import .note-name-input {
- margin-left: 7px;
- margin-right: 7px;
-}
-
-.modal-body-import label {
- font-size: 15px;
- font-weight: 400;
- margin-bottom: 10px;
- margin-top: 15px;
-}
-
-.modal-body-import {
- min-height: 420px;
- overflow: hidden;
-}
-
-.modal-body-import .import-btn-image-group {
- margin-top: 4px;
-}
-
-.modal-body-import .import-btn-image {
- display: inline-block;
- margin-left: 8px;
-}
-
-.modal-body-import .import-btn-image a {
- background: #fff;
- border: 1px solid #e6e6e6;
- /*border-radius: 20px;*/
- border-radius: 20%;
- color: #7c828e;
- cursor: pointer;
- display: block;
- float: left;
- font-size: 98px;
- text-align: center;
- text-decoration: none;
- height: 240px;
- padding-top: 60px;
- margin: 0 10px 0px 10px;
- width: 250px;
-}
-
-.modal-body-import .import-btn-image a:hover {
- background: #eee;
-}
-
-.modal-body-import .modal-body-import-desc {
- font-size: 15px;
- font-weight: 400;
- margin-top: 30px;
- color: black;
- font-family: 'Roboto', sans-serif;
-}
-
-.modal-footer-import {
- min-height: 65px;
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/noteName-import/note-import-dialog.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/noteName-import/note-import-dialog.html b/zeppelin-web/src/components/noteName-import/note-import-dialog.html
deleted file mode 100644
index c640ca1..0000000
--- a/zeppelin-web/src/components/noteName-import/note-import-dialog.html
+++ /dev/null
@@ -1,80 +0,0 @@
-<!--
-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.
--->
-<div id="noteImportModal" class="modal fade" role="dialog" tabindex="-1"
- data-backdrop="static" data-keyboard="false">
-
- <div class="modal-dialog">
- <div class="modal-content" id="NoteImportCtrl" ng-init="NoteImportInit">
-
- <!-- modal-header -->
- <div class="modal-header modal-header-import">
- <button type="button" class="close" data-dismiss="modal"
- ng-click="noteimportctrl.resetFlags()">×</button>
- <h4 class="modal-title">Import New Note</h4>
- </div>
-
- <!-- modal-body -->
- <div class="modal-body modal-body-import">
- <div class="form-group">
- <label for="noteImportName">Import As</label>
- <input class="form-control note-name-input" id="noteImportName"
- placeholder="Insert Note Name" type="text"
- ng-model="note.noteImportName" />
- </div>
-
- <div class="form-group" ng-show="note.errorText">
- <div class="alert alert-danger">{{note.errorText}}</div>
- </div>
-
- <label>JSON file size cannot exceed {{maxLimit}} MB</label>
-
- <div class="form-group slide-left import-btn-image-group" ng-show="note.step1">
- <div class="import-btn-image">
- <a class="fa fa-cloud-upload import-file-upload" ng-click="uploadFile()">
- <p class="modal-body-import-desc">Select JSON File </p>
- </a>
- <div style="display: none">
- <input class="form-control note-name-input" id="noteImportFile"
- placeholder="Note name" type="file"
- ng-model="note.importFile" onchange="angular.element(this).scope().importFile(this)" />
- </div>
- </div>
- <div class="import-btn-image">
- <a href="javascript:void(0);" ng-click="uploadURL()" class="fa fa-link">
- <p class="modal-body-import-desc">Add from URL</p>
- </a>
- </div>
- </div>
-
- <div class="form-group slide-right" ng-show="note.step2">
-
- <label for="noteImportUrl">URL</label>
- <input placeholder="Note URL" type="text" class="form-control" id="noteImportUrl"
- ng-model="note.importUrl" />
- </div>
-
- </div>
- <div class="modal-footer modal-footer-import" ng-show="note.step2">
- <button type="button" id="importBackButton"
- class="btn btn-default"
- ng-click="noteimportctrl.importBack()">Back
- </button>
- <button type="button" id="importNoteButton"
- class="btn btn-default"
- ng-click="noteimportctrl.importNote()">Import Note
- </button>
- </div>
- </div>
- </div>
-</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/noteName-import/notenameImport.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/noteName-import/notenameImport.controller.js b/zeppelin-web/src/components/noteName-import/notenameImport.controller.js
deleted file mode 100644
index 0959244..0000000
--- a/zeppelin-web/src/components/noteName-import/notenameImport.controller.js
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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 './note-import-dialog.css'
-
-angular.module('zeppelinWebApp').controller('NoteImportCtrl', NoteImportCtrl)
-
-function NoteImportCtrl ($scope, $timeout, websocketMsgSrv) {
- 'ngInject'
-
- let vm = this
- $scope.note = {}
- $scope.note.step1 = true
- $scope.note.step2 = false
- $scope.maxLimit = ''
- let limit = 0
-
- websocketMsgSrv.listConfigurations()
- $scope.$on('configurationsInfo', function (scope, event) {
- limit = event.configurations['zeppelin.websocket.max.text.message.size']
- $scope.maxLimit = Math.round(limit / 1048576)
- })
-
- vm.resetFlags = function () {
- $scope.note = {}
- $scope.note.step1 = true
- $scope.note.step2 = false
- angular.element('#noteImportFile').val('')
- }
-
- $scope.uploadFile = function () {
- angular.element('#noteImportFile').click()
- }
-
- $scope.importFile = function (element) {
- $scope.note.errorText = ''
- $scope.note.importFile = element.files[0]
- let file = $scope.note.importFile
- let reader = new FileReader()
-
- if (file.size > limit) {
- $scope.note.errorText = 'File size limit Exceeded!'
- $scope.$apply()
- return
- }
-
- reader.onloadend = function () {
- vm.processImportJson(reader.result)
- }
-
- if (file) {
- reader.readAsText(file)
- }
- }
-
- $scope.uploadURL = function () {
- $scope.note.errorText = ''
- $scope.note.step1 = false
- $timeout(function () {
- $scope.note.step2 = true
- }, 400)
- }
-
- vm.importBack = function () {
- $scope.note.errorText = ''
- $timeout(function () {
- $scope.note.step1 = true
- }, 400)
- $scope.note.step2 = false
- }
-
- vm.importNote = function () {
- $scope.note.errorText = ''
- if ($scope.note.importUrl) {
- jQuery.ajax({
- url: $scope.note.importUrl,
- type: 'GET',
- dataType: 'json',
- jsonp: false,
- xhrFields: {
- withCredentials: false
- },
- error: function (xhr, ajaxOptions, thrownError) {
- $scope.note.errorText = 'Unable to Fetch URL'
- $scope.$apply()
- }}).done(function (data) {
- vm.processImportJson(data)
- })
- } else {
- $scope.note.errorText = 'Enter URL'
- $scope.$apply()
- }
- }
-
- vm.processImportJson = function (result) {
- if (typeof result !== 'object') {
- try {
- result = JSON.parse(result)
- } catch (e) {
- $scope.note.errorText = 'JSON parse exception'
- $scope.$apply()
- return
- }
- }
- if (result.paragraphs && result.paragraphs.length > 0) {
- if (!$scope.note.noteImportName) {
- $scope.note.noteImportName = result.name
- } else {
- result.name = $scope.note.noteImportName
- }
- websocketMsgSrv.importNote(result)
- // angular.element('#noteImportModal').modal('hide');
- } else {
- $scope.note.errorText = 'Invalid JSON'
- }
- $scope.$apply()
- }
-
- /*
- ** $scope.$on functions below
- */
-
- $scope.$on('setNoteMenu', function (event, notes) {
- vm.resetFlags()
- angular.element('#noteImportModal').modal('hide')
- })
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/notevarshareService/notevarshare.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/notevarshareService/notevarshare.service.js b/zeppelin-web/src/components/notevarshareService/notevarshare.service.js
deleted file mode 100644
index 04981bf..0000000
--- a/zeppelin-web/src/components/notevarshareService/notevarshare.service.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').service('noteVarShareService', noteVarShareService)
-
-function noteVarShareService () {
- 'ngInject'
-
- let store = {}
-
- this.clear = function () {
- store = {}
- }
-
- this.put = function (key, value) {
- store[key] = value
- }
-
- this.get = function (key) {
- return store[key]
- }
-
- this.del = function (key) {
- let v = store[key]
- delete store[key]
- return v
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/rename/rename.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/rename/rename.controller.js b/zeppelin-web/src/components/rename/rename.controller.js
deleted file mode 100644
index 2682b6e..0000000
--- a/zeppelin-web/src/components/rename/rename.controller.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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 './rename.css'
-
-angular.module('zeppelinWebApp').controller('RenameCtrl', RenameCtrl)
-
-function RenameCtrl ($scope) {
- 'ngInject'
-
- let self = this
-
- $scope.params = {newName: ''}
- $scope.isValid = true
-
- $scope.rename = function () {
- angular.element('#renameModal').modal('hide')
- self.callback($scope.params.newName)
- }
-
- $scope.$on('openRenameModal', function (event, options) {
- self.validator = options.validator || defaultValidator
- self.callback = options.callback || function () {}
-
- $scope.title = options.title || 'Rename'
- $scope.params.newName = options.oldName || ''
- $scope.validate = function () {
- $scope.isValid = self.validator($scope.params.newName)
- }
-
- angular.element('#renameModal').modal('show')
- })
-
- function defaultValidator (str) {
- return !!str.trim()
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/rename/rename.css
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/rename/rename.css b/zeppelin-web/src/components/rename/rename.css
deleted file mode 100644
index 45d4710..0000000
--- a/zeppelin-web/src/components/rename/rename.css
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.
- */
-
-.modal-header-rename {
- background-color: #3071a9;
- border: 2px solid #3071a9;
- border-top-left-radius: 4px;
- border-top-right-radius: 4px;
-}
-
-.modal-header-rename .close {
- color: #cfcfcf;
- opacity: 1;
-}
-
-.modal-header-rename .modal-title {
- color: white;
- font-size: 20px;
- font-weight: 300;
-}
-
-.modal-body-rename label {
- font-size: 17px;
- font-weight: 400;
- margin-top: 5px;
- margin-bottom: 15px;
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/rename/rename.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/rename/rename.html b/zeppelin-web/src/components/rename/rename.html
deleted file mode 100644
index 71caa76..0000000
--- a/zeppelin-web/src/components/rename/rename.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!--
-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.
--->
-<div id="renameModal" class="modal fade" role="dialog" tabindex="-1">
- <div class="modal-dialog">
- <div class="modal-content">
- <!-- modal-header -->
- <div class="modal-header modal-header-rename">
- <button type="button" class="close" data-dismiss="modal">×</button>
- <h4 class="modal-title">{{title}}</h4>
- </div>
-
- <!-- modal-body -->
- <div class="modal-body modal-body-rename">
- <label ng-if="isValid">Please enter a new name</label>
- <label ng-if="!isValid" class="text-danger">Please enter a valid name</label>
- <div class="form-group" ng-class="{'has-error': !isValid}">
- <input type="text" class="form-control"
- ng-model="params.newName" ng-change="validate()"
- ng-enter="isValid && rename()" />
- </div>
- </div>
- <div class="modal-footer">
- <div>
- <button type="button" class="btn btn-default btn-primary"
- ng-click="rename()" ng-class="{'disabled': !isValid}">
- Rename
- </button>
- </div>
- </div>
- </div>
- </div>
-</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/rename/rename.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/rename/rename.service.js b/zeppelin-web/src/components/rename/rename.service.js
deleted file mode 100644
index 135f85d..0000000
--- a/zeppelin-web/src/components/rename/rename.service.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').service('renameSrv', renameSrv)
-
-function renameSrv ($rootScope) {
- 'ngInject'
-
- let self = this
-
- /**
- * <options schema>
- * title: string - Modal title
- * oldName: string - name to initialize input
- * callback: (newName: string)=>void - callback onButtonClick
- * validator: (str: string)=>boolean - input validator
- */
- self.openRenameModal = function (options) {
- $rootScope.$broadcast('openRenameModal', options)
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/repository-create/repository-dialog.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/repository-create/repository-dialog.html b/zeppelin-web/src/components/repository-create/repository-dialog.html
deleted file mode 100644
index ab678b7..0000000
--- a/zeppelin-web/src/components/repository-create/repository-dialog.html
+++ /dev/null
@@ -1,115 +0,0 @@
-<!--
-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.
--->
-
-<div id="repoModal" class="modal fade" role="dialog"
- tabindex="-1">
- <div class="modal-dialog">
-
- <!-- Modal content-->
- <div class="modal-content">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal">×</button>
- <h4 class="modal-title">Add New Repository</h4>
- </div>
-
- <form class="form-horizontal" ng-submit="addNewRepository()">
- <div class="modal-body">
- <div class="form-group">
- <label class="control-label col-sm-2" for="repoId">ID</label>
- <div class="col-sm-10">
- <input type="text" class="form-control" id="repoId" ng-model="newRepoSetting.id"
- placeholder="Repository id" required />
- </div>
- </div>
- <div class="form-group">
- <label class="control-label col-sm-2" for="repoUrl">URL</label>
- <div class="col-sm-10">
- <input type="text" pattern="(http|https|file)://.*" title="Please enter URL starts with http://, https:// or file://"
- class="form-control" id="repoUrl" ng-model="newRepoSetting.url"
- placeholder="Repository url" required />
- </div>
- </div>
- <div class="form-group">
- <label class="control-label col-sm-2" for="repoSnapshot">Snapshot</label>
- <div class="col-sm-10">
- <select class="form-control"
- id="repoSnapshot"
- ng-model="newRepoSetting.snapshot"
- ng-options="col for col in [false,true]">
- </select>
- </div>
- </div>
- <div class="form-group">
- <label class="control-label col-sm-2" for="repoUsername">Username</label>
- <div class="col-sm-10">
- <input type="text" class="form-control" id="repoUsername" ng-model="newRepoSetting.username" />
- </div>
- </div>
- <div class="form-group">
- <label class="control-label col-sm-2" for="repoPassword">Password</label>
- <div class="col-sm-10">
- <input type="password" class="form-control" id="repoPassword" ng-model="newRepoSetting.password" />
- </div>
- </div>
- <hr/>
- <div class="center-block"><h4>Proxy Settings (optional)</h4></div>
- <br/>
- <div class="form-group">
- <div class="col-sm-10">
- <label class="control-label col-sm-2" for="proxyProtocol1">Protocol</label>
- <label class="radio-inline">
- <input type="radio" name="proxyProtocol" id="proxyProtocol1" value="HTTP" ng-model="newRepoSetting.proxyProtocol"/> HTTP
- </label>
- <label class="radio-inline">
- <input type="radio" name="proxyProtocol" id="proxyProtocol2" value="HTTPS" ng-model="newRepoSetting.proxyProtocol"/> HTTPS
- </label>
- </div>
- </div>
- <div class="form-group">
- <label class="control-label col-sm-2" for="proxyHost">Host</label>
- <div class="col-sm-10">
- <input type="text" class="form-control" id="proxyHost" ng-model="newRepoSetting.proxyHost" />
- </div>
- </div>
- <div class="form-group">
- <label class="control-label col-sm-2" for="proxyPort">Port</label>
- <div class="col-sm-10">
- <input type="text" class="form-control" id="proxyPort" ng-model="newRepoSetting.proxyPort" />
- </div>
- </div>
- <div class="form-group">
- <label class="control-label col-sm-2" for="proxyLogin">Login</label>
- <div class="col-sm-10">
- <input type="text" class="form-control" id="proxyLogin" ng-model="newRepoSetting.proxyLogin" />
- </div>
- </div>
- <div class="form-group">
- <label class="control-label col-sm-2" for="proxyPassword">Password</label>
- <div class="col-sm-10">
- <input type="text" class="form-control" id="proxyPassword" ng-model="newRepoSetting.proxyPassword" />
- </div>
- </div>
- </div>
- <div class="modal-footer">
- <button type="submit"
- class="btn btn-default">Add
- </button>
- <button type="button" data-dismiss="modal"
- class="btn btn-default" ng-click="resetNewRepositorySetting()">Cancel
- </button>
- </div>
- </form>
- </div>
- </div>
-</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/resizable/resizable.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/resizable/resizable.directive.js b/zeppelin-web/src/components/resizable/resizable.directive.js
deleted file mode 100644
index 7bf8477..0000000
--- a/zeppelin-web/src/components/resizable/resizable.directive.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').directive('resizable', resizable)
-
-function resizable () {
- let resizableConfig = {
- autoHide: true,
- handles: 'se',
- helper: 'resizable-helper',
- stop: function () {
- angular.element(this).css({'width': '100%', 'height': '100%'})
- }
- }
-
- return {
- restrict: 'A',
- scope: {
- callback: '&onResize'
- },
- link: function postLink (scope, elem, attrs) {
- attrs.$observe('resize', function (resize) {
- let resetResize = function (elem, resize) {
- let colStep = window.innerWidth / 12
- elem.off('resizestop')
- let conf = angular.copy(resizableConfig)
- if (resize.graphType === 'TABLE' || resize.graphType === 'NETWORK' || resize.graphType === 'TEXT') {
- conf.grid = [colStep, 10]
- conf.minHeight = 100
- } else {
- conf.grid = [colStep, 10000]
- conf.minHeight = 0
- }
- conf.maxWidth = window.innerWidth
-
- elem.resizable(conf)
- elem.on('resizestop', function () {
- if (scope.callback) {
- let height = elem.height()
- if (height < 50) {
- height = 300
- }
- scope.callback({width: Math.ceil(elem.width() / colStep), height: height})
- }
- })
- }
-
- resize = JSON.parse(resize)
- if (resize.allowresize === 'true') {
- resetResize(elem, resize)
- angular.element(window).resize(function () {
- resetResize(elem, resize)
- })
- }
- })
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/saveAs/saveAs.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/saveAs/saveAs.service.js b/zeppelin-web/src/components/saveAs/saveAs.service.js
deleted file mode 100644
index b9cb7c8..0000000
--- a/zeppelin-web/src/components/saveAs/saveAs.service.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').service('saveAsService', saveAsService)
-
-function saveAsService (browserDetectService) {
- 'ngInject'
-
- this.saveAs = function (content, filename, extension) {
- let BOM = '\uFEFF'
- if (browserDetectService.detectIE()) {
- angular.element('body').append('<iframe id="SaveAsId" style="display: none"></iframe>')
- let frameSaveAs = angular.element('body > iframe#SaveAsId')[0].contentWindow
- content = BOM + content
- frameSaveAs.document.open('text/json', 'replace')
- frameSaveAs.document.write(content)
- frameSaveAs.document.close()
- frameSaveAs.focus()
- let t1 = Date.now()
- frameSaveAs.document.execCommand('SaveAs', false, filename + '.' + extension)
- let t2 = Date.now()
-
- // This means, this version of IE dosen't support auto download of a file with extension provided in param
- // falling back to ".txt"
- if (t1 === t2) {
- frameSaveAs.document.execCommand('SaveAs', true, filename + '.txt')
- }
- angular.element('body > iframe#SaveAsId').remove()
- } else {
- content = 'data:image/svg;charset=utf-8,' + BOM + encodeURIComponent(content)
- angular.element('body').append('<a id="SaveAsId"></a>')
- let saveAsElement = angular.element('body > a#SaveAsId')
- saveAsElement.attr('href', content)
- saveAsElement.attr('download', filename + '.' + extension)
- saveAsElement.attr('target', '_blank')
- saveAsElement[0].click()
- saveAsElement.remove()
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/searchService/search.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/searchService/search.service.js b/zeppelin-web/src/components/searchService/search.service.js
deleted file mode 100644
index a1c8640..0000000
--- a/zeppelin-web/src/components/searchService/search.service.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').service('searchService', searchService)
-
-function searchService ($resource, baseUrlSrv) {
- 'ngInject'
-
- this.search = function (term) {
- this.searchTerm = term.q
- console.log('Searching for: %o', term.q)
- if (!term.q) { // TODO(bzz): empty string check
- return
- }
- let encQuery = window.encodeURIComponent(term.q)
- return $resource(baseUrlSrv.getRestApiBase() + '/notebook/search?q=' + encQuery, {}, {
- query: {method: 'GET'}
- })
- }
-
- this.searchTerm = ''
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/websocket/websocket-event.factory.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/websocket/websocket-event.factory.js b/zeppelin-web/src/components/websocket/websocket-event.factory.js
new file mode 100644
index 0000000..f8391ab
--- /dev/null
+++ b/zeppelin-web/src/components/websocket/websocket-event.factory.js
@@ -0,0 +1,196 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').factory('websocketEvents', WebsocketEventFactory)
+
+function WebsocketEventFactory ($rootScope, $websocket, $location, baseUrlSrv) {
+ 'ngInject'
+
+ let websocketCalls = {}
+ let pingIntervalId
+
+ websocketCalls.ws = $websocket(baseUrlSrv.getWebsocketUrl())
+ websocketCalls.ws.reconnectIfNotNormalClose = true
+
+ websocketCalls.ws.onOpen(function () {
+ console.log('Websocket created')
+ $rootScope.$broadcast('setConnectedStatus', true)
+ pingIntervalId = setInterval(function () {
+ websocketCalls.sendNewEvent({op: 'PING'})
+ }, 10000)
+ })
+
+ websocketCalls.sendNewEvent = function (data) {
+ if ($rootScope.ticket !== undefined) {
+ data.principal = $rootScope.ticket.principal
+ data.ticket = $rootScope.ticket.ticket
+ data.roles = $rootScope.ticket.roles
+ } else {
+ data.principal = ''
+ data.ticket = ''
+ data.roles = ''
+ }
+ console.log('Send >> %o, %o, %o, %o, %o', data.op, data.principal, data.ticket, data.roles, data)
+ websocketCalls.ws.send(JSON.stringify(data))
+ }
+
+ websocketCalls.isConnected = function () {
+ return (websocketCalls.ws.socket.readyState === 1)
+ }
+
+ websocketCalls.ws.onMessage(function (event) {
+ let payload
+ if (event.data) {
+ payload = angular.fromJson(event.data)
+ }
+
+ console.log('Receive << %o, %o', payload.op, payload)
+
+ let op = payload.op
+ let data = payload.data
+ if (op === 'NOTE') {
+ $rootScope.$broadcast('setNoteContent', data.note)
+ } else if (op === 'NEW_NOTE') {
+ $location.path('/notebook/' + data.note.id)
+ } else if (op === 'NOTES_INFO') {
+ $rootScope.$broadcast('setNoteMenu', data.notes)
+ } else if (op === 'LIST_NOTE_JOBS') {
+ $rootScope.$broadcast('setNoteJobs', data.noteJobs)
+ } else if (op === 'LIST_UPDATE_NOTE_JOBS') {
+ $rootScope.$broadcast('setUpdateNoteJobs', data.noteRunningJobs)
+ } else if (op === 'AUTH_INFO') {
+ let btn = []
+ if ($rootScope.ticket.roles === '[]') {
+ btn = [{
+ label: 'Close',
+ action: function (dialog) {
+ dialog.close()
+ }
+ }]
+ } else {
+ btn = [{
+ label: 'Login',
+ action: function (dialog) {
+ dialog.close()
+ angular.element('#loginModal').modal({
+ show: 'true'
+ })
+ }
+ }, {
+ label: 'Cancel',
+ action: function (dialog) {
+ dialog.close()
+ // using $rootScope.apply to trigger angular digest cycle
+ // changing $location.path inside bootstrap modal wont trigger digest
+ $rootScope.$apply(function () {
+ $location.path('/')
+ })
+ }
+ }]
+ }
+
+ BootstrapDialog.show({
+ closable: false,
+ closeByBackdrop: false,
+ closeByKeyboard: false,
+ title: 'Insufficient privileges',
+ message: data.info.toString(),
+ buttons: btn
+ })
+ } else if (op === 'PARAGRAPH') {
+ $rootScope.$broadcast('updateParagraph', data)
+ } else if (op === 'RUN_PARAGRAPH_USING_SPELL') {
+ $rootScope.$broadcast('runParagraphUsingSpell', data)
+ } else if (op === 'PARAGRAPH_APPEND_OUTPUT') {
+ $rootScope.$broadcast('appendParagraphOutput', data)
+ } else if (op === 'PARAGRAPH_UPDATE_OUTPUT') {
+ $rootScope.$broadcast('updateParagraphOutput', data)
+ } else if (op === 'PROGRESS') {
+ $rootScope.$broadcast('updateProgress', data)
+ } else if (op === 'COMPLETION_LIST') {
+ $rootScope.$broadcast('completionList', data)
+ } else if (op === 'EDITOR_SETTING') {
+ $rootScope.$broadcast('editorSetting', data)
+ } else if (op === 'ANGULAR_OBJECT_UPDATE') {
+ $rootScope.$broadcast('angularObjectUpdate', data)
+ } else if (op === 'ANGULAR_OBJECT_REMOVE') {
+ $rootScope.$broadcast('angularObjectRemove', data)
+ } else if (op === 'APP_APPEND_OUTPUT') {
+ $rootScope.$broadcast('appendAppOutput', data)
+ } else if (op === 'APP_UPDATE_OUTPUT') {
+ $rootScope.$broadcast('updateAppOutput', data)
+ } else if (op === 'APP_LOAD') {
+ $rootScope.$broadcast('appLoad', data)
+ } else if (op === 'APP_STATUS_CHANGE') {
+ $rootScope.$broadcast('appStatusChange', data)
+ } else if (op === 'LIST_REVISION_HISTORY') {
+ $rootScope.$broadcast('listRevisionHistory', data)
+ } else if (op === 'NOTE_REVISION') {
+ $rootScope.$broadcast('noteRevision', data)
+ } else if (op === 'INTERPRETER_BINDINGS') {
+ $rootScope.$broadcast('interpreterBindings', data)
+ } else if (op === 'ERROR_INFO') {
+ BootstrapDialog.show({
+ closable: false,
+ closeByBackdrop: false,
+ closeByKeyboard: false,
+ title: 'Details',
+ message: data.info.toString(),
+ buttons: [{
+ // close all the dialogs when there are error on running all paragraphs
+ label: 'Close',
+ action: function () {
+ BootstrapDialog.closeAll()
+ }
+ }]
+ })
+ } else if (op === 'SESSION_LOGOUT') {
+ $rootScope.$broadcast('session_logout', data)
+ } else if (op === 'CONFIGURATIONS_INFO') {
+ $rootScope.$broadcast('configurationsInfo', data)
+ } else if (op === 'INTERPRETER_SETTINGS') {
+ $rootScope.$broadcast('interpreterSettings', data)
+ } else if (op === 'PARAGRAPH_ADDED') {
+ $rootScope.$broadcast('addParagraph', data.paragraph, data.index)
+ } else if (op === 'PARAGRAPH_REMOVED') {
+ $rootScope.$broadcast('removeParagraph', data.id)
+ } else if (op === 'PARAGRAPH_MOVED') {
+ $rootScope.$broadcast('moveParagraph', data.id, data.index)
+ } else if (op === 'NOTE_UPDATED') {
+ $rootScope.$broadcast('updateNote', data.name, data.config, data.info)
+ } else if (op === 'SET_NOTE_REVISION') {
+ $rootScope.$broadcast('setNoteRevisionResult', data)
+ } else if (op === 'PARAS_INFO') {
+ $rootScope.$broadcast('updateParaInfos', data)
+ } else {
+ console.error(`unknown websocket op: ${op}`)
+ }
+ })
+
+ websocketCalls.ws.onError(function (event) {
+ console.log('error message: ', event)
+ $rootScope.$broadcast('setConnectedStatus', false)
+ })
+
+ websocketCalls.ws.onClose(function (event) {
+ console.log('close message: ', event)
+ if (pingIntervalId !== undefined) {
+ clearInterval(pingIntervalId)
+ pingIntervalId = undefined
+ }
+ $rootScope.$broadcast('setConnectedStatus', false)
+ })
+
+ return websocketCalls
+}
[4/5] zeppelin git commit: [ZEPPELIN-2749] Use scalable file
structure for zeppelin web
Posted by ku...@apache.org.
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/interpreter/repository-create.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/interpreter/repository-create.html b/zeppelin-web/src/app/interpreter/repository-create.html
new file mode 100644
index 0000000..ab678b7
--- /dev/null
+++ b/zeppelin-web/src/app/interpreter/repository-create.html
@@ -0,0 +1,115 @@
+<!--
+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.
+-->
+
+<div id="repoModal" class="modal fade" role="dialog"
+ tabindex="-1">
+ <div class="modal-dialog">
+
+ <!-- Modal content-->
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal">×</button>
+ <h4 class="modal-title">Add New Repository</h4>
+ </div>
+
+ <form class="form-horizontal" ng-submit="addNewRepository()">
+ <div class="modal-body">
+ <div class="form-group">
+ <label class="control-label col-sm-2" for="repoId">ID</label>
+ <div class="col-sm-10">
+ <input type="text" class="form-control" id="repoId" ng-model="newRepoSetting.id"
+ placeholder="Repository id" required />
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="control-label col-sm-2" for="repoUrl">URL</label>
+ <div class="col-sm-10">
+ <input type="text" pattern="(http|https|file)://.*" title="Please enter URL starts with http://, https:// or file://"
+ class="form-control" id="repoUrl" ng-model="newRepoSetting.url"
+ placeholder="Repository url" required />
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="control-label col-sm-2" for="repoSnapshot">Snapshot</label>
+ <div class="col-sm-10">
+ <select class="form-control"
+ id="repoSnapshot"
+ ng-model="newRepoSetting.snapshot"
+ ng-options="col for col in [false,true]">
+ </select>
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="control-label col-sm-2" for="repoUsername">Username</label>
+ <div class="col-sm-10">
+ <input type="text" class="form-control" id="repoUsername" ng-model="newRepoSetting.username" />
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="control-label col-sm-2" for="repoPassword">Password</label>
+ <div class="col-sm-10">
+ <input type="password" class="form-control" id="repoPassword" ng-model="newRepoSetting.password" />
+ </div>
+ </div>
+ <hr/>
+ <div class="center-block"><h4>Proxy Settings (optional)</h4></div>
+ <br/>
+ <div class="form-group">
+ <div class="col-sm-10">
+ <label class="control-label col-sm-2" for="proxyProtocol1">Protocol</label>
+ <label class="radio-inline">
+ <input type="radio" name="proxyProtocol" id="proxyProtocol1" value="HTTP" ng-model="newRepoSetting.proxyProtocol"/> HTTP
+ </label>
+ <label class="radio-inline">
+ <input type="radio" name="proxyProtocol" id="proxyProtocol2" value="HTTPS" ng-model="newRepoSetting.proxyProtocol"/> HTTPS
+ </label>
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="control-label col-sm-2" for="proxyHost">Host</label>
+ <div class="col-sm-10">
+ <input type="text" class="form-control" id="proxyHost" ng-model="newRepoSetting.proxyHost" />
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="control-label col-sm-2" for="proxyPort">Port</label>
+ <div class="col-sm-10">
+ <input type="text" class="form-control" id="proxyPort" ng-model="newRepoSetting.proxyPort" />
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="control-label col-sm-2" for="proxyLogin">Login</label>
+ <div class="col-sm-10">
+ <input type="text" class="form-control" id="proxyLogin" ng-model="newRepoSetting.proxyLogin" />
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="control-label col-sm-2" for="proxyPassword">Password</label>
+ <div class="col-sm-10">
+ <input type="text" class="form-control" id="proxyPassword" ng-model="newRepoSetting.proxyPassword" />
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button type="submit"
+ class="btn btn-default">Add
+ </button>
+ <button type="button" data-dismiss="modal"
+ class="btn btn-default" ng-click="resetNewRepositorySetting()">Cancel
+ </button>
+ </div>
+ </form>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/interpreter/widget/number-widget.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/interpreter/widget/number-widget.directive.js b/zeppelin-web/src/app/interpreter/widget/number-widget.directive.js
new file mode 100644
index 0000000..2046b94
--- /dev/null
+++ b/zeppelin-web/src/app/interpreter/widget/number-widget.directive.js
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').directive('numberWidget', InterpreterNumberDirective)
+
+function InterpreterNumberDirective() {
+ return {
+ require: 'ngModel',
+ link: function (scope, element, attrs, modelCtrl) {
+ modelCtrl.$parsers.push(function (inputValue) {
+ let transformedInput = inputValue ? inputValue.replace(/[^\d.-]/g, '') : null
+ if (transformedInput !== inputValue) {
+ modelCtrl.$setViewValue(transformedInput)
+ modelCtrl.$render()
+ }
+ return transformedInput
+ })
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/jobmanager/jobs/job-progress-bar.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/jobmanager/jobs/job-progress-bar.html b/zeppelin-web/src/app/jobmanager/jobs/job-progress-bar.html
new file mode 100644
index 0000000..00b290b
--- /dev/null
+++ b/zeppelin-web/src/app/jobmanager/jobs/job-progress-bar.html
@@ -0,0 +1,22 @@
+<!--
+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.
+-->
+
+<div id="{{notebookJob.noteId}}_runControl" class="runControl">
+ <div id="{{notebookJob.noteId}}_progress" class="progress" ng-if="notebookJob.isRunningJob === true">
+ <div ng-if="getProgress()>0 && getProgress()<100 && notebookJob.isRunningJob === true"
+ class="progress-bar" role="progressbar" ng-style="{width:getProgress()+'%'}"></div>
+ <div ng-if="(getProgress()<=0 || getProgress()>=100) && (notebookJob.isRunningJob === true)"
+ class="progress-bar progress-bar-striped active" role="progressbar" style="width:100%;"></div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/jobmanager/jobs/job-progressBar.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/jobmanager/jobs/job-progressBar.html b/zeppelin-web/src/app/jobmanager/jobs/job-progressBar.html
deleted file mode 100644
index 00b290b..0000000
--- a/zeppelin-web/src/app/jobmanager/jobs/job-progressBar.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!--
-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.
--->
-
-<div id="{{notebookJob.noteId}}_runControl" class="runControl">
- <div id="{{notebookJob.noteId}}_progress" class="progress" ng-if="notebookJob.isRunningJob === true">
- <div ng-if="getProgress()>0 && getProgress()<100 && notebookJob.isRunningJob === true"
- class="progress-bar" role="progressbar" ng-style="{width:getProgress()+'%'}"></div>
- <div ng-if="(getProgress()<=0 || getProgress()>=100) && (notebookJob.isRunningJob === true)"
- class="progress-bar progress-bar-striped active" role="progressbar" style="width:100%;"></div>
- </div>
-</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/jobmanager/jobs/job.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/jobmanager/jobs/job.html b/zeppelin-web/src/app/jobmanager/jobs/job.html
index e555771..b6dd6be 100644
--- a/zeppelin-web/src/app/jobmanager/jobs/job.html
+++ b/zeppelin-web/src/app/jobmanager/jobs/job.html
@@ -28,7 +28,7 @@ limitations under the License.
<span ng-if="notebookJob.interpreter !== undefined" style="color: black;">
{{notebookJob.interpreter}}</span>
</a>
- <div ng-include src="'app/jobmanager/jobs/job-progressBar.html'"></div>
+ <div ng-include src="'app/jobmanager/jobs/job-progress-bar.html'"></div>
</div>
<div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook-repository/notebook-repository.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook-repository/notebook-repository.controller.js b/zeppelin-web/src/app/notebook-repository/notebook-repository.controller.js
new file mode 100644
index 0000000..0f62bc0
--- /dev/null
+++ b/zeppelin-web/src/app/notebook-repository/notebook-repository.controller.js
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').controller('NotebookRepositoryCtrl', NotebookRepositoryCtrl)
+
+function NotebookRepositoryCtrl($http, baseUrlSrv, ngToast) {
+ 'ngInject'
+
+ let vm = this
+ vm.notebookRepos = []
+ vm.showDropdownSelected = showDropdownSelected
+ vm.saveNotebookRepo = saveNotebookRepo
+
+ _init()
+
+ // Public functions
+
+ function saveNotebookRepo (valueform, repo, data) {
+ console.log('data %o', data)
+ $http.put(baseUrlSrv.getRestApiBase() + '/notebook-repositories', {
+ 'name': repo.className,
+ 'settings': data
+ }).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)
+ }
+ valueform.$show()
+ }).error(function () {
+ ngToast.danger({
+ content: 'We couldn\'t save that NotebookRepo\'s settings',
+ verticalPosition: 'bottom',
+ timeout: '3000'
+ })
+ valueform.$show()
+ })
+
+ return 'manual'
+ }
+
+ function showDropdownSelected (setting) {
+ let index = _.findIndex(setting.value, {'value': setting.selected})
+ if (index < 0) {
+ return 'No value'
+ } else {
+ return setting.value[index].name
+ }
+ }
+
+ // Private functions
+
+ 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 = baseUrlSrv.getBase()
+ }, 3000)
+ }
+ console.log('Error %o %o', status, data.message)
+ })
+ }
+
+ function _init () {
+ _getInterpreterSettings()
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook-repository/notebook-repository.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook-repository/notebook-repository.html b/zeppelin-web/src/app/notebook-repository/notebook-repository.html
new file mode 100644
index 0000000..1e30df3
--- /dev/null
+++ b/zeppelin-web/src/app/notebook-repository/notebook-repository.html
@@ -0,0 +1,98 @@
+<!--
+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.
+-->
+<div class="interpreterHead">
+ <div class="header">
+ <div class="row">
+ <div class="col-md-12">
+ <h3 class="new_h3">
+ Notebook Repository
+ </h3>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ Manage your Notebook Repositories' settings.
+ </div>
+ </div>
+ </div>
+</div>
+
+<div class="box width-full"
+ ng-repeat="repo in noterepo.notebookRepos | orderBy: 'name'">
+ <div id="{{repo.name | lowercase}}">
+ <div class="row interpreter">
+
+ <div class="col-md-12">
+ <h3 class="interpreter-title">{{repo.name}}</h3>
+ <span style="float:right" ng-show="repo.settings.length > 0">
+ <button class="btn btn-default btn-xs"
+ ng-click="valueform.$show();">
+ <span class="fa fa-pencil"></span> edit</button>
+ </span>
+ </div>
+ </div>
+ <div class="row interpreter">
+ <div class="col-md-12" ng-show="repo.settings.length > 0">
+ <h5>Settings</h5>
+ <table class="table table-striped">
+ <thead>
+ <tr>
+ <th style="width:40%">name</th>
+ <th style="width:60%">value</th>
+ </tr>
+ </thead>
+ <tr ng-repeat="setting in repo.settings" >
+ <td ng-bind="setting.name"></td>
+ <td>
+ <span class="btn-group">
+ <span ng-show="setting.type === 'DROPDOWN'">
+ <span editable-select="setting.selected"
+ e-name="{{setting.name}}"
+ e-ng-options="s.value as s.name for s in setting.value"
+ class="selectpicker" ng-disabled="!valueform.$visible" e-form="valueform">
+ {{noterepo.showDropdownSelected(setting)}}
+ </span>
+ </span>
+ <span ng-show="setting.type === 'INPUT'">
+ <span editable-textarea="setting.selected" e-name="{{setting.name}}" e-form="valueform" e-msd-elastic e-cols="100">
+ {{setting.selected | breakFilter}}
+ </span>
+ </span>
+ </span>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ <span style="float:right" ng-show="valueform.$visible">
+ <form editable-form name="valueform"
+ onbeforesave="noterepo.saveNotebookRepo(valueform, repo, $data)"
+ ng-show="valueform.$visible">
+ <button type="submit" class="btn btn-primary btn-xs">
+ <span class="fa fa-check"></span> Save
+ </button>
+ <button type="button" class="btn btn-default btn-xs"
+ ng-disabled="valueform.$waiting"
+ ng-click="valueform.$cancel();">
+ <span class="fa fa-remove"></span> Cancel
+ </button>
+ </form>
+ </span>
+ <div class="row interpreter">
+ <div ng-show="repo.settings.length === 0 || valueform.$hidden" class="col-md-12 gray40-message">
+ <em>Currently there are no settings for this Notebook Repository</em>
+ </div>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/dropdown-input/dropdown-input.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/dropdown-input/dropdown-input.directive.js b/zeppelin-web/src/app/notebook/dropdown-input/dropdown-input.directive.js
new file mode 100644
index 0000000..a64204a
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/dropdown-input/dropdown-input.directive.js
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').directive('dropdownInput', dropdownInputDirective)
+
+function dropdownInputDirective() {
+ return {
+ restrict: 'A',
+ link: function (scope, element) {
+ element.bind('click', function (event) {
+ event.stopPropagation()
+ })
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/elastic-input/elastic-input.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/elastic-input/elastic-input.controller.js b/zeppelin-web/src/app/notebook/elastic-input/elastic-input.controller.js
new file mode 100644
index 0000000..507b2f6
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/elastic-input/elastic-input.controller.js
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').controller('ElasticInputCtrl', ElasticInputCtrl)
+
+function ElasticInputCtrl () {
+ let vm = this
+ vm.showEditor = false
+ vm.value = ''
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/note-var-share.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/note-var-share.service.js b/zeppelin-web/src/app/notebook/note-var-share.service.js
new file mode 100644
index 0000000..e79f389
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/note-var-share.service.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').service('noteVarShareService', NoteVarShareService)
+
+function NoteVarShareService () {
+ 'ngInject'
+
+ let store = {}
+
+ this.clear = function () {
+ store = {}
+ }
+
+ this.put = function (key, value) {
+ store[key] = value
+ }
+
+ this.get = function (key) {
+ return store[key]
+ }
+
+ this.del = function (key) {
+ let v = store[key]
+ delete store[key]
+ return v
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/notebook-actionBar.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/notebook-actionBar.html b/zeppelin-web/src/app/notebook/notebook-actionBar.html
index 5b600f2..919ddbc 100644
--- a/zeppelin-web/src/app/notebook/notebook-actionBar.html
+++ b/zeppelin-web/src/app/notebook/notebook-actionBar.html
@@ -60,7 +60,7 @@ limitations under the License.
class="btn btn-default btn-xs"
ng-hide="viewOnly"
tooltip-placement="bottom" uib-tooltip="Clone this note" data-source-note-name="{{note.name}}"
- data-toggle="modal" data-target="#noteNameModal" data-clone="true"
+ data-toggle="modal" data-target="#noteCreateModal" data-clone="true"
ng-disabled="revisionView">
<i class="fa fa-copy"></i>
</button>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/notebook.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/notebook.controller.js b/zeppelin-web/src/app/notebook/notebook.controller.js
index 8a3a97b..7504807 100644
--- a/zeppelin-web/src/app/notebook/notebook.controller.js
+++ b/zeppelin-web/src/app/notebook/notebook.controller.js
@@ -20,7 +20,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', NotebookCtrl)
function NotebookCtrl ($scope, $route, $routeParams, $location, $rootScope,
$http, websocketMsgSrv, baseUrlSrv, $timeout, saveAsService,
- ngToast, noteActionSrv, noteVarShareService, TRASH_FOLDER_ID,
+ ngToast, noteActionService, noteVarShareService, TRASH_FOLDER_ID,
heliumService) {
'ngInject'
@@ -165,12 +165,12 @@ function NotebookCtrl ($scope, $route, $routeParams, $location, $rootScope,
// Move the note to trash and go back to the main page
$scope.moveNoteToTrash = function (noteId) {
- noteActionSrv.moveNoteToTrash(noteId, true)
+ noteActionService.moveNoteToTrash(noteId, true)
}
// Remove the note permanently if it's in the trash
$scope.removeNote = function (noteId) {
- noteActionSrv.removeNote(noteId, true)
+ noteActionService.removeNote(noteId, true)
}
$scope.isTrash = function (note) {
@@ -309,7 +309,7 @@ function NotebookCtrl ($scope, $route, $routeParams, $location, $rootScope,
}
$scope.clearAllParagraphOutput = function (noteId) {
- noteActionSrv.clearAllParagraphOutput(noteId)
+ noteActionService.clearAllParagraphOutput(noteId)
}
$scope.toggleAllEditor = function () {
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/paragraph/clipboard.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/clipboard.controller.js b/zeppelin-web/src/app/notebook/paragraph/clipboard.controller.js
new file mode 100644
index 0000000..0eb78e3
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/paragraph/clipboard.controller.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+angular.module('zeppelinWebApp').controller('clipboardCtrl', ClipboardController)
+
+function ClipboardController ($scope) {
+ 'ngInject'
+
+ $scope.complete = function (e) {
+ $scope.copied = true
+ $scope.tooltip = 'Copied!'
+ setTimeout(function () {
+ $scope.tooltip = 'Copy to clipboard'
+ }, 400)
+ }
+ $scope.$watch('input', function () {
+ $scope.copied = false
+ $scope.tooltip = 'Copy to clipboard'
+ })
+ $scope.clipError = function (e) {
+ console.log('Error: ' + e.name + ' - ' + e.message)
+ $scope.tooltip = 'Not supported browser'
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/paragraph/code-editor/code-editor.directive.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/code-editor/code-editor.directive.html b/zeppelin-web/src/app/notebook/paragraph/code-editor/code-editor.directive.html
new file mode 100644
index 0000000..1c0a1f0
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/paragraph/code-editor/code-editor.directive.html
@@ -0,0 +1,21 @@
+<!--
+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.
+-->
+
+<div class="editor"
+ ui-ace="{ onLoad : onLoad, require : ['ace/ext/language_tools'] }"
+ ng-model="paragraph.text"
+ ng-class="{'paragraph-disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' || revisionView === true,
+ 'paragraph-text--dirty' : dirtyText !== originalText && dirtyText !== undefined}">
+
+</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/paragraph/code-editor/code-editor.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/code-editor/code-editor.directive.js b/zeppelin-web/src/app/notebook/paragraph/code-editor/code-editor.directive.js
new file mode 100644
index 0000000..944f05d
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/paragraph/code-editor/code-editor.directive.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').directive('codeEditor', CodeEditorDirective)
+
+function CodeEditorDirective($templateRequest, $compile) {
+ return {
+ restrict: 'AE',
+ scope: {
+ paragraphId: '=paragraphId',
+ paragraph: '=paragraphContext',
+ dirtyText: '=dirtyText',
+ originalText: '=originalText',
+ onLoad: '=onLoad',
+ revisionView: '=revisionView'
+ },
+ link: function (scope, element, attrs, controller) {
+ $templateRequest('app/notebook/paragraph/code-editor/code-editor.directive.html').then(function (editorHtml) {
+ let editor = angular.element(editorHtml)
+ editor.attr('id', scope.paragraphId + '_editor')
+ element.append(editor)
+ $compile(editor)(scope)
+ console.debug('codeEditor directive revision view is ' + scope.revisionView)
+ })
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterized-query-form.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterized-query-form.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterized-query-form.html
new file mode 100644
index 0000000..249e7c1
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterized-query-form.html
@@ -0,0 +1,71 @@
+<!--
+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.
+-->
+<form id="{{paragraph.id}}_form" role="form"
+ ng-show="!paragraph.config.tableHide"
+ class=" paragraphForm form-horizontal row">
+ <div class="form-group col-sm-6 col-md-6 col-lg-4"
+ ng-repeat="formulaire in paragraph.settings.forms | toArray"
+ ng-init="loadForm(formulaire, paragraph.settings.params)">
+ <label class="control-label input-sm" ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }">{{formulaire.name}}</label>
+ <div>
+ <input class="form-control input-sm"
+ ng-if="paragraph.settings.forms[formulaire.name].type == 'TextBox'"
+ ng-enter="runParagraphFromButton(getEditorValue())"
+ ng-model="paragraph.settings.params[formulaire.name]"
+ ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
+ name="{{formulaire.name}}" />
+ </div>
+ <div ng-if="paragraph.config.runOnSelectionChange == true">
+ <select class="form-control input-sm"
+ ng-if="paragraph.settings.forms[formulaire.name].type == 'Select'"
+ ng-change="runParagraphFromButton(getEditorValue())"
+ ng-model="paragraph.settings.params[formulaire.name]"
+ ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
+ name="{{formulaire.name}}"
+ ng-options="option.value as (option.displayName||option.value) for option in paragraph.settings.forms[formulaire.name].options">
+ </select>
+ </div>
+ <div ng-if="paragraph.config.runOnSelectionChange == false">
+ <select class="form-control input-sm"
+ ng-if="paragraph.settings.forms[formulaire.name].type == 'Select'"
+ ng-enter="runParagraphFromButton(getEditorValue())"
+ ng-model="paragraph.settings.params[formulaire.name]"
+ ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
+ name="{{formulaire.name}}"
+ ng-options="option.value as (option.displayName||option.value) for option in paragraph.settings.forms[formulaire.name].options">
+ </select>
+ </div>
+ <div ng-if="paragraph.config.runOnSelectionChange == true &&
+ paragraph.settings.forms[formulaire.name].type == 'CheckBox'">
+ <label ng-repeat="option in paragraph.settings.forms[formulaire.name].options"
+ class="checkbox-item input-sm">
+ <input type="checkbox"
+ ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
+ ng-checked="paragraph.settings.params[formulaire.name].indexOf(option.value) > -1"
+ ng-click="toggleCheckbox(formulaire, option, false); runParagraphFromButton(getEditorValue())"/> {{option.displayName||option.value}}
+ </label>
+ </div>
+ <div ng-if="paragraph.config.runOnSelectionChange == false &&
+ paragraph.settings.forms[formulaire.name].type == 'CheckBox'">
+ <label ng-repeat="option in paragraph.settings.forms[formulaire.name].options"
+ class="checkbox-item input-sm">
+ <input type="checkbox"
+ ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
+ ng-checked="paragraph.settings.params[formulaire.name].indexOf(option.value) > -1"
+ ng-enter="runParagraphFromButton(getEditorValue())"
+ ng-click="toggleCheckbox(formulaire, option, false)"/> {{option.displayName||option.value}}
+ </label>
+ </div>
+ </div>
+</form>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterizedQueryForm.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterizedQueryForm.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterizedQueryForm.html
deleted file mode 100644
index 249e7c1..0000000
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterizedQueryForm.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<!--
-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.
--->
-<form id="{{paragraph.id}}_form" role="form"
- ng-show="!paragraph.config.tableHide"
- class=" paragraphForm form-horizontal row">
- <div class="form-group col-sm-6 col-md-6 col-lg-4"
- ng-repeat="formulaire in paragraph.settings.forms | toArray"
- ng-init="loadForm(formulaire, paragraph.settings.params)">
- <label class="control-label input-sm" ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }">{{formulaire.name}}</label>
- <div>
- <input class="form-control input-sm"
- ng-if="paragraph.settings.forms[formulaire.name].type == 'TextBox'"
- ng-enter="runParagraphFromButton(getEditorValue())"
- ng-model="paragraph.settings.params[formulaire.name]"
- ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
- name="{{formulaire.name}}" />
- </div>
- <div ng-if="paragraph.config.runOnSelectionChange == true">
- <select class="form-control input-sm"
- ng-if="paragraph.settings.forms[formulaire.name].type == 'Select'"
- ng-change="runParagraphFromButton(getEditorValue())"
- ng-model="paragraph.settings.params[formulaire.name]"
- ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
- name="{{formulaire.name}}"
- ng-options="option.value as (option.displayName||option.value) for option in paragraph.settings.forms[formulaire.name].options">
- </select>
- </div>
- <div ng-if="paragraph.config.runOnSelectionChange == false">
- <select class="form-control input-sm"
- ng-if="paragraph.settings.forms[formulaire.name].type == 'Select'"
- ng-enter="runParagraphFromButton(getEditorValue())"
- ng-model="paragraph.settings.params[formulaire.name]"
- ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
- name="{{formulaire.name}}"
- ng-options="option.value as (option.displayName||option.value) for option in paragraph.settings.forms[formulaire.name].options">
- </select>
- </div>
- <div ng-if="paragraph.config.runOnSelectionChange == true &&
- paragraph.settings.forms[formulaire.name].type == 'CheckBox'">
- <label ng-repeat="option in paragraph.settings.forms[formulaire.name].options"
- class="checkbox-item input-sm">
- <input type="checkbox"
- ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
- ng-checked="paragraph.settings.params[formulaire.name].indexOf(option.value) > -1"
- ng-click="toggleCheckbox(formulaire, option, false); runParagraphFromButton(getEditorValue())"/> {{option.displayName||option.value}}
- </label>
- </div>
- <div ng-if="paragraph.config.runOnSelectionChange == false &&
- paragraph.settings.forms[formulaire.name].type == 'CheckBox'">
- <label ng-repeat="option in paragraph.settings.forms[formulaire.name].options"
- class="checkbox-item input-sm">
- <input type="checkbox"
- ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
- ng-checked="paragraph.settings.params[formulaire.name].indexOf(option.value) > -1"
- ng-enter="runParagraphFromButton(getEditorValue())"
- ng-click="toggleCheckbox(formulaire, option, false)"/> {{option.displayName||option.value}}
- </label>
- </div>
- </div>
-</form>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/paragraph/paragraph-progress-bar.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-progress-bar.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-progress-bar.html
new file mode 100644
index 0000000..b344176
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-progress-bar.html
@@ -0,0 +1,22 @@
+<!--
+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.
+-->
+
+<div id="{{paragraph.id}}_runControl" class="runControl">
+ <div id="{{paragraph.id}}_progress" class="progress" ng-if="paragraph.status=='RUNNING'">
+ <div ng-if="getProgress()>0 && getProgress()<100 && paragraph.status=='RUNNING'"
+ class="progress-bar" role="progressbar" style="width:{{getProgress()}}%;"></div>
+ <div ng-if="(getProgress()<=0 || getProgress()>=100) && (paragraph.status=='RUNNING' )"
+ class="progress-bar progress-bar-striped active" role="progressbar" style="width:100%;"></div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/paragraph/paragraph-progressBar.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-progressBar.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-progressBar.html
deleted file mode 100644
index b344176..0000000
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph-progressBar.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!--
-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.
--->
-
-<div id="{{paragraph.id}}_runControl" class="runControl">
- <div id="{{paragraph.id}}_progress" class="progress" ng-if="paragraph.status=='RUNNING'">
- <div ng-if="getProgress()>0 && getProgress()<100 && paragraph.status=='RUNNING'"
- class="progress-bar" role="progressbar" style="width:{{getProgress()}}%;"></div>
- <div ng-if="(getProgress()<=0 || getProgress()>=100) && (paragraph.status=='RUNNING' )"
- class="progress-bar progress-bar-striped active" role="progressbar" style="width:100%;"></div>
- </div>
-</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
index ef61d08..8f55d1f 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
@@ -30,7 +30,7 @@ angular.module('zeppelinWebApp').controller('ParagraphCtrl', ParagraphCtrl)
function ParagraphCtrl ($scope, $rootScope, $route, $window, $routeParams, $location,
$timeout, $compile, $http, $q, websocketMsgSrv,
- baseUrlSrv, ngToast, saveAsService, noteVarShareService,
+ baseUrlSrv, ngToast, noteVarShareService,
heliumService) {
'ngInject'
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/paragraph/paragraph.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.html b/zeppelin-web/src/app/notebook/paragraph/paragraph.html
index 0de5e64..754a452 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.html
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.html
@@ -47,8 +47,8 @@ limitations under the License.
></code-editor>
</div>
- <div ng-include src="'app/notebook/paragraph/paragraph-progressBar.html'"></div>
- <div ng-include src="'app/notebook/paragraph/paragraph-parameterizedQueryForm.html'"></div>
+ <div ng-include src="'app/notebook/paragraph/paragraph-progress-bar.html'"></div>
+ <div ng-include src="'app/notebook/paragraph/paragraph-parameterized-query-form.html'"></div>
<!-- Rendering -->
<div class="tableDisplay"
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/paragraph/resizable.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/resizable.directive.js b/zeppelin-web/src/app/notebook/paragraph/resizable.directive.js
new file mode 100644
index 0000000..2893cd5
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/paragraph/resizable.directive.js
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').directive('resizable', ResizableDirective)
+
+function ResizableDirective () {
+ let resizableConfig = {
+ autoHide: true,
+ handles: 'se',
+ helper: 'resizable-helper',
+ stop: function () {
+ angular.element(this).css({'width': '100%', 'height': '100%'})
+ }
+ }
+
+ return {
+ restrict: 'A',
+ scope: {
+ callback: '&onResize'
+ },
+ link: function postLink (scope, elem, attrs) {
+ attrs.$observe('resize', function (resize) {
+ let resetResize = function (elem, resize) {
+ let colStep = window.innerWidth / 12
+ elem.off('resizestop')
+ let conf = angular.copy(resizableConfig)
+ if (resize.graphType === 'TABLE' || resize.graphType === 'NETWORK' || resize.graphType === 'TEXT') {
+ conf.grid = [colStep, 10]
+ conf.minHeight = 100
+ } else {
+ conf.grid = [colStep, 10000]
+ conf.minHeight = 0
+ }
+ conf.maxWidth = window.innerWidth
+
+ elem.resizable(conf)
+ elem.on('resizestop', function () {
+ if (scope.callback) {
+ let height = elem.height()
+ if (height < 50) {
+ height = 300
+ }
+ scope.callback({width: Math.ceil(elem.width() / colStep), height: height})
+ }
+ })
+ }
+
+ resize = JSON.parse(resize)
+ if (resize.allowresize === 'true') {
+ resetResize(elem, resize)
+ angular.element(window).resize(function () {
+ resetResize(elem, resize)
+ })
+ }
+ })
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/save-as/browser-detect.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/save-as/browser-detect.service.js b/zeppelin-web/src/app/notebook/save-as/browser-detect.service.js
new file mode 100644
index 0000000..a31e9af
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/save-as/browser-detect.service.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').service('browserDetectService', BrowserDetectService)
+
+function BrowserDetectService () {
+ this.detectIE = function () {
+ let ua = window.navigator.userAgent
+ let msie = ua.indexOf('MSIE ')
+ if (msie > 0) {
+ // IE 10 or older => return version number
+ return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10)
+ }
+ let trident = ua.indexOf('Trident/')
+ if (trident > 0) {
+ // IE 11 => return version number
+ let rv = ua.indexOf('rv:')
+ return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10)
+ }
+ let edge = ua.indexOf('Edge/')
+ if (edge > 0) {
+ // IE 12 (aka Edge) => return version number
+ return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10)
+ }
+ // other browser
+ return false
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/save-as/save-as.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/save-as/save-as.service.js b/zeppelin-web/src/app/notebook/save-as/save-as.service.js
new file mode 100644
index 0000000..c71c0f7
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/save-as/save-as.service.js
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').service('saveAsService', SaveAsService)
+
+function SaveAsService (browserDetectService) {
+ 'ngInject'
+
+ this.saveAs = function (content, filename, extension) {
+ let BOM = '\uFEFF'
+ if (browserDetectService.detectIE()) {
+ angular.element('body').append('<iframe id="SaveAsId" style="display: none"></iframe>')
+ let frameSaveAs = angular.element('body > iframe#SaveAsId')[0].contentWindow
+ content = BOM + content
+ frameSaveAs.document.open('text/json', 'replace')
+ frameSaveAs.document.write(content)
+ frameSaveAs.document.close()
+ frameSaveAs.focus()
+ let t1 = Date.now()
+ frameSaveAs.document.execCommand('SaveAs', false, filename + '.' + extension)
+ let t2 = Date.now()
+
+ // This means, this version of IE dosen't support auto download of a file with extension provided in param
+ // falling back to ".txt"
+ if (t1 === t2) {
+ frameSaveAs.document.execCommand('SaveAs', true, filename + '.txt')
+ }
+ angular.element('body > iframe#SaveAsId').remove()
+ } else {
+ content = 'data:image/svg;charset=utf-8,' + BOM + encodeURIComponent(content)
+ angular.element('body').append('<a id="SaveAsId"></a>')
+ let saveAsElement = angular.element('body > a#SaveAsId')
+ saveAsElement.attr('href', content)
+ saveAsElement.attr('download', filename + '.' + extension)
+ saveAsElement.attr('target', '_blank')
+ saveAsElement[0].click()
+ saveAsElement.remove()
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebook/shortcut.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/shortcut.html b/zeppelin-web/src/app/notebook/shortcut.html
new file mode 100644
index 0000000..775da4f
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/shortcut.html
@@ -0,0 +1,312 @@
+<!--
+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.
+-->
+
+<div class="modal fade" id="shortcutModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="shortcut-modal-header">
+ <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
+ <h4 class="shortcut-modal-title" id="myModalLabel">Keyboard shortcuts</h4>
+ </div>
+ <div class="table-scroll">
+ <table class="table table-shortcut">
+ <tr>
+ <th style="width:70%">Note Keyboard Shortcuts</th>
+ <th></th>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Run paragraph</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Shift</kbd> + <kbd class="kbd-default">Enter</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Cancel</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">C</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Move cursor Up</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">P</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Move cursor Down</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">N</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Remove paragraph</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">D</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Insert new paragraph above</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">A</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Insert new paragraph below</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">B</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Insert copy of paragraph below</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">Shift</kbd> + <kbd class="kbd-default">C</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Move paragraph Up</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">K</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Move paragraph Down</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">J</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Enable/Disable run paragraph</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt' }}</kbd> + <kbd class="kbd-default">R</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Toggle output</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">O</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Toggle editor</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">E</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Toggle line number</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">M</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Toggle title</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">T</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Clear output</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">L</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Link this paragraph</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">{{ isMac ? 'Option' : 'Alt'}}</kbd> + <kbd class="kbd-default">W</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Reduce paragraph width</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">Shift</kbd> + <kbd class="kbd-default">-</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Increase paragraph width</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">Shift</kbd> + <kbd class="kbd-default">+</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr class="sub-title">
+ <th style="width:70%">Editor Keyboard Shortcuts</th>
+ <th></th>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Auto-completion</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">.</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Cut the line</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">K</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Paste the line</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">Y</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Search inside the code</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">S</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Move cursor to the beginning</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">A</kbd>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <div class="col-md-8">Move cursor at the end</div>
+ </td>
+ <td>
+ <div class="keys">
+ <kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">E</kbd>
+ </div>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/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
deleted file mode 100644
index 9ae12e4..0000000
--- a/zeppelin-web/src/app/notebookRepos/notebookRepos.controller.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').controller('NotebookReposCtrl', NotebookReposCtrl)
-
-function NotebookReposCtrl ($http, baseUrlSrv, ngToast) {
- 'ngInject'
-
- let vm = this
- vm.notebookRepos = []
- vm.showDropdownSelected = showDropdownSelected
- vm.saveNotebookRepo = saveNotebookRepo
-
- _init()
-
- // Public functions
-
- function saveNotebookRepo (valueform, repo, data) {
- console.log('data %o', data)
- $http.put(baseUrlSrv.getRestApiBase() + '/notebook-repositories', {
- 'name': repo.className,
- 'settings': data
- }).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)
- }
- valueform.$show()
- }).error(function () {
- ngToast.danger({
- content: 'We couldn\'t save that NotebookRepo\'s settings',
- verticalPosition: 'bottom',
- timeout: '3000'
- })
- valueform.$show()
- })
-
- return 'manual'
- }
-
- function showDropdownSelected (setting) {
- let index = _.findIndex(setting.value, {'value': setting.selected})
- if (index < 0) {
- return 'No value'
- } else {
- return setting.value[index].name
- }
- }
-
- // Private functions
-
- 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 = baseUrlSrv.getBase()
- }, 3000)
- }
- console.log('Error %o %o', status, data.message)
- })
- }
-
- function _init () {
- _getInterpreterSettings()
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/notebookRepos/notebookRepos.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebookRepos/notebookRepos.html b/zeppelin-web/src/app/notebookRepos/notebookRepos.html
deleted file mode 100644
index 65ca372..0000000
--- a/zeppelin-web/src/app/notebookRepos/notebookRepos.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!--
-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.
--->
-<div class="interpreterHead">
- <div class="header">
- <div class="row">
- <div class="col-md-12">
- <h3 class="new_h3">
- Notebook Repos
- </h3>
- </div>
- </div>
- <div class="row">
- <div class="col-md-12">
- Manage your Notebook Repositories' settings.
- </div>
- </div>
- </div>
-</div>
-
-<div class="box width-full"
- ng-repeat="repo in noterepo.notebookRepos | orderBy: 'name'">
- <div id="{{repo.name | lowercase}}">
- <div class="row interpreter">
-
- <div class="col-md-12">
- <h3 class="interpreter-title">{{repo.name}}</h3>
- <span style="float:right" ng-show="repo.settings.length > 0">
- <button class="btn btn-default btn-xs"
- ng-click="valueform.$show();">
- <span class="fa fa-pencil"></span> edit</button>
- </span>
- </div>
- </div>
- <div class="row interpreter">
- <div class="col-md-12" ng-show="repo.settings.length > 0">
- <h5>Settings</h5>
- <table class="table table-striped">
- <thead>
- <tr>
- <th style="width:40%">name</th>
- <th style="width:60%">value</th>
- </tr>
- </thead>
- <tr ng-repeat="setting in repo.settings" >
- <td ng-bind="setting.name"></td>
- <td>
- <span class="btn-group">
- <span ng-show="setting.type === 'DROPDOWN'">
- <span editable-select="setting.selected"
- e-name="{{setting.name}}"
- e-ng-options="s.value as s.name for s in setting.value"
- class="selectpicker" ng-disabled="!valueform.$visible" e-form="valueform">
- {{noterepo.showDropdownSelected(setting)}}
- </span>
- </span>
- <span ng-show="setting.type === 'INPUT'">
- <span editable-textarea="setting.selected" e-name="{{setting.name}}" e-form="valueform" e-msd-elastic e-cols="100">
- {{setting.selected | breakFilter}}
- </span>
- </span>
- </span>
- </td>
- </tr>
- </table>
- </div>
- </div>
- <span style="float:right" ng-show="valueform.$visible">
- <form editable-form name="valueform"
- onbeforesave="noterepo.saveNotebookRepo(valueform, repo, $data)"
- ng-show="valueform.$visible">
- <button type="submit" class="btn btn-primary btn-xs">
- <span class="fa fa-check"></span> Save
- </button>
- <button type="button" class="btn btn-default btn-xs"
- ng-disabled="valueform.$waiting"
- ng-click="valueform.$cancel();">
- <span class="fa fa-remove"></span> Cancel
- </button>
- </form>
- </span>
- <div class="row interpreter">
- <div ng-show="repo.settings.length === 0 || valueform.$hidden" class="col-md-12 gray40-message">
- <em>Currently there are no settings for this Notebook Repository</em>
- </div>
- </div>
- </div>
-</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/search/search.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/search/search.service.js b/zeppelin-web/src/app/search/search.service.js
new file mode 100644
index 0000000..fe4b666
--- /dev/null
+++ b/zeppelin-web/src/app/search/search.service.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').service('searchService', SearchService)
+
+function SearchService ($resource, baseUrlSrv) {
+ 'ngInject'
+
+ this.search = function (term) {
+ this.searchTerm = term.q
+ console.log('Searching for: %o', term.q)
+ if (!term.q) { // TODO(bzz): empty string check
+ return
+ }
+ let encQuery = window.encodeURIComponent(term.q)
+ return $resource(baseUrlSrv.getRestApiBase() + '/notebook/search?q=' + encQuery, {}, {
+ query: {method: 'GET'}
+ })
+ }
+
+ this.searchTerm = ''
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/array-ordering/array-ordering.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/array-ordering/array-ordering.service.js b/zeppelin-web/src/components/array-ordering/array-ordering.service.js
new file mode 100644
index 0000000..850a5da
--- /dev/null
+++ b/zeppelin-web/src/components/array-ordering/array-ordering.service.js
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').service('arrayOrderingSrv', ArrayOrderingService)
+
+function ArrayOrderingService(TRASH_FOLDER_ID) {
+ 'ngInject'
+
+ let arrayOrderingSrv = this
+
+ this.noteListOrdering = function (note) {
+ if (note.id === TRASH_FOLDER_ID) {
+ return '\uFFFF'
+ }
+ return arrayOrderingSrv.getNoteName(note)
+ }
+
+ this.getNoteName = function (note) {
+ if (note.name === undefined || note.name.trim() === '') {
+ return 'Note ' + note.id
+ } else {
+ return note.name
+ }
+ }
+
+ this.noteComparator = function (v1, v2) {
+ let note1 = v1.value
+ let note2 = v2.value
+
+ if (note1.id === TRASH_FOLDER_ID) {
+ return 1
+ }
+
+ if (note2.id === TRASH_FOLDER_ID) {
+ return -1
+ }
+
+ if (note1.children === undefined && note2.children !== undefined) {
+ return 1
+ }
+
+ if (note1.children !== undefined && note2.children === undefined) {
+ return -1
+ }
+
+ let noteName1 = arrayOrderingSrv.getNoteName(note1)
+ let noteName2 = arrayOrderingSrv.getNoteName(note2)
+
+ return noteName1.localeCompare(noteName2)
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/arrayOrderingSrv/arrayOrdering.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/arrayOrderingSrv/arrayOrdering.service.js b/zeppelin-web/src/components/arrayOrderingSrv/arrayOrdering.service.js
deleted file mode 100644
index ead2824..0000000
--- a/zeppelin-web/src/components/arrayOrderingSrv/arrayOrdering.service.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').service('arrayOrderingSrv', arrayOrderingSrv)
-
-function arrayOrderingSrv (TRASH_FOLDER_ID) {
- 'ngInject'
-
- let arrayOrderingSrv = this
-
- this.noteListOrdering = function (note) {
- if (note.id === TRASH_FOLDER_ID) {
- return '\uFFFF'
- }
- return arrayOrderingSrv.getNoteName(note)
- }
-
- this.getNoteName = function (note) {
- if (note.name === undefined || note.name.trim() === '') {
- return 'Note ' + note.id
- } else {
- return note.name
- }
- }
-
- this.noteComparator = function (v1, v2) {
- let note1 = v1.value
- let note2 = v2.value
-
- if (note1.id === TRASH_FOLDER_ID) {
- return 1
- }
-
- if (note2.id === TRASH_FOLDER_ID) {
- return -1
- }
-
- if (note1.children === undefined && note2.children !== undefined) {
- return 1
- }
-
- if (note1.children !== undefined && note2.children === undefined) {
- return -1
- }
-
- let noteName1 = arrayOrderingSrv.getNoteName(note1)
- let noteName2 = arrayOrderingSrv.getNoteName(note2)
-
- return noteName1.localeCompare(noteName2)
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/base-url/base-url.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/base-url/base-url.service.js b/zeppelin-web/src/components/base-url/base-url.service.js
new file mode 100644
index 0000000..6ef55b9
--- /dev/null
+++ b/zeppelin-web/src/components/base-url/base-url.service.js
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').service('baseUrlSrv', BaseUrlService)
+
+function BaseUrlService() {
+ this.getPort = function () {
+ let port = Number(location.port)
+ if (!port) {
+ port = 80
+ if (location.protocol === 'https:') {
+ port = 443
+ }
+ }
+ // Exception for when running locally via grunt
+ if (port === process.env.WEB_PORT) {
+ port = process.env.SERVER_PORT
+ }
+ return port
+ }
+
+ this.getWebsocketUrl = function () {
+ let wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:'
+ return wsProtocol + '//' + location.hostname + ':' + this.getPort() +
+ skipTrailingSlash(location.pathname) + '/ws'
+ }
+
+ this.getBase = function() {
+ return location.protocol + '//' + location.hostname + ':' + this.getPort() + location.pathname
+ }
+
+ this.getRestApiBase = function () {
+ return skipTrailingSlash(this.getBase()) + '/api'
+ }
+
+ const skipTrailingSlash = function (path) {
+ return path.replace(/\/$/, '')
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/baseUrl/baseUrl.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/baseUrl/baseUrl.service.js b/zeppelin-web/src/components/baseUrl/baseUrl.service.js
deleted file mode 100644
index 5b8824a..0000000
--- a/zeppelin-web/src/components/baseUrl/baseUrl.service.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').service('baseUrlSrv', baseUrlSrv)
-
-function baseUrlSrv () {
- this.getPort = function () {
- let port = Number(location.port)
- if (!port) {
- port = 80
- if (location.protocol === 'https:') {
- port = 443
- }
- }
- // Exception for when running locally via grunt
- if (port === process.env.WEB_PORT) {
- port = process.env.SERVER_PORT
- }
- return port
- }
-
- this.getWebsocketUrl = function () {
- let wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:'
- return wsProtocol + '//' + location.hostname + ':' + this.getPort() +
- skipTrailingSlash(location.pathname) + '/ws'
- }
-
- this.getBase = function() {
- return location.protocol + '//' + location.hostname + ':' + this.getPort() + location.pathname
- }
-
- this.getRestApiBase = function () {
- return skipTrailingSlash(this.getBase()) + '/api'
- }
-
- const skipTrailingSlash = function (path) {
- return path.replace(/\/$/, '')
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/browser-detect/browserDetect.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/browser-detect/browserDetect.service.js b/zeppelin-web/src/components/browser-detect/browserDetect.service.js
deleted file mode 100644
index 2223d5f..0000000
--- a/zeppelin-web/src/components/browser-detect/browserDetect.service.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').service('browserDetectService', browserDetectService)
-
-function browserDetectService () {
- this.detectIE = function () {
- let ua = window.navigator.userAgent
- let msie = ua.indexOf('MSIE ')
- if (msie > 0) {
- // IE 10 or older => return version number
- return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10)
- }
- let trident = ua.indexOf('Trident/')
- if (trident > 0) {
- // IE 11 => return version number
- let rv = ua.indexOf('rv:')
- return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10)
- }
- let edge = ua.indexOf('Edge/')
- if (edge > 0) {
- // IE 12 (aka Edge) => return version number
- return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10)
- }
- // other browser
- return false
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/clipboard/clipboard.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/clipboard/clipboard.controller.js b/zeppelin-web/src/components/clipboard/clipboard.controller.js
deleted file mode 100644
index c4a9e42..0000000
--- a/zeppelin-web/src/components/clipboard/clipboard.controller.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.
- */
-angular.module('zeppelinWebApp').controller('clipboardCtrl', clipboardCtrl)
-
-function clipboardCtrl ($scope) {
- 'ngInject'
-
- $scope.complete = function (e) {
- $scope.copied = true
- $scope.tooltip = 'Copied!'
- setTimeout(function () {
- $scope.tooltip = 'Copy to clipboard'
- }, 400)
- }
- $scope.$watch('input', function () {
- $scope.copied = false
- $scope.tooltip = 'Copy to clipboard'
- })
- $scope.clipError = function (e) {
- console.log('Error: ' + e.name + ' - ' + e.message)
- $scope.tooltip = 'Not supported browser'
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/dropdowninput/dropdowninput.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/dropdowninput/dropdowninput.directive.js b/zeppelin-web/src/components/dropdowninput/dropdowninput.directive.js
deleted file mode 100644
index cdc74f3..0000000
--- a/zeppelin-web/src/components/dropdowninput/dropdowninput.directive.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').directive('dropdownInput', dropdownInput)
-
-function dropdownInput () {
- return {
- restrict: 'A',
- link: function (scope, element) {
- element.bind('click', function (event) {
- event.stopPropagation()
- })
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/editor/ace.editor.directive.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/editor/ace.editor.directive.html b/zeppelin-web/src/components/editor/ace.editor.directive.html
deleted file mode 100644
index 1c0a1f0..0000000
--- a/zeppelin-web/src/components/editor/ace.editor.directive.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-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.
--->
-
-<div class="editor"
- ui-ace="{ onLoad : onLoad, require : ['ace/ext/language_tools'] }"
- ng-model="paragraph.text"
- ng-class="{'paragraph-disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' || revisionView === true,
- 'paragraph-text--dirty' : dirtyText !== originalText && dirtyText !== undefined}">
-
-</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/components/editor/codeEditor.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/editor/codeEditor.directive.js b/zeppelin-web/src/components/editor/codeEditor.directive.js
deleted file mode 100644
index d8cb73f..0000000
--- a/zeppelin-web/src/components/editor/codeEditor.directive.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.
- */
-
-angular.module('zeppelinWebApp').directive('codeEditor', codeEditor)
-
-function codeEditor ($templateRequest, $compile) {
- return {
- restrict: 'AE',
- scope: {
- paragraphId: '=paragraphId',
- paragraph: '=paragraphContext',
- dirtyText: '=dirtyText',
- originalText: '=originalText',
- onLoad: '=onLoad',
- revisionView: '=revisionView'
- },
- link: function (scope, element, attrs, controller) {
- $templateRequest('components/editor/ace.editor.directive.html').then(function (editorHtml) {
- let editor = angular.element(editorHtml)
- editor.attr('id', scope.paragraphId + '_editor')
- element.append(editor)
- $compile(editor)(scope)
- console.debug('codeEditor directive revision view is ' + scope.revisionView)
- })
- }
- }
-}
[5/5] zeppelin git commit: [ZEPPELIN-2749] Use scalable file
structure for zeppelin web
Posted by ku...@apache.org.
[ZEPPELIN-2749] Use scalable file structure for zeppelin web
### What is this PR for?
We have improved zeppelin-web, but some parts are still messy. As part of keeping zeppelin-web module healthy ([ZEPPELIN-2725](https://issues.apache.org/jira/browse/ZEPPELIN-2725)), I suggest having these file structure. (Refer the screenshot section)
Here are few reasons.
- unified directory, file name helps us to recognize, find which part we should modify / fix
* Let's say we need to modify the resize feature of paragraph, where the developer can find it? currently, it's under `component/resizable` not under `paragraph/resizeable` and also it's not the shareable component. There is no reason to keep that files in `component/**`
- [this structure](https://github.com/toddmotto/angularjs-styleguide#file-naming-conventions) is what the angularjs community has verified for few years. so newly joined developers can feel more comfortable.
- this is necessary for [Modular archiecture](https://issues.apache.org/jira/browse/ZEPPELIN-2750) and it eventually helps us to make a smooth transition toward next technologies (even whatever we will use)
Additionally,
- This is not the meaningless refactoring PR and doesn't block developing new features / fixes (Please refer the `Some Details` section)
- I will handle conflicts for few days would be brought by other WIPs
For your information,
- https://github.com/toddmotto/angularjs-styleguide#file-naming-conventions
- https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#naming
#### How to Review This PR?
Please follow the commits. I modified submodules by splitting commits. Thus commit message includes what has been done in that PR. For example,
![image](https://user-images.githubusercontent.com/4968473/27993114-d8ac45e6-64dd-11e7-8130-f3fa887054a1.png)
#### Some Details
- Didn't change the widely used variable names not to make many conflicts. For example, `websocketMsgSrv`, `arrayOrderingSrv`
- Since there are helium packages already published, didn't change the HTML file names like `pivot_setting.html` (it's better to use `pivot-setting.html` if we following the rule)
### What type of PR is it?
[Improvement | Refactoring]
### Todos
Please refer the commit message.
### What is the Jira issue?
[ZEPPELIN-2749](https://issues.apache.org/jira/browse/ZEPPELIN-2749)
### How should this be tested?
**All functionalities must work** as like before, CI will test it.
### Screenshots (if appropriate)
#### Before: messy, mixed directory structure
![image](https://user-images.githubusercontent.com/4968473/27993126-0a94aca6-64de-11e7-93db-548b6fcc6913.png)
#### After: only the shared components will be placed under `components/`
![image](https://user-images.githubusercontent.com/4968473/27993118-ee1bd2d4-64dd-11e7-95b6-f71dc628a94e.png)
### Questions:
* Does the licenses files need update? - NO
* Is there breaking changes for older versions? - NO
* Does this needs documentation? - NO
Author: 1ambda <1a...@gmail.com>
Closes #2472 from 1ambda/ZEPPELIN-2749/use-scalable-file-structure-for-zeppelin-web and squashes the following commits:
22e6bf95 [1ambda] fix: AuthenticationIT, InterpreterModeActionsIT
e31f0bc8 [1ambda] fix: AbstractZeppelinIT
102e5443 [1ambda] paragraph-parameterized-query-form: Rename
74e0af41 [1ambda] paragraph-progress-bar: Rename
0029d6b7 [1ambda] job-progress-bar: Rename
af420a41 [1ambda] helium: Move helium related files into app/helium
285a6462 [1ambda] notebook-repository: Rename injected ctrl name
147572f1 [1ambda] notebook-repository: Rename files, funcs
4f66b642 [1ambda] ng-*: Rename files, funcs
f25d981e [1ambda] interpreter: Move interpreter specific directives into interpreter/
4a0602f7 [1ambda] array-ordering: Rename files
1e4ba709 [1ambda] code-editor: Move paragraph specific directive into paragraph/code-editor
31dcf6a3 [1ambda] base-url: Rename file
1afb2d03 [1ambda] note-name-filter: Rename files
ec046683 [1ambda] dropdown-input: Move notebook specific directive into notebook/dropdown-input
81fa2d44 [1ambda] elastic-input: Move notebook specific ctrl into notebook/elastic-input
657d0638 [1ambda] note-rename: Add prefix note-
47ac45d1 [1ambda] expand-collapse: Move navbar specific directive into navbar/
8bc78124 [1ambda] login: Remove invalid attr in login
b2bf91b0 [1ambda] note-import: Rename to noteImportCtrl
07b1f3ff [1ambda] note-create: Rename to noteCreateModal
568149ed [1ambda] note-create: Rename injected controller
c3402449 [1ambda] note-create: Rename files
e17c7ee7 [1ambda] note-create: Remove useless dialog postfix
b0a36a7e [1ambda] note-import: Remove meaningless postfix dialog
abf6869d [1ambda] note-import: Rename files
a40ea23c [1ambda] search: Move search specific service into serach/
7a094841 [1ambda] browser-detect: move save-as specific service into save-as/
40f62e3c [1ambda] rename: Modify injected service name
e993133a [1ambda] rename: Rename funcs
1f950943 [1ambda] note-action: Rename injected service name
d3da2d45 [1ambda] note-action: Rename files, funcs
b9f3c178 [1ambda] note-list-elem: Rename
d3132e9a [1ambda] note-list: Remove useless middle word Data
b5dff142 [1ambda] resizable: Move para specific directive into paragraph/
bfcd6b85 [1ambda] resizable: Rename funcs
40643997 [1ambda] fix: Remove useless postfix and rename files, funcs
0611aff5 [1ambda] websocket: Rename funcs
a2527530 [1ambda] fix: Remove meaningless postfix from searchService
c21a1237 [1ambda] move: paragraph specific ctrl into paragraph/
ad99c04b [1ambda] move: note specific dialog into notebook/
701f4432 [1ambda] move: note specific service into notebook/
3f02c503 [1ambda] fix: Remove unused saveAsService from paragraph ctrl
d7d7434a [1ambda] move: note specific service saveAsService into notebook/
4e7f6d9c [1ambda] fix: Move repository-create into interpreter/
a9a6368a [1ambda] fix: remove useless dir interpreter-create
c1c210de [1ambda] rename: repository-dialog -> repository-create
Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/6bd6c708
Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/6bd6c708
Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/6bd6c708
Branch: refs/heads/master
Commit: 6bd6c70881e8515a5b0679e5a8d6c235cfb1adf6
Parents: ebb6591
Author: 1ambda <1a...@gmail.com>
Authored: Mon Jul 10 15:52:37 2017 +0900
Committer: 1ambda <1a...@gmail.com>
Committed: Sat Jul 15 01:06:54 2017 +0900
----------------------------------------------------------------------
.../org/apache/zeppelin/AbstractZeppelinIT.java | 2 +-
.../zeppelin/integration/AuthenticationIT.java | 2 +-
.../integration/InterpreterModeActionsIT.java | 2 +-
zeppelin-web/src/app/app.js | 4 +-
zeppelin-web/src/app/helium/helium-conf.js | 99 +++++
zeppelin-web/src/app/helium/helium-package.js | 47 +++
zeppelin-web/src/app/helium/helium-type.js | 20 +
zeppelin-web/src/app/helium/helium.config.js | 101 -----
.../src/app/helium/helium.controller.js | 2 +-
zeppelin-web/src/app/helium/helium.service.js | 301 +++++++++++++++
zeppelin-web/src/app/home/home.controller.js | 25 +-
zeppelin-web/src/app/home/home.html | 4 +-
.../src/app/home/notebook-template.html | 4 +-
zeppelin-web/src/app/home/notebook.html | 4 +-
.../src/app/interpreter/interpreter-create.html | 383 +++++++++++++++++++
.../interpreter-create/interpreter-create.html | 383 -------------------
.../interpreter/interpreter-item.directive.js | 31 ++
.../src/app/interpreter/interpreter.html | 10 +-
.../src/app/interpreter/repository-create.html | 115 ++++++
.../widget/number-widget.directive.js | 31 ++
.../app/jobmanager/jobs/job-progress-bar.html | 22 ++
.../app/jobmanager/jobs/job-progressBar.html | 22 --
zeppelin-web/src/app/jobmanager/jobs/job.html | 2 +-
.../notebook-repository.controller.js | 87 +++++
.../notebook-repository.html | 98 +++++
.../dropdown-input/dropdown-input.directive.js | 26 ++
.../elastic-input/elastic-input.controller.js | 21 +
.../src/app/notebook/note-var-share.service.js | 39 ++
.../src/app/notebook/notebook-actionBar.html | 2 +-
.../src/app/notebook/notebook.controller.js | 8 +-
.../notebook/paragraph/clipboard.controller.js | 34 ++
.../code-editor/code-editor.directive.html | 21 +
.../code-editor/code-editor.directive.js | 38 ++
.../paragraph-parameterized-query-form.html | 71 ++++
.../paragraph-parameterizedQueryForm.html | 71 ----
.../paragraph/paragraph-progress-bar.html | 22 ++
.../paragraph/paragraph-progressBar.html | 22 --
.../notebook/paragraph/paragraph.controller.js | 2 +-
.../src/app/notebook/paragraph/paragraph.html | 4 +-
.../notebook/paragraph/resizable.directive.js | 69 ++++
.../notebook/save-as/browser-detect.service.js | 39 ++
.../src/app/notebook/save-as/save-as.service.js | 51 +++
zeppelin-web/src/app/notebook/shortcut.html | 312 +++++++++++++++
.../notebookRepos/notebookRepos.controller.js | 87 -----
.../src/app/notebookRepos/notebookRepos.html | 98 -----
zeppelin-web/src/app/search/search.service.js | 33 ++
.../array-ordering/array-ordering.service.js | 62 +++
.../arrayOrderingSrv/arrayOrdering.service.js | 62 ---
.../src/components/base-url/base-url.service.js | 50 +++
.../src/components/baseUrl/baseUrl.service.js | 50 ---
.../browser-detect/browserDetect.service.js | 39 --
.../clipboard/clipboard.controller.js | 34 --
.../dropdowninput/dropdowninput.directive.js | 26 --
.../components/editor/ace.editor.directive.html | 21 -
.../components/editor/codeEditor.directive.js | 38 --
.../elasticInputCtrl/elasticInput.controller.js | 21 -
.../expandCollapse/expandCollapse.css | 17 -
.../expandCollapse/expandCollapse.directive.js | 46 ---
.../filterNoteNames/filter-note-names.html | 19 -
.../src/components/helium/helium-conf.js | 99 -----
.../src/components/helium/helium-package.js | 47 ---
.../src/components/helium/helium-type.js | 20 -
.../src/components/helium/helium.service.js | 301 ---------------
.../interpreter/interpreter.directive.js | 31 --
.../widget/widget.number.directive.js | 31 --
zeppelin-web/src/components/login/login.html | 2 +-
.../modal-shortcut/modal-shortcut.html | 312 ---------------
.../navbar/expand-collapse/expand-collapse.css | 17 +
.../expand-collapse.directive.js | 48 +++
.../navbar/navbar-note-list-elem.html | 50 +++
.../components/navbar/navbar-noteList-elem.html | 50 ---
.../src/components/navbar/navbar.controller.js | 6 +-
zeppelin-web/src/components/navbar/navbar.html | 10 +-
.../components/ng-enter/ng-enter.directive.js | 30 ++
.../ng-enter/ng-enter.directive.test.js | 24 ++
.../components/ng-escape/ng-escape.directive.js | 28 ++
.../src/components/ngenter/ngenter.directive.js | 30 --
.../ngenter/ngenter.directive.test.js | 24 --
.../components/ngescape/ngescape.directive.js | 28 --
.../note-action/note-action.service.js | 183 +++++++++
.../note-create/note-create.controller.js | 106 +++++
.../note-create/note-create.controller.test.js | 39 ++
.../src/components/note-create/note-create.css | 49 +++
.../src/components/note-create/note-create.html | 66 ++++
.../components/note-create/visible.directive.js | 45 +++
.../note-import/note-import.controller.js | 138 +++++++
.../src/components/note-import/note-import.css | 91 +++++
.../src/components/note-import/note-import.html | 80 ++++
.../components/note-list/note-list.factory.js | 81 ++++
.../note-list/note-list.factory.test.js | 75 ++++
.../note-name-filter/note-name-filter.html | 19 +
.../note-rename/note-rename.controller.js | 48 +++
.../src/components/note-rename/note-rename.css | 38 ++
.../src/components/note-rename/note-rename.html | 43 +++
.../note-rename/note-rename.service.js | 32 ++
.../components/noteAction/noteAction.service.js | 183 ---------
.../noteListDataFactory/noteList.datafactory.js | 81 ----
.../noteList.datafactory.test.js | 75 ----
.../noteName-create/note-name-dialog.css | 49 ---
.../noteName-create/note-name-dialog.html | 66 ----
.../noteName-create/notename.controller.js | 106 -----
.../noteName-create/notename.controller.test.js | 39 --
.../noteName-create/visible.directive.js | 45 ---
.../noteName-import/note-import-dialog.css | 91 -----
.../noteName-import/note-import-dialog.html | 80 ----
.../notenameImport.controller.js | 138 -------
.../notevarshareService/notevarshare.service.js | 39 --
.../src/components/rename/rename.controller.js | 48 ---
zeppelin-web/src/components/rename/rename.css | 38 --
zeppelin-web/src/components/rename/rename.html | 43 ---
.../src/components/rename/rename.service.js | 32 --
.../repository-create/repository-dialog.html | 115 ------
.../components/resizable/resizable.directive.js | 69 ----
.../src/components/saveAs/saveAs.service.js | 51 ---
.../components/searchService/search.service.js | 33 --
.../websocket/websocket-event.factory.js | 196 ++++++++++
.../websocket/websocket-message.service.js | 343 +++++++++++++++++
.../websocketEvents/websocketEvents.factory.js | 196 ----------
.../websocketEvents/websocketMsg.service.js | 343 -----------------
zeppelin-web/src/index.html | 19 +-
zeppelin-web/src/index.js | 54 +--
121 files changed, 4075 insertions(+), 4174 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java
index e16bf1a..475be50 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java
@@ -107,7 +107,7 @@ abstract public class AbstractZeppelinIT {
" note')]"));
WebDriverWait block = new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC);
- block.until(ExpectedConditions.visibilityOfElementLocated(By.id("noteNameModal")));
+ block.until(ExpectedConditions.visibilityOfElementLocated(By.id("noteCreateModal")));
clickAndWait(By.id("createNoteButton"));
block.until(ExpectedConditions.invisibilityOfElementLocated(By.className("pull-right")));
}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-server/src/test/java/org/apache/zeppelin/integration/AuthenticationIT.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/AuthenticationIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/AuthenticationIT.java
index 523b8f8..f87bff2 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/AuthenticationIT.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/AuthenticationIT.java
@@ -125,7 +125,7 @@ public class AuthenticationIT extends AbstractZeppelinIT {
ZeppelinITUtils.sleep(1000, false);
pollingWait(By.xpath("//*[@id='userName']"), MAX_BROWSER_TIMEOUT_SEC).sendKeys(userName);
pollingWait(By.xpath("//*[@id='password']"), MAX_BROWSER_TIMEOUT_SEC).sendKeys(password);
- pollingWait(By.xpath("//*[@id='NoteImportCtrl']//button[contains(.,'Login')]"),
+ pollingWait(By.xpath("//*[@id='loginModalContent']//button[contains(.,'Login')]"),
MAX_BROWSER_TIMEOUT_SEC).click();
ZeppelinITUtils.sleep(1000, false);
}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-server/src/test/java/org/apache/zeppelin/integration/InterpreterModeActionsIT.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/InterpreterModeActionsIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/InterpreterModeActionsIT.java
index 212b04b..9bfeae0 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/InterpreterModeActionsIT.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/InterpreterModeActionsIT.java
@@ -139,7 +139,7 @@ public class InterpreterModeActionsIT extends AbstractZeppelinIT {
ZeppelinITUtils.sleep(500, false);
pollingWait(By.xpath("//*[@id='userName']"), MAX_BROWSER_TIMEOUT_SEC).sendKeys(userName);
pollingWait(By.xpath("//*[@id='password']"), MAX_BROWSER_TIMEOUT_SEC).sendKeys(password);
- pollingWait(By.xpath("//*[@id='NoteImportCtrl']//button[contains(.,'Login')]"),
+ pollingWait(By.xpath("//*[@id='loginModalContent']//button[contains(.,'Login')]"),
MAX_BROWSER_TIMEOUT_SEC).click();
ZeppelinITUtils.sleep(1000, false);
}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/app.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/app.js b/zeppelin-web/src/app/app.js
index f645d3b..9878d56 100644
--- a/zeppelin-web/src/app/app.js
+++ b/zeppelin-web/src/app/app.js
@@ -113,8 +113,8 @@ let zeppelinWebApp = angular.module('zeppelinWebApp', requiredModules)
controller: 'InterpreterCtrl'
})
.when('/notebookRepos', {
- templateUrl: 'app/notebookRepos/notebookRepos.html',
- controller: 'NotebookReposCtrl',
+ templateUrl: 'app/notebook-repository/notebook-repository.html',
+ controller: 'NotebookRepositoryCtrl',
controllerAs: 'noterepo'
})
.when('/credential', {
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/helium/helium-conf.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/helium/helium-conf.js b/zeppelin-web/src/app/helium/helium-conf.js
new file mode 100644
index 0000000..10ca18a
--- /dev/null
+++ b/zeppelin-web/src/app/helium/helium-conf.js
@@ -0,0 +1,99 @@
+/*
+ * 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 createAllPackageConfigs (defaultPackages, persistedConfs) {
+ let packageConfs = {}
+
+ for (let name in defaultPackages) {
+ const pkgSearchResult = defaultPackages[name]
+
+ const spec = pkgSearchResult.pkg.config
+ if (!spec) { continue }
+
+ const artifact = pkgSearchResult.pkg.artifact
+ if (!artifact) { continue }
+
+ let persistedConf = {}
+ if (persistedConfs[artifact]) {
+ persistedConf = persistedConfs[artifact]
+ }
+
+ 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 (currentConfs) {
+ const filtered = currentConfs.reduce((acc, c) => {
+ acc[c.name] = parseConfigValue(c.type, c.value)
+ return acc
+ }, {})
+
+ return filtered
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/helium/helium-package.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/helium/helium-package.js b/zeppelin-web/src/app/helium/helium-package.js
new file mode 100644
index 0000000..88d191a
--- /dev/null
+++ b/zeppelin-web/src/app/helium/helium-package.js
@@ -0,0 +1,47 @@
+/*
+ * 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 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
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/helium/helium-type.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/helium/helium-type.js b/zeppelin-web/src/app/helium/helium-type.js
new file mode 100644
index 0000000..27b34fa
--- /dev/null
+++ b/zeppelin-web/src/app/helium/helium-type.js
@@ -0,0 +1,20 @@
+/*
+ * 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 HeliumType = {
+ VISUALIZATION: 'VISUALIZATION',
+ SPELL: 'SPELL',
+ INTERPRETER: 'INTERPRETER',
+ APPLICATION: 'APPLICATION',
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/helium/helium.config.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/helium/helium.config.js b/zeppelin-web/src/app/helium/helium.config.js
deleted file mode 100644
index ace7136..0000000
--- a/zeppelin-web/src/app/helium/helium.config.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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
-}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/helium/helium.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/helium/helium.controller.js b/zeppelin-web/src/app/helium/helium.controller.js
index a610fb6..a397ace 100644
--- a/zeppelin-web/src/app/helium/helium.controller.js
+++ b/zeppelin-web/src/app/helium/helium.controller.js
@@ -12,7 +12,7 @@
* limitations under the License.
*/
-import { HeliumType, } from '../../components/helium/helium-type'
+import { HeliumType, } from './helium-type'
export default function HeliumCtrl ($scope, $rootScope, $sce,
baseUrlSrv, ngToast, heliumService) {
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/helium/helium.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/helium/helium.service.js b/zeppelin-web/src/app/helium/helium.service.js
new file mode 100644
index 0000000..d2054b3
--- /dev/null
+++ b/zeppelin-web/src/app/helium/helium.service.js
@@ -0,0 +1,301 @@
+/*
+ * 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'
+import {
+ createAllPackageConfigs,
+ createPersistableConfig,
+ mergePersistedConfWithSpec,
+} from './helium-conf'
+import {
+ createDefaultPackages,
+} from './helium-package'
+
+angular.module('zeppelinWebApp').service('heliumService', HeliumService)
+
+export default function HeliumService($http, $sce, baseUrlSrv) {
+ 'ngInject'
+
+ let visualizationBundles = []
+ let visualizationPackageOrder = []
+ // name `heliumBundles` should be same as `HeliumBundleFactory.HELIUM_BUNDLES_VAR`
+ let heliumBundles = []
+ // map for `{ magic: interpreter }`
+ let spellPerMagic = {}
+ // map for `{ magic: package-name }`
+ let pkgNamePerMagic = {}
+
+ /**
+ * @param magic {string} e.g `%flowchart`
+ * @returns {SpellBase} undefined if magic is not registered
+ */
+ this.getSpellByMagic = function (magic) {
+ return spellPerMagic[magic]
+ }
+
+ this.executeSpell = function (magic, textWithoutMagic) {
+ const promisedConf = this.getSinglePackageConfigUsingMagic(magic)
+ .then(confs => createPersistableConfig(confs))
+
+ return promisedConf.then(conf => {
+ const spell = this.getSpellByMagic(magic)
+ const spellResult = spell.interpret(textWithoutMagic, conf)
+ const parsed = spellResult.getAllParsedDataWithTypes(
+ spellPerMagic, magic, textWithoutMagic)
+
+ return parsed
+ })
+ }
+
+ this.executeSpellAsDisplaySystem = function (magic, textWithoutMagic) {
+ const promisedConf = this.getSinglePackageConfigUsingMagic(magic)
+ .then(confs => createPersistableConfig(confs))
+
+ return promisedConf.then(conf => {
+ const spell = this.getSpellByMagic(magic)
+ const spellResult = spell.interpret(textWithoutMagic.trim(), conf)
+ const parsed = spellResult.getAllParsedDataWithTypes(spellPerMagic)
+
+ return parsed
+ })
+ }
+
+ this.getVisualizationCachedPackages = function () {
+ return visualizationBundles
+ }
+
+ this.getVisualizationCachedPackageOrder = function () {
+ return visualizationPackageOrder
+ }
+
+ /**
+ * @returns {Promise} which returns bundleOrder and cache it in `visualizationPackageOrder`
+ */
+ this.getVisualizationPackageOrder = function () {
+ return $http.get(baseUrlSrv.getRestApiBase() + '/helium/order/visualization')
+ .then(function (response, status) {
+ const order = response.data.body
+ visualizationPackageOrder = order
+ return order
+ })
+ .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.enable = function (name, artifact) {
+ return $http.post(baseUrlSrv.getRestApiBase() + '/helium/enable/' + name, artifact)
+ }
+
+ this.disable = function (name) {
+ return $http.post(baseUrlSrv.getRestApiBase() + '/helium/disable/' + name)
+ }
+
+ this.saveConfig = function (pkg, defaultPackageConfig, closeConfigPanelCallback) {
+ // in case of local package, it will include `/`
+ const pkgArtifact = encodeURIComponent(pkg.artifact)
+ const pkgName = pkg.name
+ const filtered = createPersistableConfig(defaultPackageConfig)
+
+ if (!pkgName || !pkgArtifact || !filtered) {
+ console.error(
+ `Can't save config for helium package '${pkgArtifact}'`, filtered)
+ return
+ }
+
+ const url = `${baseUrlSrv.getRestApiBase()}/helium/config/${pkgName}/${pkgArtifact}`
+ return $http.post(url, filtered)
+ .then(() => {
+ if (closeConfigPanelCallback) { closeConfigPanelCallback() }
+ }).catch((error) => {
+ console.error(`Failed to save config for ${pkgArtifact}`, error)
+ })
+ }
+
+ /**
+ * @returns {Promise<Object>} which including {name, Array<package info for artifact>}
+ */
+ 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)
+ })
+ }
+
+ this.getAllEnabledPackages = function () {
+ return $http.get(`${baseUrlSrv.getRestApiBase()}/helium/enabledPackage`)
+ .then(function (response, status) {
+ return response.data.body
+ })
+ .catch(function (error) {
+ console.error('Failed to get all enabled package infos', error)
+ })
+ }
+
+ this.getSingleBundle = function (pkgName) {
+ let url = `${baseUrlSrv.getRestApiBase()}/helium/bundle/load/${pkgName}`
+ if (process.env.HELIUM_BUNDLE_DEV) {
+ url = url + '?refresh=true'
+ }
+
+ return $http.get(url)
+ .then(function (response, status) {
+ const bundle = response.data
+ if (bundle.substring(0, 'ERROR:'.length) === 'ERROR:') {
+ console.error(`Failed to get bundle: ${pkgName}`, bundle)
+ return '' // empty bundle will be filtered later
+ }
+
+ return bundle
+ })
+ .catch(function (error) {
+ console.error(`Failed to get single bundle: ${pkgName}`, error)
+ })
+ }
+
+ 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, Array<Object>}> }
+ */
+ 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<Array<Object>> }
+ */
+ this.getSinglePackageConfigs = function (pkg) {
+ const pkgName = pkg.name
+ // in case of local package, it will include `/`
+ const pkgArtifact = encodeURIComponent(pkg.artifact)
+
+ if (!pkgName || !pkgArtifact) {
+ console.error('Failed to fetch config for\n', pkg)
+ return Promise.resolve([])
+ }
+
+ const confUrl = `${baseUrlSrv.getRestApiBase()}/helium/config/${pkgName}/${pkgArtifact}`
+ const promisedConf = $http.get(confUrl)
+ .then(function (response, status) {
+ return response.data.body
+ })
+
+ return promisedConf.then(({confSpec, confPersisted}) => {
+ const merged = mergePersistedConfWithSpec(confPersisted, confSpec)
+ return merged
+ })
+ }
+
+ this.getSinglePackageConfigUsingMagic = function (magic) {
+ const pkgName = pkgNamePerMagic[magic]
+
+ const confUrl = `${baseUrlSrv.getRestApiBase()}/helium/spell/config/${pkgName}`
+ const promisedConf = $http.get(confUrl)
+ .then(function (response, status) {
+ return response.data.body
+ })
+
+ return promisedConf.then(({confSpec, confPersisted}) => {
+ const merged = mergePersistedConfWithSpec(confPersisted, confSpec)
+ return merged
+ })
+ }
+
+ const p = this.getAllEnabledPackages()
+ .then(enabledPackageSearchResults => {
+ const promises = enabledPackageSearchResults.map(packageSearchResult => {
+ const pkgName = packageSearchResult.pkg.name
+ return this.getSingleBundle(pkgName)
+ })
+
+ return Promise.all(promises)
+ })
+ .then(bundles => {
+ return bundles.reduce((acc, b) => {
+ // filter out empty bundle
+ if (b === '') { return acc }
+ acc.push(b)
+ return acc
+ }, [])
+ })
+
+ // load should be promise
+ this.load = p.then(availableBundles => {
+ // evaluate bundles
+ availableBundles.map(b => {
+ // eslint-disable-next-line no-eval
+ eval(b)
+ })
+
+ // extract bundles by type
+ heliumBundles.map(b => {
+ if (b.type === HeliumType.SPELL) {
+ const spell = new b.class() // eslint-disable-line new-cap
+ const pkgName = b.id
+ spellPerMagic[spell.getMagic()] = spell
+ pkgNamePerMagic[spell.getMagic()] = pkgName
+ } else if (b.type === HeliumType.VISUALIZATION) {
+ visualizationBundles.push(b)
+ }
+ })
+ })
+
+ this.init = function() {
+ this.getVisualizationPackageOrder()
+ }
+
+ // init
+ this.init()
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/home/home.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/home/home.controller.js b/zeppelin-web/src/app/home/home.controller.js
index 83f9681..2cf8439 100644
--- a/zeppelin-web/src/app/home/home.controller.js
+++ b/zeppelin-web/src/app/home/home.controller.js
@@ -14,15 +14,16 @@
angular.module('zeppelinWebApp').controller('HomeCtrl', HomeCtrl)
-function HomeCtrl ($scope, noteListDataFactory, websocketMsgSrv, $rootScope, arrayOrderingSrv,
- ngToast, noteActionSrv, TRASH_FOLDER_ID) {
+function HomeCtrl ($scope, noteListFactory, websocketMsgSrv, $rootScope, arrayOrderingSrv,
+ ngToast, noteActionService, TRASH_FOLDER_ID) {
'ngInject'
ngToast.dismiss()
let vm = this
- vm.notes = noteListDataFactory
+ vm.notes = noteListFactory
vm.websocketMsgSrv = websocketMsgSrv
vm.arrayOrderingSrv = arrayOrderingSrv
+ vm.noteActionService = noteActionService
vm.notebookHome = false
vm.noteCustomHome = true
@@ -85,15 +86,15 @@ function HomeCtrl ($scope, noteListDataFactory, websocketMsgSrv, $rootScope, arr
})
$scope.renameNote = function (nodeId, nodePath) {
- noteActionSrv.renameNote(nodeId, nodePath)
+ vm.noteActionService.renameNote(nodeId, nodePath)
}
$scope.moveNoteToTrash = function (noteId) {
- noteActionSrv.moveNoteToTrash(noteId, false)
+ vm.noteActionService.moveNoteToTrash(noteId, false)
}
$scope.moveFolderToTrash = function (folderId) {
- noteActionSrv.moveFolderToTrash(folderId)
+ vm.noteActionService.moveFolderToTrash(folderId)
}
$scope.restoreNote = function (noteId) {
@@ -105,27 +106,27 @@ function HomeCtrl ($scope, noteListDataFactory, websocketMsgSrv, $rootScope, arr
}
$scope.restoreAll = function () {
- noteActionSrv.restoreAll()
+ vm.noteActionService.restoreAll()
}
$scope.renameFolder = function (node) {
- noteActionSrv.renameFolder(node.id)
+ vm.noteActionService.renameFolder(node.id)
}
$scope.removeNote = function (noteId) {
- noteActionSrv.removeNote(noteId, false)
+ vm.noteActionService.removeNote(noteId, false)
}
$scope.removeFolder = function (folderId) {
- noteActionSrv.removeFolder(folderId)
+ vm.noteActionService.removeFolder(folderId)
}
$scope.emptyTrash = function () {
- noteActionSrv.emptyTrash()
+ vm.noteActionService.emptyTrash()
}
$scope.clearAllParagraphOutput = function (noteId) {
- noteActionSrv.clearAllParagraphOutput(noteId)
+ vm.noteActionService.clearAllParagraphOutput(noteId)
}
$scope.isFilterNote = function (note) {
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/home/home.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/home/home.html b/zeppelin-web/src/app/home/home.html
index 7c1154f..1ab9718 100644
--- a/zeppelin-web/src/app/home/home.html
+++ b/zeppelin-web/src/app/home/home.html
@@ -36,10 +36,10 @@ limitations under the License.
<div>
<h5><a href="" data-toggle="modal" data-target="#noteImportModal" style="text-decoration: none;">
<i style="font-size: 15px;" class="fa fa-upload"></i> Import note</a></h5>
- <h5 ng-controller="NotenameCtrl as notenamectrl"><a href="" data-toggle="modal" data-target="#noteNameModal" style="text-decoration: none;" ng-click="notenamectrl.getInterpreterSettings()">
+ <h5 ng-controller="NoteCreateCtrl as noteCreateCtrl"><a href="" data-toggle="modal" data-target="#noteCreateModal" style="text-decoration: none;" ng-click="noteCreateCtrl.getInterpreterSettings()">
<i style="font-size: 15px;" class="icon-notebook"></i> Create new note</a></h5>
<ul id="notebook-names">
- <li class="filter-names" ng-include="'components/filterNoteNames/filter-note-names.html'"></li>
+ <li class="filter-names" ng-include="'components/note-name-filter/note-name-filter.html'"></li>
<li ng-repeat="note in home.notes.list | filter:query.q | orderBy:node:false:home.arrayOrderingSrv.noteComparator track by $index">
<i style="font-size: 10px;" class="icon-doc"></i>
<a style="text-decoration: none;" href="#/notebook/{{note.id}}">{{noteName(note)}}</a>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/home/notebook-template.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/home/notebook-template.html b/zeppelin-web/src/app/home/notebook-template.html
index 4c287de..76602aa 100644
--- a/zeppelin-web/src/app/home/notebook-template.html
+++ b/zeppelin-web/src/app/home/notebook-template.html
@@ -58,8 +58,8 @@ limitations under the License.
<a style="text-decoration: none; cursor: pointer;" ng-click="toggleFolderNode(node)">
<i style="font-size: 10px;" ng-class="node.hidden ? 'fa fa-folder' : 'fa fa-folder-open'"></i> {{getNoteName(node)}}
</a>
- <a ng-if="!node.isTrash" href="" data-toggle="modal" data-target="#noteNameModal" style="text-decoration: none;"
- ng-controller="NotenameCtrl as notenamectrl" ng-click="notenamectrl.getInterpreterSettings()" data-path="{{node.id}}">
+ <a ng-if="!node.isTrash" href="" data-toggle="modal" data-target="#noteCreateModal" style="text-decoration: none;"
+ ng-controller="NoteCreateCtrl as noteCreateCtrl" ng-click="noteCreateCtrl.getInterpreterSettings()" data-path="{{node.id}}">
<i style="margin-left: 10px;"
class="fa fa-plus notebook-list-btn" ng-show="showFolderButton"
tooltip-placement="bottom" uib-tooltip="Create new note">
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/home/notebook.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/home/notebook.html b/zeppelin-web/src/app/home/notebook.html
index 76214e9..f276a22 100644
--- a/zeppelin-web/src/app/home/notebook.html
+++ b/zeppelin-web/src/app/home/notebook.html
@@ -23,10 +23,10 @@ limitations under the License.
</h4>
<h5><a href="" data-toggle="modal" data-target="#noteImportModal" style="text-decoration: none;">
<i style="font-size: 15px;" class="fa fa-upload"></i> Import note</a></h5>
- <h5><a href="" data-toggle="modal" data-target="#noteNameModal" style="text-decoration: none;">
+ <h5><a href="" data-toggle="modal" data-target="#noteCreateModal" style="text-decoration: none;">
<i style="font-size: 15px;" class="icon-notebook"></i> Create new note</a></h5>
<ul id="notebook-names">
- <li class="filter-names" ng-include="'components/filterNoteNames/filter-note-names.html'"></li>
+ <li class="filter-names" ng-include="'components/note-name-filter/note-name-filter.html'"></li>
<div ng-if="!query.q || query.q === ''">
<li ng-repeat="node in home.notes.root.children | orderBy:node:false:home.arrayOrderingSrv.noteComparator track by $index"
ng-include src="'app/home/notebook-template.html'" ng-class="note_folder_renderer"></li>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/interpreter/interpreter-create.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/interpreter/interpreter-create.html b/zeppelin-web/src/app/interpreter/interpreter-create.html
new file mode 100644
index 0000000..b37f160
--- /dev/null
+++ b/zeppelin-web/src/app/interpreter/interpreter-create.html
@@ -0,0 +1,383 @@
+<!--
+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.
+-->
+<div>
+ <div class="row interpreter">
+ <div class="col-md-12" ng-show="showAddNewSetting">
+ <hr />
+ <div class="interpreterSettingAdd">
+ <h4>Create new interpreter</h4>
+
+ <div class="form-group" style="width:200px">
+ <b>Interpreter Name</b>
+ <input id="newInterpreterSettingName" input pu-elastic-input
+ pu-elastic-input-minwidth="180px" ng-model="newInterpreterSetting.name" />
+ </div>
+
+ <b>Interpreter group</b>
+ <div class="form-group"
+ style="width:180px">
+ <select class="form-control input-sm" ng-model="newInterpreterSetting.group"
+ ng-change="newInterpreterGroupChange()">
+ <option ng-repeat="availableInterpreter in availableInterpreters | unique: 'name'| orderBy: 'name'" value="{{availableInterpreter.name}}">
+ {{availableInterpreter.name}}
+ </option>
+ </select>
+ </div>
+
+ <div>
+ <h5>Option</h5>
+ <div class="row interpreter" style="margin-top: 5px;">
+ <div class="col-md-6">
+ The interpreter will be instantiated
+ <span class="btn-group">
+ <button type="button" class="btn btn-default btn-xs dropdown-toggle"
+ data-toggle="dropdown">
+ {{getInterpreterRunningOption(setting.id)}} <span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu" role="menu">
+ <li>
+ <a style="cursor:pointer"
+ ng-click="setInterpreterRunningOption(setting.id, 'shared', 'shared')">
+ Globally
+ </a>
+ </li>
+ <li>
+ <a style="cursor:pointer"
+ ng-click="setInterpreterRunningOption(setting.id, 'scoped', '')">
+ Per Note
+ </a>
+ </li>
+ <li ng-if="ticket.principal !== 'anonymous'">
+ <a style="cursor:pointer"
+ ng-click="setInterpreterRunningOption(setting.id, 'shared', 'scoped')">
+ Per User
+ </a>
+ </li>
+ </ul>
+ </span>
+ in
+ <span class="btn-group">
+ <button type="button" class="btn btn-default btn-xs dropdown-toggle"
+ data-toggle="dropdown"
+ ng-disabled="getInterpreterRunningOption(setting.id) === 'Globally'">
+ <span ng-if="getInterpreterRunningOption(setting.id) !== 'Per User'">
+ {{getPerNoteOption(setting.id)}}
+ </span>
+ <span ng-if="getInterpreterRunningOption(setting.id) === 'Per User'">
+ {{getPerUserOption(setting.id)}}
+ </span>
+ <span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu" role="menu">
+ <li
+ ng-if="getInterpreterRunningOption(setting.id) === 'Globally'">
+ <a style="cursor:pointer"
+ uib-tooltip="Single interpreter instance are shared across notes"
+ ng-click="setPerNoteOption(setting.id, 'shared')">
+ shared per note
+ </a>
+ </li>
+
+ <li>
+ <a style="cursor:pointer"
+ ng-if="getInterpreterRunningOption(setting.id) === 'Per Note'"
+ uib-tooltip="Separate Interpreter instance for each note"
+ ng-click="setPerNoteOption(setting.id, 'scoped')">
+ scoped per note
+ </a>
+ </li>
+ <li>
+ <a style="cursor:pointer"
+ ng-if="getInterpreterRunningOption(setting.id) === 'Per User'"
+ uib-tooltip="Separate Interpreter instance for each note"
+ ng-click="setPerUserOption(setting.id, 'scoped')">
+ scoped per user
+ </a>
+ </li>
+
+ <li>
+ <a style="cursor:pointer"
+ ng-if="getInterpreterRunningOption(setting.id) === 'Per Note'"
+ uib-tooltip="Separate Interpreter process for each note"
+ ng-click="setPerNoteOption(setting.id, 'isolated')">
+ isolated per note
+ </a>
+ </li>
+ <li>
+ <a style="cursor:pointer"
+ ng-if="getInterpreterRunningOption(setting.id) === 'Per User'"
+ uib-tooltip="Separate Interpreter process for each note"
+ ng-click="setPerUserOption(setting.id, 'isolated')">
+ isolated per user
+ </a>
+ </li>
+ </ul>
+ </span>
+ process
+ <a class="fa fa-info-circle interpreter-binding-mode-info-link"
+ aria-hidden="true"
+ uib-tooltip="Can manage interpreter sessions differently by setting this option. Click this button to learn more"
+ ng-href="{{getInterpreterBindingModeDocsLink()}}" target="_blank"></a>
+ <span ng-if="getInterpreterRunningOption(setting.id) === 'Per User' && ticket.principal !== 'anonymous'">
+ <span ng-if="getPerNoteOption(setting.id) === 'shared'">
+ <button type="button" class="btn btn-default btn-xs"
+ ng-click="setPerNoteOption(setting.id, 'scoped')"
+ data-toggle="dropdown">
+ <i class="fa fa-plus"></i>
+ </button>
+ </span>
+ </span>
+ </div>
+ </div>
+ <div class="row interpreter"
+ style="margin-top: 6px;"
+ ng-if="getInterpreterRunningOption(setting.id) === 'Per User'
+ && ticket.principal !== 'anonymous'
+ && getPerNoteOption(setting.id) !== 'shared'">
+ <div class="col-md-12">
+ <span>
+ <span class="hidden-xs" style="padding-left: 190px;">And </span>
+ <span class="visible-xs" style="padding-left: 0px;">And </span>
+ <span class="btn-group">
+ <button type="button" class="btn btn-default btn-xs dropdown-toggle"
+ data-toggle="dropdown"
+ ng-disabled="true">
+ <span>
+ Per Note
+ </span>
+ <span class="caret"></span>
+ </button>
+ </span>
+ in
+ <span class="btn-group">
+ <button type="button" class="btn btn-default btn-xs dropdown-toggle"
+ data-toggle="dropdown">
+ <span>
+ {{getPerNoteOption(setting.id)}}
+ </span>
+ <span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu" role="menu">
+ <li>
+ <a style="cursor:pointer"
+ uib-tooltip="Separate Interpreter instance for each note"
+ ng-click="setPerNoteOption(setting.id, 'scoped')">
+ scoped per note
+ </a>
+ </li>
+ <li>
+ <a style="cursor:pointer"
+ uib-tooltip="Separate Interpreter process for each note"
+ ng-click="setPerNoteOption(setting.id, 'isolated')">
+ isolated per note
+ </a>
+ </li>
+ </ul>
+ </span>
+ process.
+ <button type="button" class="btn btn-default btn-xs"
+ ng-click="setPerNoteOption(setting.id, 'shared')"
+ data-toggle="dropdown">
+ <i class="fa fa-minus"></i>
+ </button>
+ </span>
+ </div>
+ </div>
+ </div>
+ <div class="row interpreter" style="margin-top: 5px;"
+ ng-show="getInterpreterRunningOption(setting.id)=='Per User' && getPerUserOption(setting.id)=='isolated'">
+ <div class="col-md-12">
+ <div class="checkbox remove-margin-top-bottom">
+ <span class="input-group" style="line-height:30px;">
+ <label>
+ <input type="checkbox" style="width:20px" ng-model="newInterpreterSetting.option.isUserImpersonate" />
+ User Impersonate
+ </label>
+ </span>
+ </div>
+ </div>
+ </div>
+ <div class="row interpreter">
+ <div class="col-md-12">
+ <div class="checkbox remove-margin-top-bottom">
+ <span class="input-group" style="line-height:30px;">
+ <label>
+ <input type="checkbox" style="width:20px" id="isExistingProcess" ng-model="newInterpreterSetting.option.isExistingProcess"/>
+ Connect to existing process
+ </label>
+ </span>
+ </div>
+ </div>
+ </div>
+ <div class="row interpreter" ng-show="newInterpreterSetting.option.isExistingProcess" >
+ <div class="col-md-12">
+ <b>Host</b>
+ <input id="newInterpreterSettingHost" input pu-elastic-input
+ pu-elastic-input-minwidth="180px" ng-model="newInterpreterSetting.option.host"/>
+ </div>
+ <div class="col-md-12">
+ <b>Port</b>
+ <input id="newInterpreterSettingPort" input pu-elastic-input
+ pu-elastic-input-minwidth="180px" ng-model="newInterpreterSetting.option.port"/>
+ </div>
+ </div>
+ <div class="row interpreter">
+ <div class="col-md-12">
+ <div class="checkbox remove-margin-top-bottom">
+ <span class="input-group" style="line-height:30px;">
+ <label>
+ <input type="checkbox" style="width:20px !important" id="idShowPermission" ng-click="togglePermissions('newInterpreter')" ng-model="newInterpreterSetting.option.setPermission"/>
+ Set permission
+ </label>
+ </span>
+ </div>
+ </div>
+ </div>
+ <br/>
+
+ <div class="row interpreter">
+ <div class="col-md-12">
+ <!-- permissions -->
+ <div ng-show="newInterpreterSetting.option.setPermission" class="permissionsForm">
+ <div>
+ <p>
+ Enter comma separated users and groups in the fields. <br />
+ Empty field (*) implies anyone can run this interpreter.
+ </p>
+ <div>
+ <span class="owners">Owners </span>
+ <select id="newInterpreterOwners" class="form-control" multiple="multiple">
+ <option ng-repeat="owner in newInterpreterSetting.option.owners" selected="selected">{{owner}}</option>
+ </select>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div>
+ <h5>Properties</h5>
+ <table class="table table-striped properties">
+ <tr>
+ <th>name</th>
+ <th>value</th>
+ <th>action</th>
+ <th>description</th>
+ </tr>
+ <tr ng-repeat="key in newInterpreterSetting.properties | sortByKey">
+ <td>{{key}}</td>
+ <td style="vertical-align: middle;">
+ <textarea ng-if="newInterpreterSetting.properties[key].type === 'textarea'"
+ msd-elastic ng-model="newInterpreterSetting.properties[key].value"></textarea>
+ <input ng-if="newInterpreterSetting.properties[key].type === 'string'"
+ type="text" msd-elastic ng-model="newInterpreterSetting.properties[key].value" />
+ <input ng-if="newInterpreterSetting.properties[key].type === 'number'"
+ type="text" number-widget msd-elastic ng-model="newInterpreterSetting.properties[key].value" />
+ <input ng-if="newInterpreterSetting.properties[key].type === 'url'"
+ type="text" msd-elastic ng-model="newInterpreterSetting.properties[key].value" />
+ <input ng-if="newInterpreterSetting.properties[key].type === 'password'"
+ type="password" msd-elastic ng-model="newInterpreterSetting.properties[key].value" />
+ <input ng-if="newInterpreterSetting.properties[key].type === 'boolean'"
+ type="checkbox" msd-elastic ng-model="newInterpreterSetting.properties[key].value" />
+ </td>
+ <td style="vertical-align: middle;">
+ <button class="btn btn-default btn-sm fa fa-remove" ng-click="removeInterpreterProperty(key)">
+ </button>
+ </td>
+ <td style="vertical-align: middle;">
+ {{newInterpreterSetting.properties[key].description}}
+ </td>
+ </tr>
+
+ <tr>
+ <td style="vertical-align: middle;">
+ <input pu-elastic-input pu-elastic-input-minwidth="180px"
+ ng-model="newInterpreterSetting.propertyKey" />
+ </td>
+ <td style="vertical-align: middle;" ng-switch on="newInterpreterSetting.propertyType">
+ <textarea ng-switch-default msd-elastic ng-model="newInterpreterSetting.propertyValue"></textarea>
+ <input ng-switch-when="string" type="text" msd-elastic ng-model="newInterpreterSetting.propertyValue" />
+ <input ng-switch-when="number" type="text" number-widget msd-elastic ng-model="newInterpreterSetting.propertyValue" />
+ <input ng-switch-when="url" type="text" msd-elastic ng-model="newInterpreterSetting.propertyValue" />
+ <input ng-switch-when="password" type="password" msd-elastic ng-model="newInterpreterSetting.propertyValue" />
+ <input ng-switch-when="checkbox" type="checkbox" msd-elastic ng-model="newInterpreterSetting.propertyValue" />
+ </td>
+ <td style="vertical-align: middle;">
+ <select msd-elastic ng-model="newInterpreterSetting.propertyType" ng-init="newInterpreterSetting.propertyType=interpreterPropertyTypes[0]"
+ ng-options="item for item in interpreterPropertyTypes" ng-change="defaultValueByType(newInterpreterSetting)">
+ </select>
+ <button class="btn btn-default btn-sm fa fa-plus" ng-click="addNewInterpreterProperty()">
+ </button>
+ </td>
+ <td></td>
+ </tr>
+ </table>
+ </div>
+
+ <div>
+ <h5>Dependencies</h5>
+ <table class="table table-striped properties">
+ <tr>
+ <th>artifact</th>
+ <th>exclude</th>
+ <th>action</th>
+ </tr>
+
+ <tr ng-repeat="dep in newInterpreterSetting.dependencies">
+ <td>
+ <input ng-model="dep.groupArtifactVersion" style="width:100%" />
+ </td>
+ <td>
+ <textarea msd-elastic ng-model="dep.exclusions"
+ ng-list
+ placeholder="(Optional) comma separated groupId:artifactId list">
+ </textarea>
+ </td>
+ <td>
+ <button class="btn btn-default btn-sm fa fa-remove"
+ ng-click="removeInterpreterDependency(dep.groupArtifactVersion)">
+ </button>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <input ng-model="newInterpreterSetting.depArtifact"
+ placeholder="groupId:artifactId:version or local file path"
+ style="width: 100%" />
+ </td>
+ <td>
+ <textarea msd-elastic ng-model="newInterpreterSetting.depExclude"
+ ng-list
+ placeholder="(Optional) comma separated groupId:artifactId list">
+ </textarea>
+ </td>
+ <td>
+ <button class="btn btn-default btn-sm fa fa-plus" ng-click="addNewInterpreterDependency()">
+ </button>
+ </td>
+ </tr>
+ </table>
+ </div>
+
+ <span class="btn btn-primary" ng-click="addNewInterpreterSetting()">
+ Save
+ </span>
+ <span class="btn btn-default" ng-click="cancelInterpreterSetting()">
+ Cancel
+ </span>
+ </div>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/interpreter/interpreter-create/interpreter-create.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/interpreter/interpreter-create/interpreter-create.html b/zeppelin-web/src/app/interpreter/interpreter-create/interpreter-create.html
deleted file mode 100644
index 1fa60f8..0000000
--- a/zeppelin-web/src/app/interpreter/interpreter-create/interpreter-create.html
+++ /dev/null
@@ -1,383 +0,0 @@
-<!--
-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.
--->
-<div>
- <div class="row interpreter">
- <div class="col-md-12" ng-show="showAddNewSetting">
- <hr />
- <div class="interpreterSettingAdd">
- <h4>Create new interpreter</h4>
-
- <div class="form-group" style="width:200px">
- <b>Interpreter Name</b>
- <input id="newInterpreterSettingName" input pu-elastic-input
- pu-elastic-input-minwidth="180px" ng-model="newInterpreterSetting.name" />
- </div>
-
- <b>Interpreter group</b>
- <div class="form-group"
- style="width:180px">
- <select class="form-control input-sm" ng-model="newInterpreterSetting.group"
- ng-change="newInterpreterGroupChange()">
- <option ng-repeat="availableInterpreter in availableInterpreters | unique: 'name'| orderBy: 'name'" value="{{availableInterpreter.name}}">
- {{availableInterpreter.name}}
- </option>
- </select>
- </div>
-
- <div>
- <h5>Option</h5>
- <div class="row interpreter" style="margin-top: 5px;">
- <div class="col-md-6">
- The interpreter will be instantiated
- <span class="btn-group">
- <button type="button" class="btn btn-default btn-xs dropdown-toggle"
- data-toggle="dropdown">
- {{getInterpreterRunningOption(setting.id)}} <span class="caret"></span>
- </button>
- <ul class="dropdown-menu" role="menu">
- <li>
- <a style="cursor:pointer"
- ng-click="setInterpreterRunningOption(setting.id, 'shared', 'shared')">
- Globally
- </a>
- </li>
- <li>
- <a style="cursor:pointer"
- ng-click="setInterpreterRunningOption(setting.id, 'scoped', '')">
- Per Note
- </a>
- </li>
- <li ng-if="ticket.principal !== 'anonymous'">
- <a style="cursor:pointer"
- ng-click="setInterpreterRunningOption(setting.id, 'shared', 'scoped')">
- Per User
- </a>
- </li>
- </ul>
- </span>
- in
- <span class="btn-group">
- <button type="button" class="btn btn-default btn-xs dropdown-toggle"
- data-toggle="dropdown"
- ng-disabled="getInterpreterRunningOption(setting.id) === 'Globally'">
- <span ng-if="getInterpreterRunningOption(setting.id) !== 'Per User'">
- {{getPerNoteOption(setting.id)}}
- </span>
- <span ng-if="getInterpreterRunningOption(setting.id) === 'Per User'">
- {{getPerUserOption(setting.id)}}
- </span>
- <span class="caret"></span>
- </button>
- <ul class="dropdown-menu" role="menu">
- <li
- ng-if="getInterpreterRunningOption(setting.id) === 'Globally'">
- <a style="cursor:pointer"
- uib-tooltip="Single interpreter instance are shared across notes"
- ng-click="setPerNoteOption(setting.id, 'shared')">
- shared per note
- </a>
- </li>
-
- <li>
- <a style="cursor:pointer"
- ng-if="getInterpreterRunningOption(setting.id) === 'Per Note'"
- uib-tooltip="Separate Interpreter instance for each note"
- ng-click="setPerNoteOption(setting.id, 'scoped')">
- scoped per note
- </a>
- </li>
- <li>
- <a style="cursor:pointer"
- ng-if="getInterpreterRunningOption(setting.id) === 'Per User'"
- uib-tooltip="Separate Interpreter instance for each note"
- ng-click="setPerUserOption(setting.id, 'scoped')">
- scoped per user
- </a>
- </li>
-
- <li>
- <a style="cursor:pointer"
- ng-if="getInterpreterRunningOption(setting.id) === 'Per Note'"
- uib-tooltip="Separate Interpreter process for each note"
- ng-click="setPerNoteOption(setting.id, 'isolated')">
- isolated per note
- </a>
- </li>
- <li>
- <a style="cursor:pointer"
- ng-if="getInterpreterRunningOption(setting.id) === 'Per User'"
- uib-tooltip="Separate Interpreter process for each note"
- ng-click="setPerUserOption(setting.id, 'isolated')">
- isolated per user
- </a>
- </li>
- </ul>
- </span>
- process
- <a class="fa fa-info-circle interpreter-binding-mode-info-link"
- aria-hidden="true"
- uib-tooltip="Can manage interpreter sessions differently by setting this option. Click this button to learn more"
- ng-href="{{getInterpreterBindingModeDocsLink()}}" target="_blank"></a>
- <span ng-if="getInterpreterRunningOption(setting.id) === 'Per User' && ticket.principal !== 'anonymous'">
- <span ng-if="getPerNoteOption(setting.id) === 'shared'">
- <button type="button" class="btn btn-default btn-xs"
- ng-click="setPerNoteOption(setting.id, 'scoped')"
- data-toggle="dropdown">
- <i class="fa fa-plus"></i>
- </button>
- </span>
- </span>
- </div>
- </div>
- <div class="row interpreter"
- style="margin-top: 6px;"
- ng-if="getInterpreterRunningOption(setting.id) === 'Per User'
- && ticket.principal !== 'anonymous'
- && getPerNoteOption(setting.id) !== 'shared'">
- <div class="col-md-12">
- <span>
- <span class="hidden-xs" style="padding-left: 190px;">And </span>
- <span class="visible-xs" style="padding-left: 0px;">And </span>
- <span class="btn-group">
- <button type="button" class="btn btn-default btn-xs dropdown-toggle"
- data-toggle="dropdown"
- ng-disabled="true">
- <span>
- Per Note
- </span>
- <span class="caret"></span>
- </button>
- </span>
- in
- <span class="btn-group">
- <button type="button" class="btn btn-default btn-xs dropdown-toggle"
- data-toggle="dropdown">
- <span>
- {{getPerNoteOption(setting.id)}}
- </span>
- <span class="caret"></span>
- </button>
- <ul class="dropdown-menu" role="menu">
- <li>
- <a style="cursor:pointer"
- uib-tooltip="Separate Interpreter instance for each note"
- ng-click="setPerNoteOption(setting.id, 'scoped')">
- scoped per note
- </a>
- </li>
- <li>
- <a style="cursor:pointer"
- uib-tooltip="Separate Interpreter process for each note"
- ng-click="setPerNoteOption(setting.id, 'isolated')">
- isolated per note
- </a>
- </li>
- </ul>
- </span>
- process.
- <button type="button" class="btn btn-default btn-xs"
- ng-click="setPerNoteOption(setting.id, 'shared')"
- data-toggle="dropdown">
- <i class="fa fa-minus"></i>
- </button>
- </span>
- </div>
- </div>
- </div>
- <div class="row interpreter" style="margin-top: 5px;"
- ng-show="getInterpreterRunningOption(setting.id)=='Per User' && getPerUserOption(setting.id)=='isolated'">
- <div class="col-md-12">
- <div class="checkbox remove-margin-top-bottom">
- <span class="input-group" style="line-height:30px;">
- <label>
- <input type="checkbox" style="width:20px" ng-model="newInterpreterSetting.option.isUserImpersonate" />
- User Impersonate
- </label>
- </span>
- </div>
- </div>
- </div>
- <div class="row interpreter">
- <div class="col-md-12">
- <div class="checkbox remove-margin-top-bottom">
- <span class="input-group" style="line-height:30px;">
- <label>
- <input type="checkbox" style="width:20px" id="isExistingProcess" ng-model="newInterpreterSetting.option.isExistingProcess"/>
- Connect to existing process
- </label>
- </span>
- </div>
- </div>
- </div>
- <div class="row interpreter" ng-show="newInterpreterSetting.option.isExistingProcess" >
- <div class="col-md-12">
- <b>Host</b>
- <input id="newInterpreterSettingHost" input pu-elastic-input
- pu-elastic-input-minwidth="180px" ng-model="newInterpreterSetting.option.host"/>
- </div>
- <div class="col-md-12">
- <b>Port</b>
- <input id="newInterpreterSettingPort" input pu-elastic-input
- pu-elastic-input-minwidth="180px" ng-model="newInterpreterSetting.option.port"/>
- </div>
- </div>
- <div class="row interpreter">
- <div class="col-md-12">
- <div class="checkbox remove-margin-top-bottom">
- <span class="input-group" style="line-height:30px;">
- <label>
- <input type="checkbox" style="width:20px !important" id="idShowPermission" ng-click="togglePermissions('newInterpreter')" ng-model="newInterpreterSetting.option.setPermission"/>
- Set permission
- </label>
- </span>
- </div>
- </div>
- </div>
- <br/>
-
- <div class="row interpreter">
- <div class="col-md-12">
- <!-- permissions -->
- <div ng-show="newInterpreterSetting.option.setPermission" class="permissionsForm">
- <div>
- <p>
- Enter comma separated users and groups in the fields. <br />
- Empty field (*) implies anyone can run this interpreter.
- </p>
- <div>
- <span class="owners">Owners </span>
- <select id="newInterpreterOwners" class="form-control" multiple="multiple">
- <option ng-repeat="owner in newInterpreterSetting.option.owners" selected="selected">{{owner}}</option>
- </select>
- </div>
- </div>
- </div>
- </div>
- </div>
-
- <div>
- <h5>Properties</h5>
- <table class="table table-striped properties">
- <tr>
- <th>name</th>
- <th>value</th>
- <th>action</th>
- <th>description</th>
- </tr>
- <tr ng-repeat="key in newInterpreterSetting.properties | sortByKey">
- <td>{{key}}</td>
- <td style="vertical-align: middle;">
- <textarea ng-if="newInterpreterSetting.properties[key].type === 'textarea'"
- msd-elastic ng-model="newInterpreterSetting.properties[key].value"></textarea>
- <input ng-if="newInterpreterSetting.properties[key].type === 'string'"
- type="text" msd-elastic ng-model="newInterpreterSetting.properties[key].value" />
- <input ng-if="newInterpreterSetting.properties[key].type === 'number'"
- type="text" widget-number msd-elastic ng-model="newInterpreterSetting.properties[key].value" />
- <input ng-if="newInterpreterSetting.properties[key].type === 'url'"
- type="text" msd-elastic ng-model="newInterpreterSetting.properties[key].value" />
- <input ng-if="newInterpreterSetting.properties[key].type === 'password'"
- type="password" msd-elastic ng-model="newInterpreterSetting.properties[key].value" />
- <input ng-if="newInterpreterSetting.properties[key].type === 'boolean'"
- type="checkbox" msd-elastic ng-model="newInterpreterSetting.properties[key].value" />
- </td>
- <td style="vertical-align: middle;">
- <button class="btn btn-default btn-sm fa fa-remove" ng-click="removeInterpreterProperty(key)">
- </button>
- </td>
- <td style="vertical-align: middle;">
- {{newInterpreterSetting.properties[key].description}}
- </td>
- </tr>
-
- <tr>
- <td style="vertical-align: middle;">
- <input pu-elastic-input pu-elastic-input-minwidth="180px"
- ng-model="newInterpreterSetting.propertyKey" />
- </td>
- <td style="vertical-align: middle;" ng-switch on="newInterpreterSetting.propertyType">
- <textarea ng-switch-default msd-elastic ng-model="newInterpreterSetting.propertyValue"></textarea>
- <input ng-switch-when="string" type="text" msd-elastic ng-model="newInterpreterSetting.propertyValue" />
- <input ng-switch-when="number" type="text" widget-number msd-elastic ng-model="newInterpreterSetting.propertyValue" />
- <input ng-switch-when="url" type="text" msd-elastic ng-model="newInterpreterSetting.propertyValue" />
- <input ng-switch-when="password" type="password" msd-elastic ng-model="newInterpreterSetting.propertyValue" />
- <input ng-switch-when="checkbox" type="checkbox" msd-elastic ng-model="newInterpreterSetting.propertyValue" />
- </td>
- <td style="vertical-align: middle;">
- <select msd-elastic ng-model="newInterpreterSetting.propertyType" ng-init="newInterpreterSetting.propertyType=interpreterPropertyTypes[0]"
- ng-options="item for item in interpreterPropertyTypes" ng-change="defaultValueByType(newInterpreterSetting)">
- </select>
- <button class="btn btn-default btn-sm fa fa-plus" ng-click="addNewInterpreterProperty()">
- </button>
- </td>
- <td></td>
- </tr>
- </table>
- </div>
-
- <div>
- <h5>Dependencies</h5>
- <table class="table table-striped properties">
- <tr>
- <th>artifact</th>
- <th>exclude</th>
- <th>action</th>
- </tr>
-
- <tr ng-repeat="dep in newInterpreterSetting.dependencies">
- <td>
- <input ng-model="dep.groupArtifactVersion" style="width:100%" />
- </td>
- <td>
- <textarea msd-elastic ng-model="dep.exclusions"
- ng-list
- placeholder="(Optional) comma separated groupId:artifactId list">
- </textarea>
- </td>
- <td>
- <button class="btn btn-default btn-sm fa fa-remove"
- ng-click="removeInterpreterDependency(dep.groupArtifactVersion)">
- </button>
- </td>
- </tr>
-
- <tr>
- <td>
- <input ng-model="newInterpreterSetting.depArtifact"
- placeholder="groupId:artifactId:version or local file path"
- style="width: 100%" />
- </td>
- <td>
- <textarea msd-elastic ng-model="newInterpreterSetting.depExclude"
- ng-list
- placeholder="(Optional) comma separated groupId:artifactId list">
- </textarea>
- </td>
- <td>
- <button class="btn btn-default btn-sm fa fa-plus" ng-click="addNewInterpreterDependency()">
- </button>
- </td>
- </tr>
- </table>
- </div>
-
- <span class="btn btn-primary" ng-click="addNewInterpreterSetting()">
- Save
- </span>
- <span class="btn btn-default" ng-click="cancelInterpreterSetting()">
- Cancel
- </span>
- </div>
- </div>
- </div>
-</div>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/interpreter/interpreter-item.directive.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/interpreter/interpreter-item.directive.js b/zeppelin-web/src/app/interpreter/interpreter-item.directive.js
new file mode 100644
index 0000000..4bde44d
--- /dev/null
+++ b/zeppelin-web/src/app/interpreter/interpreter-item.directive.js
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+angular.module('zeppelinWebApp').directive('interpreterItem', InterpreterItemDirective)
+
+function InterpreterItemDirective ($timeout) {
+ 'ngInject'
+
+ return {
+ restrict: 'A',
+ link: function (scope, element, attr) {
+ if (scope.$last === true) {
+ $timeout(function () {
+ let id = 'ngRenderFinished'
+ scope.$emit(id)
+ })
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/6bd6c708/zeppelin-web/src/app/interpreter/interpreter.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/interpreter/interpreter.html b/zeppelin-web/src/app/interpreter/interpreter.html
index 617ce38..c1d90cc 100644
--- a/zeppelin-web/src/app/interpreter/interpreter.html
+++ b/zeppelin-web/src/app/interpreter/interpreter.html
@@ -72,7 +72,7 @@ limitations under the License.
</a>
</li>
<li class="liVertical">
- <div ng-include src="'components/repository-create/repository-dialog.html'"></div>
+ <div ng-include src="'app/interpreter/repository-create.html'"></div>
<div class="btn btn-default"
data-toggle="modal"
data-target="#repoModal">
@@ -83,11 +83,11 @@ limitations under the License.
</div>
</div>
- <div ng-include src="'app/interpreter/interpreter-create/interpreter-create.html'"></div>
+ <div ng-include src="'app/interpreter/interpreter-create.html'"></div>
</div>
-<div class="box width-full"
- ng-repeat="setting in interpreterSettings | orderBy: 'name' | filter: {name:searchInterpreter} " interpreter-directive>
+<div interpreter-item class="box width-full"
+ ng-repeat="setting in interpreterSettings | orderBy: 'name' | filter: {name:searchInterpreter}" >
<div id="{{setting.name | lowercase}}">
<div class="row interpreter">
@@ -443,7 +443,7 @@ limitations under the License.
<td style="vertical-align: middle;" ng-switch on="setting.propertyType">
<textarea ng-switch-default msd-elastic ng-model="setting.propertyValue"></textarea>
<input ng-switch-when="string" type="text" msd-elastic ng-model="setting.propertyValue"/>
- <input ng-switch-when="number" type="text" msd-elastic ng-model="setting.propertyValue" widget-number />
+ <input ng-switch-when="number" type="text" msd-elastic ng-model="setting.propertyValue" number-widget />
<input ng-switch-when="url" type="text" msd-elastic ng-model="setting.propertyValue" />
<input ng-switch-when="password" type="password" msd-elastic ng-model="setting.propertyValue" />
<input ng-switch-when="checkbox" type="checkbox" msd-elastic ng-model="setting.propertyValue" />