diff --git a/apps/desktop/src/App.vue b/apps/desktop/src/App.vue index 2979afa64..7dd12736b 100644 --- a/apps/desktop/src/App.vue +++ b/apps/desktop/src/App.vue @@ -239,7 +239,7 @@ const selectedSql = ref(""); const cursorPos = ref(0); const formatSqlRequest = ref<{ id: number; tabId: string } | null>(null); const compressSqlRequest = ref<{ id: number; tabId: string } | null>(null); -const activeOutputView = ref<"result" | "summary" | "explain" | "chart">("result"); +const activeOutputView = ref<"result" | "summary" | "explain" | "chart" | "messages">("result"); const newQueryContextSource = ref<"tab" | "sidebar">("tab"); const queryEditorDdlTarget = ref<{ connectionId: string; database: string; catalog?: string; schema?: string; tableName: string; objectType?: ObjectSourceKind } | null>(null); const queryEditorObjectSourceTarget = ref<{ diff --git a/apps/desktop/src/components/layout/ContentArea.vue b/apps/desktop/src/components/layout/ContentArea.vue index 0e71a96d5..ccc082bdb 100644 --- a/apps/desktop/src/components/layout/ContentArea.vue +++ b/apps/desktop/src/components/layout/ContentArea.vue @@ -3,6 +3,7 @@ import { computed, ref, defineAsyncComponent, watch, nextTick, onMounted, onUnmo import { safeLocalStorageGet, safeLocalStorageSet } from "@/lib/backend/safeStorage"; import { appendDebugLog, isDebugLoggingEnabled } from "@/lib/backend/debugLog"; import { canReloadUnavailableDataTab } from "@/lib/table/tableDataRefresh"; +import { defaultViewForResult } from "@/lib/query/queryResultDefaultView"; import { isQueryExecutionErrorResult } from "@/lib/query/queryResultError"; import type { CSSProperties } from "vue"; import { useI18n } from "vue-i18n"; @@ -18,6 +19,7 @@ import QueryEditor from "@/components/editor/QueryEditor.vue"; import ColumnInfoPanel from "@/components/editor/ColumnInfoPanel.vue"; import QueryLoadingState from "@/components/common/QueryLoadingState.vue"; import QueryErrorActions from "@/components/common/QueryErrorActions.vue"; +import QueryMessagesView from "@/components/layout/QueryMessagesView.vue"; import QueryResultToolbarActions from "@/components/layout/QueryResultToolbarActions.vue"; import QueryResultViewSwitcher from "@/components/layout/QueryResultViewSwitcher.vue"; import DataGridCopyFormatControl from "@/components/grid/DataGridCopyFormatControl.vue"; @@ -138,7 +140,7 @@ const props = defineProps<{ activeTab: QueryTab; activeConnection?: ConnectionConfig; executableSql: string; - activeOutputView: "result" | "summary" | "explain" | "chart"; + activeOutputView: "result" | "summary" | "explain" | "chart" | "messages"; formatSqlRequest: { id: number; tabId: string } | null; compressSqlRequest: { id: number; tabId: string } | null; selectedSql: string; @@ -147,7 +149,7 @@ const props = defineProps<{ }>(); const emit = defineEmits<{ - "update:activeOutputView": [value: "result" | "summary" | "explain" | "chart"]; + "update:activeOutputView": [value: "result" | "summary" | "explain" | "chart" | "messages"]; fixWithAi: [errorMessage: string]; sendSelectionToAi: [sql: string]; execute: [sqlOverride?: SqlExecutionOverride]; @@ -427,6 +429,8 @@ const hasTabularResult = computed(() => { }); const canShowResultOutput = computed(() => hasTabularResult.value || props.activeTab.isExecuting); const canShowExplainOutput = computed(() => !!props.activeTab.explainPlan || !!props.activeTab.explainError || !!props.activeTab.explainTableResult || !!props.activeTab.explainTableError || props.activeTab.isExplaining === true); +const resultMessageCount = computed(() => props.activeTab.result?.messages?.length ?? 0); +const canShowMessagesOutput = computed(() => resultMessageCount.value > 0); const showStandaloneResultToolbar = computed(() => activeElasticsearchJsonResponse.value || props.activeOutputView !== "result" || !props.activeTab.result || !hasTabularResult.value); const standaloneResultToolbarCompact = computed(() => isDataGridToolbarCompact(standaloneResultToolbarWidth.value, standaloneResultToolbarViewportWidth.value)); let standaloneResultToolbarResizeObserver: ResizeObserver | undefined; @@ -599,7 +603,8 @@ watch( () => { if (props.activeTab.isExecuting) return; if (hasExecutionSummary.value && !hasTabularResult.value && props.activeOutputView === "result") { - emit("update:activeOutputView", "summary"); + const result = props.activeTab.result; + emit("update:activeOutputView", result ? defaultViewForResult(result) : "summary"); } }, { immediate: true }, @@ -1319,6 +1324,8 @@ defineExpose({ focusSearch, refreshData, refreshQueryEditorCompletionCache, hand :can-show-result="canShowResultOutput" :can-show-summary="hasExecutionSummary" :can-show-chart="hasNumericData && !activeElasticsearchJsonResponse" + :can-show-messages="canShowMessagesOutput" + :message-count="resultMessageCount" :compact="standaloneResultToolbarCompact" @select-view="emit('update:activeOutputView', $event)" /> @@ -1414,6 +1421,8 @@ defineExpose({ focusSearch, refreshData, refreshQueryEditorCompletionCache, hand + +