浏览代码

HUE-9352 [editor] Wait with showing the execute button until the session is loaded in editor v2

Johan Ahlen 5 年之前
父节点
当前提交
7a5f68fa5f

+ 38 - 13
desktop/core/src/desktop/js/apps/notebook2/components/ko.executableActions.js

@@ -21,6 +21,7 @@ import DisposableComponent from 'ko/components/DisposableComponent';
 import huePubSub from 'utils/huePubSub';
 import I18n from 'utils/i18n';
 import { EXECUTABLE_UPDATED_EVENT, EXECUTION_STATUS } from 'apps/notebook2/execution/executable';
+import sessionManager from 'apps/notebook2/execution/sessionManager';
 
 export const NAME = 'executable-actions';
 
@@ -30,24 +31,32 @@ export const EXECUTE_ACTIVE_EXECUTABLE_EVENT = 'executable.active.executable';
 const TEMPLATE = `
 <div class="snippet-execute-actions" data-test="${ NAME }">
   <div class="btn-group">
+    <!-- ko if: showLoading -->
+    <button class="btn btn-primary btn-mini btn-execute disable-feedback" disabled title="${ I18n('Creating session') }">
+      <i class="fa fa-fw fa-spinner fa-spin"></i> ${ I18n('Loading') }
+    </button>
+    <!-- /ko -->
     <!-- ko if: showExecute -->
-    <button class="btn btn-primary btn-mini btn-execute disable-feedback" data-test="execute" data-bind="click: execute, disable: disabled"><i class="fa fa-play fa-fw"></i> ${I18n(
-      'Execute'
-    )}</button>
+    <button class="btn btn-primary btn-mini btn-execute disable-feedback" data-test="execute" data-bind="click: execute, disable: disabled">
+      <i class="fa fa-fw fa-play"></i> ${ I18n('Execute') }
+    </button>
     <!-- /ko -->
     <!-- ko if: showStop -->
       <!-- ko ifnot: stopping -->
-      <button class="btn btn-danger btn-mini btn-execute disable-feedback" data-test="stop" data-bind="click: stop"><i class="fa fa-stop fa-fw"></i>
-      <!-- ko ifnot: waiting -->
-        ${ I18n('Stop') }
-      <!-- /ko -->
-      <!-- ko if: waiting -->
-        ${ I18n('Stop batch') }
-      <!-- /ko -->
+      <button class="btn btn-danger btn-mini btn-execute disable-feedback" data-test="stop" data-bind="click: stop">
+        <i class="fa fa-stop fa-fw"></i>
+        <!-- ko ifnot: waiting -->
+          ${ I18n('Stop') }
+        <!-- /ko -->
+        <!-- ko if: waiting -->
+          ${ I18n('Stop batch') }
+        <!-- /ko -->
       </button>
       <!-- /ko -->
       <!-- ko if: stopping -->
-      <button class="btn btn-primary btn-mini btn-execute disable-feedback disabled"><i class="fa fa-spinner fa-spin fa-fw"></i>${ I18n('Stopping') }</button>
+      <button class="btn btn-primary btn-mini btn-execute disable-feedback disabled">
+        <i class="fa fa-fw fa-spinner fa-spin"></i> ${ I18n('Stopping') }
+      </button>
       <!-- /ko -->
     <!-- /ko -->
   </div>
@@ -68,6 +77,8 @@ class ExecutableActions extends DisposableComponent {
     this.partOfRunningExecution = ko.observable(false);
     this.beforeExecute = params.beforeExecute;
 
+    this.lastSession = ko.observable();
+
     this.limit = ko.observable();
 
     this.subscribe(this.limit, newVal => {
@@ -83,12 +94,16 @@ class ExecutableActions extends DisposableComponent {
         this.partOfRunningExecution()
     );
 
+    this.showLoading = ko.pureComputed(() => !this.lastSession());
+
     this.showExecute = ko.pureComputed(
       () =>
+        !this.showLoading() &&
         this.status() !== EXECUTION_STATUS.running &&
         this.status() !== EXECUTION_STATUS.streaming &&
         !this.waiting()
     );
+
     this.showStop = ko.pureComputed(
       () =>
         this.status() === EXECUTION_STATUS.running ||
@@ -100,8 +115,10 @@ class ExecutableActions extends DisposableComponent {
       const executable = this.activeExecutable();
 
       return (
-        !executable ||
-        (executable.parsedStatement && WHITE_SPACE_REGEX.test(executable.parsedStatement.statement))
+        !this.lastSession() ||
+        (!executable ||
+          (executable.parsedStatement &&
+            WHITE_SPACE_REGEX.test(executable.parsedStatement.statement)))
       );
     });
 
@@ -125,9 +142,17 @@ class ExecutableActions extends DisposableComponent {
   }
 
   updateFromExecutable(executable) {
+    const waitForSession =
+      !this.lastSession() || this.lastSession().type !== executable.executor.connector().type;
     this.status(executable.status);
     this.partOfRunningExecution(executable.isPartOfRunningExecution());
     this.limit(executable.executor.defaultLimit());
+    if (waitForSession) {
+      this.lastSession(undefined);
+      sessionManager
+        .getSession({ type: executable.executor.connector().id })
+        .then(this.lastSession);
+    }
   }
 
   async stop() {

+ 18 - 2
desktop/core/src/desktop/js/apps/notebook2/components/ko.executableActions.test.js

@@ -3,11 +3,15 @@ import { koSetup } from 'jest/koTestUtils';
 import { NAME } from './ko.executableActions';
 import { EXECUTABLE_UPDATED_EVENT, EXECUTION_STATUS } from 'apps/notebook2/execution/executable';
 import { sleep } from 'utils/hueUtils';
+import sessionManager from 'apps/notebook2/execution/sessionManager';
 
 describe('ko.executableActions.js', () => {
   const setup = koSetup();
 
   it('should render component', async () => {
+    const spy = spyOn(sessionManager, 'getSession').and.returnValue(
+      Promise.resolve({ type: 'foo' })
+    );
     const mockExecutable = {
       cancel: () => {},
       cancelBatchChain: () => {},
@@ -17,7 +21,10 @@ describe('ko.executableActions.js', () => {
       reset: () => {},
       nextExecutable: {},
       executor: {
-        defaultLimit: () => {}
+        defaultLimit: () => {},
+        connector: () => ({
+          id: 'foo'
+        })
       },
       status: EXECUTION_STATUS.ready
     };
@@ -27,10 +34,14 @@ describe('ko.executableActions.js', () => {
       activeExecutable: activeExecutable
     });
 
+    expect(spy).toHaveBeenCalled();
     expect(element.querySelector('[data-test="' + NAME + '"]')).toBeTruthy();
   });
 
   it('should handle execute and stop clicks', async () => {
+    const spy = spyOn(sessionManager, 'getSession').and.returnValue(
+      Promise.resolve({ type: 'foo' })
+    );
     let executeCalled = false;
     let cancelCalled = false;
     const mockExecutable = {
@@ -48,7 +59,10 @@ describe('ko.executableActions.js', () => {
       reset: () => {},
       nextExecutable: {},
       executor: {
-        defaultLimit: () => {}
+        defaultLimit: () => {},
+        connector: () => ({
+          id: 'foo'
+        })
       },
       status: EXECUTION_STATUS.ready
     };
@@ -58,6 +72,8 @@ describe('ko.executableActions.js', () => {
       activeExecutable: activeExecutable
     });
 
+    expect(spy).toHaveBeenCalled();
+
     // Click play
     expect(executeCalled).toBeFalsy();
     expect(wrapper.querySelector('[data-test="execute"]')).toBeTruthy();