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:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user