|
|
@@ -23,67 +23,32 @@ import hueAnalytics from 'utils/hueAnalytics';
|
|
|
import huePubSub from 'utils/huePubSub';
|
|
|
import hueUtils from 'utils/hueUtils';
|
|
|
|
|
|
-import { Snippet, STATUS as SNIPPET_STATUS } from 'apps/notebook2/snippet';
|
|
|
-
|
|
|
-const NOTEBOOK_MAPPING = {
|
|
|
- ignore: [
|
|
|
- 'ace',
|
|
|
- 'aceEditor',
|
|
|
- 'aceMode',
|
|
|
- 'autocompleter',
|
|
|
- 'availableDatabases',
|
|
|
- 'availableSnippets',
|
|
|
- 'avoidClosing',
|
|
|
- 'canWrite',
|
|
|
- 'cleanedDateTimeMeta',
|
|
|
- 'cleanedMeta',
|
|
|
- 'cleanedNumericMeta',
|
|
|
- 'cleanedStringMeta',
|
|
|
- 'dependents',
|
|
|
- 'errorLoadingQueries',
|
|
|
- 'hasProperties',
|
|
|
- 'history',
|
|
|
- 'images',
|
|
|
- 'inFocus',
|
|
|
- 'parentNotebook',
|
|
|
- 'parentVm',
|
|
|
- 'queries',
|
|
|
- 'saveResultsModalVisible',
|
|
|
- 'selectedStatement',
|
|
|
- 'snippetImage',
|
|
|
- 'user',
|
|
|
- 'positionStatement',
|
|
|
- 'lastExecutedStatement',
|
|
|
- 'downloadResultViewModel'
|
|
|
- ]
|
|
|
-};
|
|
|
-
|
|
|
-class Notebook {
|
|
|
+import Snippet, { STATUS as SNIPPET_STATUS } from 'apps/notebook2/snippet';
|
|
|
+import { notebookToContextJSON, notebookToJSON } from 'apps/notebook2/notebookSerde';
|
|
|
+
|
|
|
+export default class Notebook {
|
|
|
constructor(vm, notebook) {
|
|
|
- const self = this;
|
|
|
-
|
|
|
- self.parentVm = vm;
|
|
|
-
|
|
|
- self.id = ko.observable(notebook.id);
|
|
|
- self.uuid = ko.observable(notebook.uuid || hueUtils.UUID());
|
|
|
- self.name = ko.observable(notebook.name || 'My Notebook');
|
|
|
- self.description = ko.observable(notebook.description || '');
|
|
|
- self.type = ko.observable(notebook.type || 'notebook');
|
|
|
- self.initialType = self.type().replace('query-', '');
|
|
|
- self.coordinatorUuid = ko.observable(notebook.coordinatorUuid);
|
|
|
- self.isHistory = ko.observable(!!notebook.is_history);
|
|
|
- self.isManaged = ko.observable(!!notebook.isManaged);
|
|
|
- self.parentSavedQueryUuid = ko.observable(notebook.parentSavedQueryUuid); // History parent
|
|
|
- self.isSaved = ko.observable(!!notebook.isSaved);
|
|
|
- self.canWrite = ko.observable(notebook.can_write !== false);
|
|
|
- self.onSuccessUrl = ko.observable(notebook.onSuccessUrl);
|
|
|
- self.pubSubUrl = ko.observable(notebook.pubSubUrl);
|
|
|
- self.isPresentationModeDefault = ko.observable(!!notebook.isPresentationModeDefault);
|
|
|
- self.isPresentationMode = ko.observable(false);
|
|
|
- self.isPresentationModeInitialized = ko.observable(false);
|
|
|
- self.isPresentationMode.subscribe(newValue => {
|
|
|
+ this.parentVm = vm;
|
|
|
+ this.id = ko.observable(notebook.id);
|
|
|
+ this.uuid = ko.observable(notebook.uuid || hueUtils.UUID());
|
|
|
+ this.name = ko.observable(notebook.name || '');
|
|
|
+ this.description = ko.observable(notebook.description || '');
|
|
|
+ this.type = ko.observable(notebook.type || 'notebook');
|
|
|
+ this.initialType = this.type().replace('query-', '');
|
|
|
+ this.coordinatorUuid = ko.observable(notebook.coordinatorUuid);
|
|
|
+ this.isHistory = ko.observable(!!notebook.is_history);
|
|
|
+ this.isManaged = ko.observable(!!notebook.isManaged);
|
|
|
+ this.parentSavedQueryUuid = ko.observable(notebook.parentSavedQueryUuid); // History parent
|
|
|
+ this.isSaved = ko.observable(!!notebook.isSaved);
|
|
|
+ this.canWrite = ko.observable(notebook.can_write !== false);
|
|
|
+ this.onSuccessUrl = ko.observable(notebook.onSuccessUrl);
|
|
|
+ this.pubSubUrl = ko.observable(notebook.pubSubUrl);
|
|
|
+ this.isPresentationModeDefault = ko.observable(!!notebook.isPresentationModeDefault);
|
|
|
+ this.isPresentationMode = ko.observable(false);
|
|
|
+ this.isPresentationModeInitialized = ko.observable(false);
|
|
|
+ this.isPresentationMode.subscribe(newValue => {
|
|
|
if (!newValue) {
|
|
|
- self.cancelExecutingAll();
|
|
|
+ this.cancelExecutingAll();
|
|
|
}
|
|
|
huePubSub.publish('editor.presentation.operate.toggle', newValue); // Problem with headers / row numbers redraw on full screen results
|
|
|
vm.togglePresentationMode();
|
|
|
@@ -91,95 +56,95 @@ class Notebook {
|
|
|
hueAnalytics.convert('editor', 'presentation');
|
|
|
}
|
|
|
});
|
|
|
- self.presentationSnippets = ko.observable({});
|
|
|
- self.isHidingCode = ko.observable(!!notebook.isHidingCode);
|
|
|
-
|
|
|
- self.snippets = ko.observableArray();
|
|
|
- self.selectedSnippet = ko.observable(vm.editorType()); // Aka selectedSnippetType
|
|
|
- self.directoryUuid = ko.observable(notebook.directoryUuid);
|
|
|
- self.dependents = komapping.fromJS(notebook.dependents || []);
|
|
|
- self.dependentsCoordinator = ko.pureComputed(() =>
|
|
|
- self.dependents().filter(doc => doc.type() === 'oozie-coordinator2' && doc.is_managed())
|
|
|
+ this.presentationSnippets = ko.observable({});
|
|
|
+ this.isHidingCode = ko.observable(!!notebook.isHidingCode);
|
|
|
+
|
|
|
+ this.snippets = ko.observableArray();
|
|
|
+ this.selectedSnippet = ko.observable(vm.editorType()); // Aka selectedSnippetType
|
|
|
+ this.directoryUuid = ko.observable(notebook.directoryUuid);
|
|
|
+ this.dependents = komapping.fromJS(notebook.dependents || []);
|
|
|
+ this.dependentsCoordinator = ko.pureComputed(() =>
|
|
|
+ this.dependents().filter(doc => doc.type() === 'oozie-coordinator2' && doc.is_managed())
|
|
|
);
|
|
|
- if (self.dependentsCoordinator().length > 0 && !self.coordinatorUuid()) {
|
|
|
- self.coordinatorUuid(self.dependentsCoordinator()[0].uuid());
|
|
|
+ if (this.dependentsCoordinator().length > 0 && !this.coordinatorUuid()) {
|
|
|
+ this.coordinatorUuid(this.dependentsCoordinator()[0].uuid());
|
|
|
}
|
|
|
- self.history = ko.observableArray(
|
|
|
+ this.history = ko.observableArray(
|
|
|
vm.selectedNotebook() &&
|
|
|
vm.selectedNotebook().history().length > 0 &&
|
|
|
- vm.selectedNotebook().history()[0].type === self.type()
|
|
|
+ vm.selectedNotebook().history()[0].type === this.type()
|
|
|
? vm.selectedNotebook().history()
|
|
|
: []
|
|
|
);
|
|
|
|
|
|
// This is to keep the "Saved Query" tab selected when opening a doc from the left assist
|
|
|
// TODO: Refactor code to reflect purpose
|
|
|
- self.history.subscribe(val => {
|
|
|
+ this.history.subscribe(val => {
|
|
|
if (
|
|
|
- self.id() == null &&
|
|
|
- val.length == 0 &&
|
|
|
- self.historyFilter() === '' &&
|
|
|
+ this.id() == null &&
|
|
|
+ val.length === 0 &&
|
|
|
+ this.historyFilter() === '' &&
|
|
|
!vm.isNotificationManager()
|
|
|
) {
|
|
|
- self.snippets()[0].currentQueryTab('savedQueries');
|
|
|
+ this.snippets()[0].currentQueryTab('savedQueries');
|
|
|
}
|
|
|
});
|
|
|
|
|
|
- self.historyFilter = ko.observable('');
|
|
|
- self.historyFilterVisible = ko.observable(false);
|
|
|
- self.historyFilter.extend({ rateLimit: { method: 'notifyWhenChangesStop', timeout: 900 } });
|
|
|
- self.historyFilter.subscribe(() => {
|
|
|
- if (self.historyCurrentPage() !== 1) {
|
|
|
- self.historyCurrentPage(1);
|
|
|
+ this.historyFilter = ko.observable('');
|
|
|
+ this.historyFilterVisible = ko.observable(false);
|
|
|
+ this.historyFilter.extend({ rateLimit: { method: 'notifyWhenChangesStop', timeout: 900 } });
|
|
|
+ this.historyFilter.subscribe(() => {
|
|
|
+ if (this.historyCurrentPage() !== 1) {
|
|
|
+ this.historyCurrentPage(1);
|
|
|
} else {
|
|
|
- self.fetchHistory();
|
|
|
+ this.fetchHistory();
|
|
|
}
|
|
|
});
|
|
|
- self.loadingHistory = ko.observable(self.history().length === 0);
|
|
|
- self.historyInitialHeight = ko.observable(0).extend({ throttle: 1000 });
|
|
|
- self.forceHistoryInitialHeight = ko.observable(false);
|
|
|
- self.historyCurrentPage = ko.observable(
|
|
|
+ this.loadingHistory = ko.observable(this.history().length === 0);
|
|
|
+ this.historyInitialHeight = ko.observable(0).extend({ throttle: 1000 });
|
|
|
+ this.forceHistoryInitialHeight = ko.observable(false);
|
|
|
+ this.historyCurrentPage = ko.observable(
|
|
|
vm.selectedNotebook() ? vm.selectedNotebook().historyCurrentPage() : 1
|
|
|
);
|
|
|
- self.historyCurrentPage.subscribe(() => {
|
|
|
- self.fetchHistory();
|
|
|
+ this.historyCurrentPage.subscribe(() => {
|
|
|
+ this.fetchHistory();
|
|
|
});
|
|
|
- self.historyTotalPages = ko.observable(
|
|
|
+ this.historyTotalPages = ko.observable(
|
|
|
vm.selectedNotebook() ? vm.selectedNotebook().historyTotalPages() : 1
|
|
|
);
|
|
|
|
|
|
- self.schedulerViewModel = null;
|
|
|
- self.schedulerViewModelIsLoaded = ko.observable(false);
|
|
|
- self.schedulerViewerViewModel = ko.observable();
|
|
|
- self.isBatchable = ko.pureComputed(
|
|
|
- () => self.snippets().length > 0 && self.snippets().every(snippet => snippet.isBatchable())
|
|
|
+ this.schedulerViewModel = null;
|
|
|
+ this.schedulerViewModelIsLoaded = ko.observable(false);
|
|
|
+ this.schedulerViewerViewModel = ko.observable();
|
|
|
+ this.isBatchable = ko.pureComputed(
|
|
|
+ () => this.snippets().length > 0 && this.snippets().every(snippet => snippet.isBatchable())
|
|
|
);
|
|
|
|
|
|
- self.isExecutingAll = ko.observable(!!notebook.isExecutingAll);
|
|
|
+ this.isExecutingAll = ko.observable(!!notebook.isExecutingAll);
|
|
|
|
|
|
- self.executingAllIndex = ko.observable(notebook.executingAllIndex || 0);
|
|
|
+ this.executingAllIndex = ko.observable(notebook.executingAllIndex || 0);
|
|
|
|
|
|
- self.retryModalConfirm = null;
|
|
|
- self.retryModalCancel = null;
|
|
|
+ this.retryModalConfirm = null;
|
|
|
+ this.retryModalCancel = null;
|
|
|
|
|
|
- self.avoidClosing = false;
|
|
|
+ this.avoidClosing = false;
|
|
|
|
|
|
- self.canSave = vm.canSave;
|
|
|
+ this.canSave = vm.canSave;
|
|
|
|
|
|
- self.unloaded = ko.observable(false);
|
|
|
- self.updateHistoryFailed = false;
|
|
|
+ this.unloaded = ko.observable(false);
|
|
|
+ this.updateHistoryFailed = false;
|
|
|
|
|
|
- self.viewSchedulerId = ko.observable(notebook.viewSchedulerId || '');
|
|
|
- self.viewSchedulerId.subscribe(() => {
|
|
|
- self.save();
|
|
|
+ this.viewSchedulerId = ko.observable(notebook.viewSchedulerId || '');
|
|
|
+ this.viewSchedulerId.subscribe(() => {
|
|
|
+ this.save();
|
|
|
});
|
|
|
- self.isSchedulerJobRunning = ko.observable();
|
|
|
- self.loadingScheduler = ko.observable(false);
|
|
|
+ this.isSchedulerJobRunning = ko.observable();
|
|
|
+ this.loadingScheduler = ko.observable(false);
|
|
|
|
|
|
// Init
|
|
|
if (notebook.snippets) {
|
|
|
notebook.snippets.forEach(snippet => {
|
|
|
- self.addSnippet(snippet);
|
|
|
+ this.addSnippet(snippet);
|
|
|
});
|
|
|
if (
|
|
|
typeof notebook.presentationSnippets != 'undefined' &&
|
|
|
@@ -188,16 +153,16 @@ class Notebook {
|
|
|
// Load
|
|
|
$.each(notebook.presentationSnippets, (key, snippet) => {
|
|
|
snippet.status = 'ready'; // Protect from storm of check_statuses
|
|
|
- const _snippet = new Snippet(vm, self, snippet);
|
|
|
+ const _snippet = new Snippet(vm, this, snippet);
|
|
|
_snippet.init();
|
|
|
_snippet.previousChartOptions = vm.getPreviousChartOptions(_snippet);
|
|
|
- self.presentationSnippets()[key] = _snippet;
|
|
|
+ this.presentationSnippets()[key] = _snippet;
|
|
|
});
|
|
|
}
|
|
|
- if (vm.editorMode() && self.history().length === 0) {
|
|
|
- self.fetchHistory(() => {
|
|
|
- self.updateHistory(['starting', 'running'], 30000);
|
|
|
- self.updateHistory(['available'], 60000 * 5);
|
|
|
+ if (vm.editorMode() && this.history().length === 0) {
|
|
|
+ this.fetchHistory(() => {
|
|
|
+ this.updateHistory(['starting', 'running'], 30000);
|
|
|
+ this.updateHistory(['available'], 60000 * 5);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
@@ -205,7 +170,7 @@ class Notebook {
|
|
|
huePubSub.subscribeOnce(
|
|
|
'assist.db.panel.ready',
|
|
|
() => {
|
|
|
- if (self.type().indexOf('query') === 0) {
|
|
|
+ if (this.type().indexOf('query') === 0) {
|
|
|
const whenDatabaseAvailable = function(snippet) {
|
|
|
huePubSub.publish('assist.set.database', {
|
|
|
source: snippet.type(),
|
|
|
@@ -236,10 +201,10 @@ class Notebook {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- if (self.snippets().length === 1) {
|
|
|
- whenSnippetAvailable(self.snippets()[0]);
|
|
|
+ if (this.snippets().length === 1) {
|
|
|
+ whenSnippetAvailable(this.snippets()[0]);
|
|
|
} else {
|
|
|
- const snippetsSub = self.snippets.subscribe(snippets => {
|
|
|
+ const snippetsSub = this.snippets.subscribe(snippets => {
|
|
|
if (snippets.length === 1) {
|
|
|
whenSnippetAvailable(snippets[0]);
|
|
|
}
|
|
|
@@ -255,37 +220,34 @@ class Notebook {
|
|
|
}
|
|
|
|
|
|
addSnippet(snippet) {
|
|
|
- const self = this;
|
|
|
- const newSnippet = new Snippet(self.parentVm, self, snippet);
|
|
|
- self.snippets.push(newSnippet);
|
|
|
+ const newSnippet = new Snippet(this.parentVm, this, snippet);
|
|
|
+ this.snippets.push(newSnippet);
|
|
|
newSnippet.init();
|
|
|
return newSnippet;
|
|
|
}
|
|
|
|
|
|
cancelExecutingAll() {
|
|
|
- const self = this;
|
|
|
- const index = self.executingAllIndex();
|
|
|
- if (self.isExecutingAll() && self.snippets()[index]) {
|
|
|
- self.snippets()[index].cancel();
|
|
|
+ const index = this.executingAllIndex();
|
|
|
+ if (this.isExecutingAll() && this.snippets()[index]) {
|
|
|
+ this.snippets()[index].cancel();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
clearHistory() {
|
|
|
- const self = this;
|
|
|
hueAnalytics.log('notebook', 'clearHistory');
|
|
|
apiHelper
|
|
|
.clearNotebookHistory({
|
|
|
- notebookJson: komapping.toJSON(self.getContext(), NOTEBOOK_MAPPING),
|
|
|
- docType: self.selectedSnippet(),
|
|
|
- isNotificationManager: self.parentVm.isNotificationManager()
|
|
|
+ notebookJson: notebookToContextJSON(this),
|
|
|
+ docType: this.selectedSnippet(),
|
|
|
+ isNotificationManager: this.parentVm.isNotificationManager()
|
|
|
})
|
|
|
.then(() => {
|
|
|
- self.history.removeAll();
|
|
|
- if (self.isHistory()) {
|
|
|
- self.id(null);
|
|
|
- self.uuid(hueUtils.UUID());
|
|
|
- self.parentVm.changeURL(
|
|
|
- self.parentVm.URLS.editor + '?type=' + self.parentVm.editorType()
|
|
|
+ this.history.removeAll();
|
|
|
+ if (this.isHistory()) {
|
|
|
+ this.id(null);
|
|
|
+ this.uuid(hueUtils.UUID());
|
|
|
+ this.parentVm.changeURL(
|
|
|
+ this.parentVm.URLS.editor + '?type=' + this.parentVm.editorType()
|
|
|
);
|
|
|
}
|
|
|
})
|
|
|
@@ -298,54 +260,50 @@ class Notebook {
|
|
|
}
|
|
|
|
|
|
clearResults() {
|
|
|
- const self = this;
|
|
|
- self.snippets().forEach(snippet => {
|
|
|
+ this.snippets().forEach(snippet => {
|
|
|
snippet.result.clear();
|
|
|
snippet.status(SNIPPET_STATUS.ready);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
close() {
|
|
|
- const self = this;
|
|
|
hueAnalytics.log('notebook', 'close');
|
|
|
apiHelper.closeNotebook({
|
|
|
- notebookJson: komapping.toJSON(self, NOTEBOOK_MAPPING),
|
|
|
- editorMode: self.parentVm.editorMode()
|
|
|
+ notebookJson: notebookToJSON(this),
|
|
|
+ editorMode: this.parentVm.editorMode()
|
|
|
});
|
|
|
}
|
|
|
|
|
|
executeAll() {
|
|
|
- const self = this;
|
|
|
- if (self.isExecutingAll() || self.snippets().length === 0) {
|
|
|
+ if (this.isExecutingAll() || this.snippets().length === 0) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- self.isExecutingAll(true);
|
|
|
- self.executingAllIndex(0);
|
|
|
+ this.isExecutingAll(true);
|
|
|
+ this.executingAllIndex(0);
|
|
|
|
|
|
- self.snippets()[self.executingAllIndex()].execute();
|
|
|
+ this.snippets()[this.executingAllIndex()].execute();
|
|
|
}
|
|
|
|
|
|
fetchHistory(callback) {
|
|
|
- const self = this;
|
|
|
const QUERIES_PER_PAGE = 50;
|
|
|
- self.loadingHistory(true);
|
|
|
+ this.loadingHistory(true);
|
|
|
|
|
|
$.get(
|
|
|
'/notebook/api/get_history',
|
|
|
{
|
|
|
- doc_type: self.selectedSnippet(),
|
|
|
+ doc_type: this.selectedSnippet(),
|
|
|
limit: QUERIES_PER_PAGE,
|
|
|
- page: self.historyCurrentPage(),
|
|
|
- doc_text: self.historyFilter(),
|
|
|
- is_notification_manager: self.parentVm.isNotificationManager()
|
|
|
+ page: this.historyCurrentPage(),
|
|
|
+ doc_text: this.historyFilter(),
|
|
|
+ is_notification_manager: this.parentVm.isNotificationManager()
|
|
|
},
|
|
|
data => {
|
|
|
const parsedHistory = [];
|
|
|
if (data && data.history) {
|
|
|
data.history.forEach(nbk => {
|
|
|
parsedHistory.push(
|
|
|
- self.makeHistoryRecord(
|
|
|
+ this.makeHistoryRecord(
|
|
|
nbk.absoluteUrl,
|
|
|
nbk.data.statement,
|
|
|
nbk.data.lastExecuted,
|
|
|
@@ -356,39 +314,25 @@ class Notebook {
|
|
|
);
|
|
|
});
|
|
|
}
|
|
|
- self.history(parsedHistory);
|
|
|
- self.historyTotalPages(Math.ceil(data.count / QUERIES_PER_PAGE));
|
|
|
+ this.history(parsedHistory);
|
|
|
+ this.historyTotalPages(Math.ceil(data.count / QUERIES_PER_PAGE));
|
|
|
}
|
|
|
).always(() => {
|
|
|
- self.loadingHistory(false);
|
|
|
+ this.loadingHistory(false);
|
|
|
if (callback) {
|
|
|
callback();
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- getContext() {
|
|
|
- const self = this;
|
|
|
- return {
|
|
|
- id: self.id,
|
|
|
- uuid: self.uuid,
|
|
|
- parentSavedQueryUuid: self.parentSavedQueryUuid,
|
|
|
- isSaved: self.isSaved,
|
|
|
- type: self.type,
|
|
|
- name: self.name
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
getSnippets(type) {
|
|
|
- const self = this;
|
|
|
- return self.snippets().filter(snippet => snippet.type() === type);
|
|
|
+ return this.snippets().filter(snippet => snippet.type() === type);
|
|
|
}
|
|
|
|
|
|
loadScheduler() {
|
|
|
- const self = this;
|
|
|
- if (typeof self.parentVm.CoordinatorEditorViewModel !== 'undefined' && self.isBatchable()) {
|
|
|
+ if (typeof this.parentVm.CoordinatorEditorViewModel !== 'undefined' && this.isBatchable()) {
|
|
|
let action;
|
|
|
- if (self.coordinatorUuid()) {
|
|
|
+ if (this.coordinatorUuid()) {
|
|
|
action = 'edit';
|
|
|
} else {
|
|
|
action = 'new';
|
|
|
@@ -400,8 +344,8 @@ class Notebook {
|
|
|
'/scheduler/api/schedule/' + action + '/',
|
|
|
{
|
|
|
format: 'json',
|
|
|
- document: self.uuid(),
|
|
|
- coordinator: self.coordinatorUuid()
|
|
|
+ document: this.uuid(),
|
|
|
+ coordinator: this.coordinatorUuid()
|
|
|
},
|
|
|
data => {
|
|
|
if ($('#schedulerEditor').length > 0) {
|
|
|
@@ -411,7 +355,7 @@ class Notebook {
|
|
|
const $schedulerEditor = $('#schedulerEditor');
|
|
|
$schedulerEditor.html(r);
|
|
|
|
|
|
- self.schedulerViewModel = new self.parentVm.CoordinatorEditorViewModel(
|
|
|
+ this.schedulerViewModel = new this.parentVm.CoordinatorEditorViewModel(
|
|
|
data.coordinator,
|
|
|
data.credentials,
|
|
|
data.workflows,
|
|
|
@@ -419,7 +363,7 @@ class Notebook {
|
|
|
);
|
|
|
|
|
|
ko.cleanNode($schedulerEditor[0]);
|
|
|
- ko.applyBindings(self.schedulerViewModel, $schedulerEditor[0]);
|
|
|
+ ko.applyBindings(this.schedulerViewModel, $schedulerEditor[0]);
|
|
|
$(document).off('showSubmitPopup');
|
|
|
$(document).on('showSubmitPopup', (event, data) => {
|
|
|
const $submitModalEditor = $('.submit-modal-editor');
|
|
|
@@ -437,14 +381,14 @@ class Notebook {
|
|
|
|
|
|
huePubSub.publish('render.jqcron');
|
|
|
|
|
|
- self.schedulerViewModel.coordinator.properties.cron_advanced.valueHasMutated(); // Update jsCron enabled status
|
|
|
- self.schedulerViewModel.coordinator.tracker().markCurrentStateAsClean();
|
|
|
- self.schedulerViewModel.isEditing(true);
|
|
|
+ this.schedulerViewModel.coordinator.properties.cron_advanced.valueHasMutated(); // Update jsCron enabled status
|
|
|
+ this.schedulerViewModel.coordinator.tracker().markCurrentStateAsClean();
|
|
|
+ this.schedulerViewModel.isEditing(true);
|
|
|
|
|
|
- self.schedulerViewModelIsLoaded(true);
|
|
|
+ this.schedulerViewModelIsLoaded(true);
|
|
|
|
|
|
if (action === 'new') {
|
|
|
- self.schedulerViewModel.coordinator.properties.document(self.uuid()); // Expected for triggering the display
|
|
|
+ this.schedulerViewModel.coordinator.properties.document(this.uuid()); // Expected for triggering the display
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
@@ -473,12 +417,11 @@ class Notebook {
|
|
|
}
|
|
|
|
|
|
newSnippet(type) {
|
|
|
- const self = this;
|
|
|
if (type) {
|
|
|
- self.selectedSnippet(type);
|
|
|
+ this.selectedSnippet(type);
|
|
|
}
|
|
|
- const snippet = self.addSnippet({
|
|
|
- type: self.selectedSnippet(),
|
|
|
+ const snippet = this.addSnippet({
|
|
|
+ type: this.selectedSnippet(),
|
|
|
result: {}
|
|
|
});
|
|
|
|
|
|
@@ -489,152 +432,127 @@ class Notebook {
|
|
|
}
|
|
|
}, 100);
|
|
|
|
|
|
- hueAnalytics.log('notebook', 'add_snippet/' + (type ? type : self.selectedSnippet()));
|
|
|
+ hueAnalytics.log('notebook', 'add_snippet/' + (type ? type : this.selectedSnippet()));
|
|
|
return snippet;
|
|
|
}
|
|
|
|
|
|
newSnippetAbove(id) {
|
|
|
- const self = this;
|
|
|
- self.newSnippet();
|
|
|
+ this.newSnippet();
|
|
|
let idx = 0;
|
|
|
- self.snippets().forEach((snippet, cnt) => {
|
|
|
+ this.snippets().forEach((snippet, cnt) => {
|
|
|
if (snippet.id() === id) {
|
|
|
idx = cnt;
|
|
|
}
|
|
|
});
|
|
|
- self.snippets(self.snippets().move(self.snippets().length - 1, idx));
|
|
|
+ this.snippets(this.snippets().move(this.snippets().length - 1, idx));
|
|
|
}
|
|
|
|
|
|
nextHistoryPage() {
|
|
|
- const self = this;
|
|
|
- if (self.historyCurrentPage() < self.historyTotalPages()) {
|
|
|
- self.historyCurrentPage(self.historyCurrentPage() + 1);
|
|
|
+ if (this.historyCurrentPage() < this.historyTotalPages()) {
|
|
|
+ this.historyCurrentPage(this.historyCurrentPage() + 1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
prevHistoryPage() {
|
|
|
- const self = this;
|
|
|
- if (self.historyCurrentPage() !== 1) {
|
|
|
- self.historyCurrentPage(self.historyCurrentPage() - 1);
|
|
|
+ if (this.historyCurrentPage() !== 1) {
|
|
|
+ this.historyCurrentPage(this.historyCurrentPage() - 1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- save(callback) {
|
|
|
- const self = this;
|
|
|
+ async save(callback) {
|
|
|
hueAnalytics.log('notebook', 'save');
|
|
|
|
|
|
- // Remove the result data from the snippets
|
|
|
- // Also do it for presentation mode
|
|
|
- const cp = komapping.toJS(self, NOTEBOOK_MAPPING);
|
|
|
- cp.snippets
|
|
|
- .concat(Object.keys(cp.presentationSnippets).map(key => cp.presentationSnippets[key]))
|
|
|
- .forEach(snippet => {
|
|
|
- snippet.result.data.length = 0; // snippet.result.clear() does not work for some reason
|
|
|
- snippet.result.meta.length = 0;
|
|
|
- snippet.result.logs = '';
|
|
|
- snippet.result.fetchedOnce = false;
|
|
|
- snippet.progress = 0; // Remove progress
|
|
|
- snippet.jobs.length = 0;
|
|
|
- });
|
|
|
- if (cp.schedulerViewModel) {
|
|
|
- cp.schedulerViewModel.availableTimezones = [];
|
|
|
- }
|
|
|
const editorMode =
|
|
|
- self.parentVm.editorMode() ||
|
|
|
- (self.isPresentationMode() && self.parentVm.editorType() !== 'notebook'); // Editor should not convert to Notebook in presentation mode
|
|
|
+ this.parentVm.editorMode() ||
|
|
|
+ (this.isPresentationMode() && this.parentVm.editorType() !== 'notebook'); // Editor should not convert to Notebook in presentation mode
|
|
|
|
|
|
- apiHelper
|
|
|
- .saveNotebook({
|
|
|
- notebookJson: komapping.toJSON(cp, NOTEBOOK_MAPPING),
|
|
|
+ try {
|
|
|
+ const data = await apiHelper.saveNotebook({
|
|
|
+ notebookJson: notebookToJSON(this),
|
|
|
editorMode: editorMode
|
|
|
- })
|
|
|
- .then(data => {
|
|
|
- if (data.status === 0) {
|
|
|
- self.id(data.id);
|
|
|
- self.isSaved(true);
|
|
|
- const wasHistory = self.isHistory();
|
|
|
- self.isHistory(false);
|
|
|
- $(document).trigger('info', data.message);
|
|
|
- if (editorMode) {
|
|
|
- if (!data.save_as) {
|
|
|
- const existingQuery = self
|
|
|
- .snippets()[0]
|
|
|
- .queries()
|
|
|
- .filter(item => item.uuid() === data.uuid);
|
|
|
- if (existingQuery.length > 0) {
|
|
|
- existingQuery[0].name(data.name);
|
|
|
- existingQuery[0].description(data.description);
|
|
|
- existingQuery[0].last_modified(data.last_modified);
|
|
|
- }
|
|
|
- } else if (self.snippets()[0].queries().length > 0) {
|
|
|
- // Saved queries tab already loaded
|
|
|
- self.snippets()[0].queries.unshift(komapping.fromJS(data));
|
|
|
- }
|
|
|
+ });
|
|
|
|
|
|
- if (self.coordinatorUuid() && self.schedulerViewModel) {
|
|
|
- self.saveScheduler();
|
|
|
- self.schedulerViewModel.coordinator.refreshParameters();
|
|
|
- }
|
|
|
- if (wasHistory || data.save_as) {
|
|
|
- self.loadScheduler();
|
|
|
+ if (data.status === 0) {
|
|
|
+ this.id(data.id);
|
|
|
+ this.isSaved(true);
|
|
|
+ const wasHistory = this.isHistory();
|
|
|
+ this.isHistory(false);
|
|
|
+ $(document).trigger('info', data.message);
|
|
|
+ if (editorMode) {
|
|
|
+ if (!data.save_as) {
|
|
|
+ const existingQuery = this.snippets()[0]
|
|
|
+ .queries()
|
|
|
+ .filter(item => item.uuid() === data.uuid);
|
|
|
+ if (existingQuery.length > 0) {
|
|
|
+ existingQuery[0].name(data.name);
|
|
|
+ existingQuery[0].description(data.description);
|
|
|
+ existingQuery[0].last_modified(data.last_modified);
|
|
|
}
|
|
|
+ } else if (this.snippets()[0].queries().length > 0) {
|
|
|
+ // Saved queries tab already loaded
|
|
|
+ this.snippets()[0].queries.unshift(komapping.fromJS(data));
|
|
|
+ }
|
|
|
|
|
|
- if (
|
|
|
- self.snippets()[0].downloadResultViewModel &&
|
|
|
- self
|
|
|
- .snippets()[0]
|
|
|
- .downloadResultViewModel()
|
|
|
- .saveTarget() === 'dashboard'
|
|
|
- ) {
|
|
|
- huePubSub.publish(
|
|
|
- 'open.link',
|
|
|
- self.parentVm.URLS.report +
|
|
|
- '&uuid=' +
|
|
|
- data.uuid +
|
|
|
- '&statement=' +
|
|
|
- self.snippets()[0].result.handle().statement_id
|
|
|
- );
|
|
|
- } else {
|
|
|
- self.parentVm.changeURL(self.parentVm.URLS.editor + '?editor=' + data.id);
|
|
|
- }
|
|
|
- } else {
|
|
|
- self.parentVm.changeURL(self.parentVm.URLS.notebook + '?notebook=' + data.id);
|
|
|
+ if (this.coordinatorUuid() && this.schedulerViewModel) {
|
|
|
+ this.saveScheduler();
|
|
|
+ this.schedulerViewModel.coordinator.refreshParameters();
|
|
|
+ }
|
|
|
+ if (wasHistory || data.save_as) {
|
|
|
+ this.loadScheduler();
|
|
|
}
|
|
|
- if (typeof callback == 'function') {
|
|
|
- callback();
|
|
|
+
|
|
|
+ if (
|
|
|
+ this.snippets()[0].downloadResultViewModel &&
|
|
|
+ this.snippets()[0]
|
|
|
+ .downloadResultViewModel()
|
|
|
+ .saveTarget() === 'dashboard'
|
|
|
+ ) {
|
|
|
+ huePubSub.publish(
|
|
|
+ 'open.link',
|
|
|
+ this.parentVm.URLS.report +
|
|
|
+ '&uuid=' +
|
|
|
+ data.uuid +
|
|
|
+ '&statement=' +
|
|
|
+ this.snippets()[0].result.handle().statement_id
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ this.parentVm.changeURL(this.parentVm.URLS.editor + '?editor=' + data.id);
|
|
|
}
|
|
|
} else {
|
|
|
- $(document).trigger('error', data.message);
|
|
|
+ this.parentVm.changeURL(this.parentVm.URLS.notebook + '?notebook=' + data.id);
|
|
|
}
|
|
|
- })
|
|
|
- .fail(xhr => {
|
|
|
- if (xhr.status !== 502) {
|
|
|
- $(document).trigger('error', xhr.responseText);
|
|
|
+ if (typeof callback == 'function') {
|
|
|
+ callback();
|
|
|
}
|
|
|
- });
|
|
|
+ } else {
|
|
|
+ $(document).trigger('error', data.message);
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ if (err && err.status !== 502) {
|
|
|
+ $(document).trigger('error', err.responseText);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
saveScheduler() {
|
|
|
- const self = this;
|
|
|
if (
|
|
|
- self.isBatchable() &&
|
|
|
- (!self.coordinatorUuid() || self.schedulerViewModel.coordinator.isDirty())
|
|
|
+ this.isBatchable() &&
|
|
|
+ (!this.coordinatorUuid() || this.schedulerViewModel.coordinator.isDirty())
|
|
|
) {
|
|
|
- self.schedulerViewModel.coordinator.isManaged(true);
|
|
|
- self.schedulerViewModel.coordinator.properties.document(self.uuid());
|
|
|
- self.schedulerViewModel.save(data => {
|
|
|
- if (!self.coordinatorUuid()) {
|
|
|
- self.coordinatorUuid(data.uuid);
|
|
|
- self.save();
|
|
|
+ this.schedulerViewModel.coordinator.isManaged(true);
|
|
|
+ this.schedulerViewModel.coordinator.properties.document(this.uuid());
|
|
|
+ this.schedulerViewModel.save(data => {
|
|
|
+ if (!this.coordinatorUuid()) {
|
|
|
+ this.coordinatorUuid(data.uuid);
|
|
|
+ this.save();
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
showSubmitPopup() {
|
|
|
- const self = this;
|
|
|
$.get(
|
|
|
- '/scheduler/api/submit/' + self.coordinatorUuid(),
|
|
|
+ '/scheduler/api/submit/' + this.coordinatorUuid(),
|
|
|
{
|
|
|
format: 'json'
|
|
|
},
|
|
|
@@ -649,10 +567,9 @@ class Notebook {
|
|
|
}
|
|
|
|
|
|
unload() {
|
|
|
- const self = this;
|
|
|
- self.unloaded(true);
|
|
|
+ this.unloaded(true);
|
|
|
let currentQueries = null;
|
|
|
- self.snippets().forEach(snippet => {
|
|
|
+ this.snippets().forEach(snippet => {
|
|
|
if (snippet.checkStatusTimeout != null) {
|
|
|
clearTimeout(snippet.checkStatusTimeout);
|
|
|
snippet.checkStatusTimeout = null;
|
|
|
@@ -665,9 +582,7 @@ class Notebook {
|
|
|
}
|
|
|
|
|
|
updateHistory(statuses, interval) {
|
|
|
- const self = this;
|
|
|
- let items = self
|
|
|
- .history()
|
|
|
+ let items = this.history()
|
|
|
.filter(item => statuses.indexOf(item.status()) !== -1)
|
|
|
.slice(0, 25);
|
|
|
|
|
|
@@ -687,7 +602,7 @@ class Notebook {
|
|
|
})
|
|
|
.fail(() => {
|
|
|
items = [];
|
|
|
- self.updateHistoryFailed = true;
|
|
|
+ this.updateHistoryFailed = true;
|
|
|
console.warn('Lost connectivity to the Hue history refresh backend.');
|
|
|
})
|
|
|
.always(() => {
|
|
|
@@ -695,9 +610,9 @@ class Notebook {
|
|
|
window.setTimeout(() => {
|
|
|
updateHistoryCall(items.pop());
|
|
|
}, 1000);
|
|
|
- } else if (!self.updateHistoryFailed) {
|
|
|
+ } else if (!this.updateHistoryFailed) {
|
|
|
window.setTimeout(() => {
|
|
|
- self.updateHistory(statuses, interval);
|
|
|
+ this.updateHistory(statuses, interval);
|
|
|
}, interval);
|
|
|
}
|
|
|
});
|
|
|
@@ -705,12 +620,10 @@ class Notebook {
|
|
|
|
|
|
if (items.length > 0) {
|
|
|
updateHistoryCall(items.pop());
|
|
|
- } else if (!self.updateHistoryFailed) {
|
|
|
+ } else if (!this.updateHistoryFailed) {
|
|
|
window.setTimeout(() => {
|
|
|
- self.updateHistory(statuses, interval);
|
|
|
+ this.updateHistory(statuses, interval);
|
|
|
}, interval);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-export { Notebook, NOTEBOOK_MAPPING };
|