feat: add data editing functionality with JSON support; integrate CodeMirror for JSON input

This commit is contained in:
2026-02-07 02:36:06 +08:00
parent aaaeb873ac
commit e06b269374
4 changed files with 310 additions and 3 deletions

View File

@@ -1,9 +1,11 @@
'use client';
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { useConfigStore } from './store/config';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import CodeMirror from '@uiw/react-codemirror';
import { json } from '@codemirror/lang-json';
import {
Table,
TableBody,
@@ -23,11 +25,11 @@ import {
PopoverContent,
PopoverTrigger,
} from '@/components/ui/popover';
import { Plus, Pencil, Trash2 } from 'lucide-react';
import { Plus, Pencil, Trash2, Code } from 'lucide-react';
import { LayoutMain } from '@/modules/layout';
const TableList = () => {
const { list, setShowEdit, setFormData, deleteConfig } = useConfigStore();
const { list, setShowEdit, setFormData, deleteConfig, setShowDataEdit, setDataFormData } = useConfigStore();
interface ConfigItem {
id?: string;
@@ -48,6 +50,11 @@ const TableList = () => {
}
};
const handleEditData = (config: ConfigItem) => {
setShowDataEdit(true);
setDataFormData(config);
};
return (
<div className="rounded-md border">
<Table>
@@ -75,6 +82,12 @@ const TableList = () => {
<Pencil className="w-4 h-4 mr-1" />
</Button>
<Button
variant="outline"
size="sm"
onClick={() => handleEditData(config)}>
</Button>
<Popover>
<PopoverTrigger asChild>
<Button
@@ -180,6 +193,88 @@ const FormModal = () => {
);
};
const DataEditModal = () => {
const { showDataEdit, setShowDataEdit, dataFormData, setDataFormData, updateData } = useConfigStore();
const [jsonValue, setJsonValue] = useState('');
const [error, setError] = useState('');
useEffect(() => {
if (!showDataEdit) return;
if (dataFormData?.data) {
try {
const formatted = JSON.stringify(dataFormData.data, null, 2);
setJsonValue(formatted);
setError('');
} catch (e) {
setJsonValue('');
setError('数据格式错误');
}
} else {
setJsonValue('');
}
}, [dataFormData, showDataEdit]);
const handleSave = async () => {
try {
const parsedData = JSON.parse(jsonValue);
const res = await updateData({
...dataFormData,
data: parsedData,
});
if (res.code === 200) {
setShowDataEdit(false);
setDataFormData({});
}
} catch (e) {
setError('JSON 格式错误,请检查后重试');
}
};
return (
<Dialog open={showDataEdit} onOpenChange={(open) => {
setShowDataEdit(open);
if (!open) {
setDataFormData({});
setError('');
}
}}>
<DialogContent className="max-w-3xl">
<DialogHeader>
<DialogTitle> - {dataFormData?.key}</DialogTitle>
</DialogHeader>
<div className="p-4">
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
<label className="text-sm font-medium"> (JSON格式)</label>
<div className="border rounded-md overflow-hidden">
<CodeMirror
value={jsonValue}
height="400px"
extensions={[json()]}
onChange={(value) => {
setJsonValue(value);
setError('');
}}
theme="light"
/>
</div>
{error && <span className="text-xs text-red-500">{error}</span>}
</div>
<div className="flex gap-2 justify-end">
<Button type="button" variant="outline" onClick={() => setShowDataEdit(false)}>
</Button>
<Button type="button" onClick={handleSave}>
</Button>
</div>
</div>
</div>
</DialogContent>
</Dialog>
);
};
export const List = () => {
const { getConfigList, setShowEdit, setFormData } = useConfigStore();
@@ -201,6 +296,7 @@ export const List = () => {
</div>
<TableList />
<FormModal />
<DataEditModal />
</div>
);
};

View File

@@ -20,6 +20,10 @@ interface ConfigStore {
updateEnv: (data: Config) => Promise<void>;
envData: Config;
setEnvData: (envData: Config) => void;
showDataEdit: boolean;
setShowDataEdit: (showDataEdit: boolean) => void;
dataFormData: any;
setDataFormData: (dataFormData: any) => void;
}
export const useConfigStore = create<ConfigStore>((set, get) => ({
@@ -101,4 +105,8 @@ export const useConfigStore = create<ConfigStore>((set, get) => ({
},
envData: {},
setEnvData: (envData: any) => set({ envData }),
showDataEdit: false,
setShowDataEdit: (showDataEdit: boolean) => set({ showDataEdit }),
dataFormData: {},
setDataFormData: (dataFormData: any) => set({ dataFormData }),
}));