fix: add Shiki SQL syntax highlighting to all SQL display components

Add useSqlHighlighter composable and integrate Shiki highlighting into
DangerConfirmDialog, QueryHistory, DataGrid (replacing regex-based
highlighting), SqlFileExecutionDialog, SchemaDiffDialog, TreeItem,
ObjectBrowser, and FieldLineageDialog. Also fix danger dialog overflow
by adding overflow-hidden to DialogContent and wrap/scroll support.
This commit is contained in:
t8y2 committed 2026-05-26 15:31:15 +08:00
1 parent a1f718d6bd
commit f5f986cdd6
10 files changed
+221 -26

No files matched your search

@@ -1,14 +1,17 @@
<script setup lang="ts">
import { computed } from "vue";
import { useI18n } from "vue-i18n";
import { AlertTriangle } from "lucide-vue-next";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
import { useSqlHighlighter } from "@/composables/useSqlHighlighter";
const { t } = useI18n();
const { highlight } = useSqlHighlighter();
const open = defineModel<boolean>("open", { default: false });
withDefaults(
const props = withDefaults(
defineProps<{
sql?: string;
title?: string;
@@ -29,6 +32,9 @@ const emit = defineEmits<{
confirm: [];
}>();
const code = computed(() => props.details || props.sql);
const highlightedCode = computed(() => highlight(code.value));
function onConfirm() {
open.value = false;
emit("confirm");
@@ -45,13 +51,13 @@ function onConfirm() {
</DialogTitle>
</DialogHeader>
<div class="py-4">
<div class="py-4 min-w-0">
<p class="text-sm text-muted-foreground mb-3">{{ message || t("dangerDialog.message") }}</p>
<pre
v-if="details || sql"
class="text-xs bg-muted p-3 rounded overflow-auto max-h-40 min-w-0 font-mono whitespace-pre-wrap"
>{{ details || sql }}</pre
>
v-if="code"
class="text-xs bg-muted p-3 rounded overflow-auto max-h-40 min-w-0 font-mono whitespace-pre"
v-html="highlightedCode"
/>
</div>
<DialogFooter>
@@ -1,6 +1,7 @@
<script setup lang="ts">
import { ref, computed, onMounted } from "vue";
import { useI18n } from "vue-i18n";
import { useSqlHighlighter } from "@/composables/useSqlHighlighter";
import { Clock, Copy, Database, RotateCcw, Search, Sparkles, Trash2, X } from "lucide-vue-next";
import { RecycleScroller } from "vue-virtual-scroller";
import { Button } from "@/components/ui/button";
@@ -18,6 +19,7 @@ import * as api from "@/lib/api";
const { t } = useI18n();
const { toast } = useToast();
const { highlight } = useSqlHighlighter();
const store = useHistoryStore();
const emit = defineEmits<{
@@ -297,7 +299,8 @@ onMounted(() => store.load());
</div>
<pre
class="max-h-48 overflow-auto rounded border bg-muted/30 p-3 text-xs"
><code>{{ selectedEntry.sql }}</code></pre>
v-html="highlight(selectedEntry.sql)"
></pre>
</div>
<div v-if="selectedEntry.rollback_sql">
<div class="mb-1 flex items-center justify-between">
@@ -309,7 +312,8 @@ onMounted(() => store.load());
</div>
<pre
class="max-h-40 overflow-auto rounded border bg-muted/30 p-3 text-xs"
><code>{{ selectedEntry.rollback_sql }}</code></pre>
v-html="highlight(selectedEntry.rollback_sql || '')"
></pre>
</div>
</div>
<DialogFooter>