feat: add data editing functionality with JSON support; integrate CodeMirror for JSON input
This commit is contained in:
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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 }),
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user