feat(redis): add JSON format/compress buttons in raw content view

This commit is contained in:
t8y2
2026-06-09 14:20:58 +08:00
parent fdc4214bbb
commit a13fcb9964
3 changed files with 134 additions and 6 deletions
@@ -15,6 +15,8 @@ import {
Loader2,
Pencil,
WrapText,
IndentIncrease,
IndentDecrease,
} from "@lucide/vue";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
@@ -289,6 +291,64 @@ function handleStringInput() {
}
}
function formatJsonText(raw: string): string | null {
try {
const parsed = JSON.parse(raw);
return JSON.stringify(parsed, null, 2);
} catch {
return null;
}
}
function compressJsonText(raw: string): string | null {
try {
const parsed = JSON.parse(raw);
return JSON.stringify(parsed);
} catch {
return null;
}
}
function handleFormatStringJson() {
const result = formatJsonText(editValue.value);
if (result != null) {
editValue.value = result;
isEditing.value = true;
} else {
toast(t("redis.jsonFormatError"), 3000);
}
}
function handleCompressStringJson() {
const result = compressJsonText(editValue.value);
if (result != null) {
editValue.value = result;
isEditing.value = true;
} else {
toast(t("redis.jsonFormatError"), 3000);
}
}
function handleFormatMemberJson() {
const result = formatJsonText(memberEditValue.value);
if (result != null) {
memberEditValue.value = result;
isEditingMember.value = true;
} else {
toast(t("redis.jsonFormatError"), 3000);
}
}
function handleCompressMemberJson() {
const result = compressJsonText(memberEditValue.value);
if (result != null) {
memberEditValue.value = result;
isEditingMember.value = true;
} else {
toast(t("redis.jsonFormatError"), 3000);
}
}
async function applyDeleteKey() {
await api.redisDeleteKey(props.connectionId, props.db, props.keyRaw);
emit("deleted");
@@ -849,6 +909,26 @@ onBeforeUnmount(() => {
</Button>
</div>
<span class="flex-1" />
<Button
v-if="stringValueView === 'raw'"
variant="ghost"
size="sm"
class="h-6 rounded-[5px] px-2 text-xs"
:title="t('redis.formatJson')"
@click="handleFormatStringJson"
>
<IndentIncrease class="h-3.5 w-3.5" />
</Button>
<Button
v-if="stringValueView === 'raw'"
variant="ghost"
size="sm"
class="h-6 rounded-[5px] px-2 text-xs"
:title="t('redis.compressJson')"
@click="handleCompressStringJson"
>
<IndentDecrease class="h-3.5 w-3.5" />
</Button>
<label class="flex items-center gap-1.5 text-muted-foreground">
<WrapText class="h-3.5 w-3.5" />
{{ t("redis.wordWrap") }}
@@ -1313,12 +1393,34 @@ onBeforeUnmount(() => {
<Badge variant="outline" class="shrink-0 text-xs">{{ selectedMemberDetail.format.toUpperCase() }}</Badge>
</SheetTitle>
</SheetHeader>
<textarea
v-if="isEditingMember"
v-model="memberEditValue"
class="dbx-editor-font-family min-h-0 flex-1 resize-none bg-background p-5 text-[13px] leading-6 outline-none"
spellcheck="false"
/>
<template v-if="isEditingMember">
<div v-if="selectedMemberJsonDetail" class="flex h-9 items-center gap-2 border-b px-5 text-xs shrink-0">
<span class="flex-1" />
<Button
variant="ghost"
size="sm"
class="h-6 rounded-[5px] px-2 text-xs"
:title="t('redis.formatJson')"
@click="handleFormatMemberJson"
>
<IndentIncrease class="h-3.5 w-3.5" />
</Button>
<Button
variant="ghost"
size="sm"
class="h-6 rounded-[5px] px-2 text-xs"
:title="t('redis.compressJson')"
@click="handleCompressMemberJson"
>
<IndentDecrease class="h-3.5 w-3.5" />
</Button>
</div>
<textarea
v-model="memberEditValue"
class="dbx-editor-font-family min-h-0 flex-1 resize-none bg-background p-5 text-[13px] leading-6 outline-none"
spellcheck="false"
/>
</template>
<template v-else-if="selectedMemberJsonDetail">
<div class="flex h-9 items-center gap-2 border-b px-5 text-xs">
<div class="flex overflow-hidden rounded-md border bg-muted/20 p-0.5">
@@ -1344,6 +1446,26 @@ onBeforeUnmount(() => {
</Button>
</div>
<span class="flex-1" />
<Button
v-if="memberValueView === 'raw'"
variant="ghost"
size="sm"
class="h-6 rounded-[5px] px-2 text-xs"
:title="t('redis.formatJson')"
@click="handleFormatMemberJson"
>
<IndentIncrease class="h-3.5 w-3.5" />
</Button>
<Button
v-if="memberValueView === 'raw'"
variant="ghost"
size="sm"
class="h-6 rounded-[5px] px-2 text-xs"
:title="t('redis.compressJson')"
@click="handleCompressMemberJson"
>
<IndentDecrease class="h-3.5 w-3.5" />
</Button>
<label class="flex items-center gap-1.5 text-muted-foreground">
<WrapText class="h-3.5 w-3.5" />
{{ t("redis.wordWrap") }}
+3
View File
@@ -1440,6 +1440,9 @@ export default {
jsonView: "JSON view",
rawContent: "Raw content",
wordWrap: "Word wrap",
formatJson: "Format",
compressJson: "Compress",
jsonFormatError: "Invalid JSON format",
},
mongo: {
documents: "{count} documents",
+3
View File
@@ -1411,6 +1411,9 @@ export default {
jsonView: "JSON 视图",
rawContent: "原始内容",
wordWrap: "自动换行",
formatJson: "格式化",
compressJson: "压缩",
jsonFormatError: "JSON 格式不合法",
},
mongo: {
documents: "{count} 个文档",