Bläddra i källkod

[frontend] Add execution logs to the SQL scratchpad component

Johan Åhlén 4 år sedan
förälder
incheckning
3d749397d4

+ 1 - 1
desktop/core/src/desktop/js/apps/editor/components/executionAnalysis/ExecutionAnalysisPanel.vue

@@ -97,7 +97,7 @@
       }, 5);
 
       const updateFromExecutable = (executable: Executable): void => {
-        if (props.executable.id !== executable.id) {
+        if (!props.executable || props.executable.id !== executable.id) {
           return;
         }
         debouncedUpdate.cancel();

+ 2 - 0
desktop/core/src/desktop/js/apps/editor/components/sqlScratchpad/SqlScratchpad.scss

@@ -48,9 +48,11 @@
       }
     }
 
+    .sql-scratchpad-logs,
     .sql-scratchpad-result {
       @include flex(0 1 50%);
 
+      position: relative;
       overflow: hidden;
 
       h1 {

+ 53 - 3
desktop/core/src/desktop/js/apps/editor/components/sqlScratchpad/SqlScratchpad.vue

@@ -37,10 +37,24 @@
       <div class="sql-scratchpad-actions">
         <ExecuteButton :executable="activeExecutable" />
         <ExecuteLimitInput :executable="activeExecutable" />
+        <HueButton
+          :style="{ float: 'right' }"
+          :small="true"
+          @click="
+            () => {
+              logsVisible = !logsVisible;
+            }
+          "
+        >
+          {{ logsVisible ? 'Result' : 'Logs' }}
+        </HueButton>
       </div>
-      <div class="sql-scratchpad-result">
+      <div v-show="!logsVisible" class="sql-scratchpad-result">
         <ResultTable :executable="activeExecutable" />
       </div>
+      <div v-show="logsVisible" class="sql-scratchpad-logs">
+        <ExecutionAnalysisPanel :executable="activeExecutable" />
+      </div>
     </div>
     <div v-else-if="!loading && !executor && errorMessage">
       {{ errorMessage }}
@@ -54,16 +68,24 @@
   import KnockoutObservable from '@types/knockout';
 
   import genericAutocompleteParser from 'parse/sql/generic/genericAutocompleteParser';
-  import genericSyntaxParser from 'parse/sql/generic/genericSyntaxParser';
   import { SqlParserProvider } from 'parse/types';
   import { SqlReferenceProvider } from 'sql/reference/types';
 
   import './SqlScratchpad.scss';
+  import {
+    EXECUTABLE_LOGS_UPDATED_TOPIC,
+    EXECUTABLE_TRANSITIONED_TOPIC,
+    ExecutableLogsUpdatedEvent,
+    ExecutableTransitionedEvent
+  } from '../../execution/events';
+  import { ExecutionStatus } from '../../execution/executable';
+  import ExecutionLogs from '../../execution/executionLogs';
   import AceEditor from '../aceEditor/AceEditor.vue';
   import { ActiveStatementChangedEventDetails } from '../aceEditor/types';
   import ExecutableProgressBar from '../ExecutableProgressBar.vue';
   import ExecuteButton from '../ExecuteButton.vue';
   import ExecuteLimitInput from '../ExecuteLimitInput.vue';
+  import ExecutionAnalysisPanel from '../executionAnalysis/ExecutionAnalysisPanel.vue';
   import ResultTable from '../result/ResultTable.vue';
   import Executor from '../../execution/executor';
   import SqlExecutable from '../../execution/sqlExecutable';
@@ -71,7 +93,9 @@
   import { setBaseUrl } from 'api/utils';
   import contextCatalog from 'catalog/contextCatalog';
   import HueIcons from 'components/icons/HueIcons.vue';
+  import HueButton from 'components/HueButton.vue';
   import Spinner from 'components/Spinner.vue';
+  import SubscriptionTracker from 'components/utils/SubscriptionTracker';
   import { findEditorConnector, getConfig } from 'config/hueConfig';
   import { Compute, Connector, Namespace } from 'config/types';
   import UUID from 'utils/string/UUID';
@@ -79,6 +103,8 @@
   export default defineComponent({
     name: 'SqlScratchpad',
     components: {
+      ExecutionAnalysisPanel,
+      HueButton,
       Spinner,
       HueIcons,
       ResultTable,
@@ -111,15 +137,18 @@
     },
     setup(props) {
       const { apiUrl, dialect, username, email, password } = toRefs(props);
+      const subTracker = new SubscriptionTracker();
       const activeExecutable = ref<SqlExecutable>(null);
       const executor = ref<Executor>(null);
       const loading = ref<boolean>(true);
+      const logs = ref<ExecutionLogs>(undefined);
+      const logsVisible = ref<boolean>(false);
       const errorMessage = ref<string>(null);
       const id = UUID();
 
       const sqlParserProvider: SqlParserProvider = {
         getAutocompleteParser: () => Promise.resolve(genericAutocompleteParser),
-        getSyntaxParser: () => Promise.resolve(genericSyntaxParser)
+        getSyntaxParser: () => Promise.reject()
       };
 
       const sqlReferenceProvider: SqlReferenceProvider = {
@@ -191,10 +220,29 @@
         } catch {}
       };
 
+      subTracker.subscribe<ExecutableLogsUpdatedEvent>(
+        EXECUTABLE_LOGS_UPDATED_TOPIC,
+        executionLogs => {
+          if (activeExecutable.value?.id === executionLogs.executable.id) {
+            logs.value = executionLogs;
+          }
+        }
+      );
+
+      subTracker.subscribe<ExecutableTransitionedEvent>(EXECUTABLE_TRANSITIONED_TOPIC, event => {
+        if (
+          event.executable.id === activeExecutable.value?.id &&
+          event.newStatus === ExecutionStatus.failed
+        ) {
+          logsVisible.value = true;
+        }
+      });
+
       const onActiveStatementChanged = (event: ActiveStatementChangedEventDetails) => {
         if (executor.value) {
           executor.value.update(event, false);
           activeExecutable.value = executor.value.activeExecutable as SqlExecutable;
+          logs.value = activeExecutable.value.logs;
         }
       };
 
@@ -214,6 +262,8 @@
         errorMessage,
         executor,
         id,
+        logs,
+        logsVisible,
         onActiveStatementChanged,
         sqlParserProvider,
         sqlReferenceProvider