feat: render SQL initial/result data as tables in a two-pane layout

Rewrites Content.vue to give the SQL language its own top/bottom split
(code editor over data tables) instead of sharing the horizontal
left/right layout used by other languages. SqlSection.vue now renders
the preset data and the post-run result as two side-by-side
n-data-tables, falling back to the existing error UI when a run fails.

Also registers NDataTable globally in main.ts (naive-ui components must
be explicitly registered via create()); without it n-data-table was an
inert unresolved custom element and no rows rendered.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-05 00:47:53 -06:00
parent 436f39d424
commit edd2f706ac
3 changed files with 87 additions and 16 deletions

View File

@@ -9,13 +9,27 @@ import TurtleSection from "./TurtleSection.vue"
<template>
<n-layout-content class="container">
<n-split direction="horizontal" :min="1 / 3" :max="4 / 5">
<n-split
v-if="code.language === 'sql'"
direction="vertical"
:default-size="3 / 5"
:min="1 / 4"
:max="3 / 4"
>
<template #1>
<CodeSection />
</template>
<template #2>
<SqlSection />
</template>
</n-split>
<n-split v-else direction="horizontal" :min="1 / 3" :max="4 / 5">
<template #1>
<CodeSection />
</template>
<template #2>
<n-split
v-if="code.language !== 'turtle' && code.language !== 'sql'"
v-if="code.language !== 'turtle'"
direction="vertical"
:default-size="1 / 3"
:min="1 / 5"
@@ -28,8 +42,7 @@ import TurtleSection from "./TurtleSection.vue"
<OutputSection />
</template>
</n-split>
<TurtleSection v-else-if="code.language === 'turtle'" />
<SqlSection v-else />
<TurtleSection v-else />
</template>
</n-split>
</n-layout-content>

View File

@@ -1,9 +1,10 @@
<script lang="ts" setup>
import type { DataTableColumns } from "naive-ui"
import { computed, watch } from "vue"
import CodeEditor from "../components/CodeEditor.vue"
import { output } from "../composables/code"
import { selectedTableId } from "../composables/sqlTable"
import { buildSetupSql, sqlTables } from "../data/sqlTables"
import { output, status } from "../composables/code"
import { parseResultRows, selectedTableId } from "../composables/sqlTable"
import { sqlTables } from "../data/sqlTables"
import { Status } from "../types"
import OutputSection from "./OutputSection.vue"
const selectedTable = computed(
@@ -12,23 +13,78 @@ const selectedTable = computed(
sqlTables[0],
)
const tableColumns = computed<DataTableColumns>(() =>
selectedTable.value.columns.map((column) => ({
title: column.name,
key: column.name,
})),
)
const initialRows = computed(() =>
selectedTable.value.rows.map((row) =>
Object.fromEntries(
selectedTable.value.columns.map((column, index) => [
column.name,
row[index],
]),
),
),
)
const resultRows = computed(() =>
parseResultRows(output.value, selectedTable.value.columns),
)
watch(selectedTableId, () => {
output.value = ""
status.value = Status.NotStarted
})
</script>
<template>
<n-split direction="vertical" :default-size="1 / 3" :min="1 / 5" :max="3 / 5">
<n-split
direction="horizontal"
:default-size="1 / 2"
:min="1 / 4"
:max="3 / 4"
>
<template #1>
<CodeEditor
:model-value="buildSetupSql(selectedTable)"
language="sql"
readonly
label="表结构与初始数据"
<div class="table-panel">
<div class="panel-title">原始数据{{ selectedTable.label }}</div>
<n-data-table
size="small"
:bordered="false"
:columns="tableColumns"
:data="initialRows"
:row-key="(row: any) => row.id"
/>
</div>
</template>
<template #2>
<OutputSection />
<div class="table-panel" v-if="status === Status.Accepted">
<div class="panel-title">运行后数据</div>
<n-data-table
size="small"
:bordered="false"
:columns="tableColumns"
:data="resultRows"
:row-key="(row: any) => row.id"
/>
</div>
<OutputSection v-else />
</template>
</n-split>
</template>
<style scoped>
.table-panel {
height: 100%;
overflow: auto;
padding: 12px 20px;
box-sizing: border-box;
}
.panel-title {
font-size: 16px;
margin-bottom: 8px;
}
</style>

View File

@@ -5,6 +5,7 @@ import {
NCollapse,
NCollapseItem,
NConfigProvider,
NDataTable,
NDropdown,
NFlex,
NIcon,
@@ -40,6 +41,7 @@ const naive = create({
NCollapse,
NCollapseItem,
NConfigProvider,
NDataTable,
NMessageProvider,
NLayout,
NLayoutHeader,