feat: add data editing functionality with JSON support; integrate CodeMirror for JSON input
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^6.1.0",
|
||||
"@base-ui/react": "^1.1.0",
|
||||
"@codemirror/lang-json": "^6.0.2",
|
||||
"@kevisual/api": "^0.0.44",
|
||||
"@kevisual/cache": "^0.0.5",
|
||||
"@kevisual/query": "^0.0.39",
|
||||
@@ -28,6 +29,7 @@
|
||||
"@radix-ui/react-tabs": "^1.1.13",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"@uiw/react-codemirror": "^4.25.4",
|
||||
"antd": "^6.2.3",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
|
||||
201
pnpm-lock.yaml
generated
201
pnpm-lock.yaml
generated
@@ -14,6 +14,9 @@ importers:
|
||||
'@base-ui/react':
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0(@types/react@19.2.7)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
'@codemirror/lang-json':
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2
|
||||
'@kevisual/api':
|
||||
specifier: ^0.0.44
|
||||
version: 0.0.44
|
||||
@@ -62,6 +65,9 @@ importers:
|
||||
'@tanstack/react-table':
|
||||
specifier: ^8.21.3
|
||||
version: 8.21.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
'@uiw/react-codemirror':
|
||||
specifier: ^4.25.4
|
||||
version: 4.25.4(@babel/runtime@7.28.6)(@codemirror/autocomplete@6.20.0)(@codemirror/language@6.12.1)(@codemirror/lint@6.9.3)(@codemirror/search@6.6.0)(@codemirror/state@6.5.4)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.39.12)(codemirror@6.0.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
antd:
|
||||
specifier: ^6.2.3
|
||||
version: 6.2.3(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
@@ -236,6 +242,33 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
'@codemirror/autocomplete@6.20.0':
|
||||
resolution: {integrity: sha512-bOwvTOIJcG5FVo5gUUupiwYh8MioPLQ4UcqbcRf7UQ98X90tCa9E1kZ3Z7tqwpZxYyOvh1YTYbmZE9RTfTp5hg==}
|
||||
|
||||
'@codemirror/commands@6.10.2':
|
||||
resolution: {integrity: sha512-vvX1fsih9HledO1c9zdotZYUZnE4xV0m6i3m25s5DIfXofuprk6cRcLUZvSk3CASUbwjQX21tOGbkY2BH8TpnQ==}
|
||||
|
||||
'@codemirror/lang-json@6.0.2':
|
||||
resolution: {integrity: sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==}
|
||||
|
||||
'@codemirror/language@6.12.1':
|
||||
resolution: {integrity: sha512-Fa6xkSiuGKc8XC8Cn96T+TQHYj4ZZ7RdFmXA3i9xe/3hLHfwPZdM+dqfX0Cp0zQklBKhVD8Yzc8LS45rkqcwpQ==}
|
||||
|
||||
'@codemirror/lint@6.9.3':
|
||||
resolution: {integrity: sha512-y3YkYhdnhjDBAe0VIA0c4wVoFOvnp8CnAvfLqi0TqotIv92wIlAAP7HELOpLBsKwjAX6W92rSflA6an/2zBvXw==}
|
||||
|
||||
'@codemirror/search@6.6.0':
|
||||
resolution: {integrity: sha512-koFuNXcDvyyotWcgOnZGmY7LZqEOXZaaxD/j6n18TCLx2/9HieZJ5H6hs1g8FiRxBD0DNfs0nXn17g872RmYdw==}
|
||||
|
||||
'@codemirror/state@6.5.4':
|
||||
resolution: {integrity: sha512-8y7xqG/hpB53l25CIoit9/ngxdfoG+fx+V3SHBrinnhOtLvKHRyAJJuHzkWrR4YXXLX8eXBsejgAAxHUOdW1yw==}
|
||||
|
||||
'@codemirror/theme-one-dark@6.1.3':
|
||||
resolution: {integrity: sha512-NzBdIvEJmx6fjeremiGp3t/okrLPYT0d9orIc7AFun8oZcRk58aejkqhv6spnz4MLAevrKNPMQYXEWMg4s+sKA==}
|
||||
|
||||
'@codemirror/view@6.39.12':
|
||||
resolution: {integrity: sha512-f+/VsHVn/kOA9lltk/GFzuYwVVAKmOnNjxbrhkk3tPHntFqjWeI2TbIXx006YkBkqC10wZ4NsnWXCQiFPeAISQ==}
|
||||
|
||||
'@date-fns/tz@1.4.1':
|
||||
resolution: {integrity: sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA==}
|
||||
|
||||
@@ -464,6 +497,21 @@ packages:
|
||||
peerDependencies:
|
||||
dotenv: ^17
|
||||
|
||||
'@lezer/common@1.5.1':
|
||||
resolution: {integrity: sha512-6YRVG9vBkaY7p1IVxL4s44n5nUnaNnGM2/AckNgYOnxTG2kWh1vR8BMxPseWPjRNpb5VtXnMpeYAEAADoRV1Iw==}
|
||||
|
||||
'@lezer/highlight@1.2.3':
|
||||
resolution: {integrity: sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==}
|
||||
|
||||
'@lezer/json@1.0.3':
|
||||
resolution: {integrity: sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==}
|
||||
|
||||
'@lezer/lr@1.4.8':
|
||||
resolution: {integrity: sha512-bPWa0Pgx69ylNlMlPvBPryqeLYQjyJjqPx+Aupm5zydLIF3NE+6MMLT8Yi23Bd9cif9VS00aUebn+6fDIGBcDA==}
|
||||
|
||||
'@marijn/find-cluster-break@1.0.2':
|
||||
resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==}
|
||||
|
||||
'@next/env@16.1.6':
|
||||
resolution: {integrity: sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ==}
|
||||
|
||||
@@ -1650,6 +1698,28 @@ packages:
|
||||
'@types/react@19.2.7':
|
||||
resolution: {integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==}
|
||||
|
||||
'@uiw/codemirror-extensions-basic-setup@4.25.4':
|
||||
resolution: {integrity: sha512-YzNwkm0AbPv1EXhCHYR5v0nqfemG2jEB0Z3Att4rBYqKrlG7AA9Rhjc3IyBaOzsBu18wtrp9/+uhTyu7TXSRng==}
|
||||
peerDependencies:
|
||||
'@codemirror/autocomplete': '>=6.0.0'
|
||||
'@codemirror/commands': '>=6.0.0'
|
||||
'@codemirror/language': '>=6.0.0'
|
||||
'@codemirror/lint': '>=6.0.0'
|
||||
'@codemirror/search': '>=6.0.0'
|
||||
'@codemirror/state': '>=6.0.0'
|
||||
'@codemirror/view': '>=6.0.0'
|
||||
|
||||
'@uiw/react-codemirror@4.25.4':
|
||||
resolution: {integrity: sha512-ipO067oyfUw+DVaXhQCxkB0ZD9b7RnY+ByrprSYSKCHaULvJ3sqWYC/Zen6zVQ8/XC4o5EPBfatGiX20kC7XGA==}
|
||||
peerDependencies:
|
||||
'@babel/runtime': '>=7.11.0'
|
||||
'@codemirror/state': '>=6.0.0'
|
||||
'@codemirror/theme-one-dark': '>=6.0.0'
|
||||
'@codemirror/view': '>=6.0.0'
|
||||
codemirror: '>=6.0.0'
|
||||
react: '>=17.0.0'
|
||||
react-dom: '>=17.0.0'
|
||||
|
||||
antd@6.2.3:
|
||||
resolution: {integrity: sha512-q92r7/hcQAR2iv6CCysdz7c2Pdl/3nhslc3azF9e6AEl4knO6v+nlaeor1oF2jBanZ/tiw2m3NprOVUgPDvyhg==}
|
||||
peerDependencies:
|
||||
@@ -1683,12 +1753,18 @@ packages:
|
||||
react: ^18 || ^19 || ^19.0.0-rc
|
||||
react-dom: ^18 || ^19 || ^19.0.0-rc
|
||||
|
||||
codemirror@6.0.2:
|
||||
resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==}
|
||||
|
||||
compute-scroll-into-view@3.1.1:
|
||||
resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==}
|
||||
|
||||
copy-to-clipboard@3.3.3:
|
||||
resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==}
|
||||
|
||||
crelt@1.0.6:
|
||||
resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==}
|
||||
|
||||
csstype@3.2.3:
|
||||
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
||||
|
||||
@@ -1986,6 +2062,9 @@ packages:
|
||||
string-convert@0.2.1:
|
||||
resolution: {integrity: sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==}
|
||||
|
||||
style-mod@4.1.3:
|
||||
resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==}
|
||||
|
||||
styled-jsx@5.1.6:
|
||||
resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
@@ -2079,6 +2158,9 @@ packages:
|
||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc
|
||||
|
||||
w3c-keyname@2.2.8:
|
||||
resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
|
||||
|
||||
zustand@5.0.11:
|
||||
resolution: {integrity: sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg==}
|
||||
engines: {node: '>=12.20.0'}
|
||||
@@ -2176,6 +2258,64 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@types/react': 19.2.7
|
||||
|
||||
'@codemirror/autocomplete@6.20.0':
|
||||
dependencies:
|
||||
'@codemirror/language': 6.12.1
|
||||
'@codemirror/state': 6.5.4
|
||||
'@codemirror/view': 6.39.12
|
||||
'@lezer/common': 1.5.1
|
||||
|
||||
'@codemirror/commands@6.10.2':
|
||||
dependencies:
|
||||
'@codemirror/language': 6.12.1
|
||||
'@codemirror/state': 6.5.4
|
||||
'@codemirror/view': 6.39.12
|
||||
'@lezer/common': 1.5.1
|
||||
|
||||
'@codemirror/lang-json@6.0.2':
|
||||
dependencies:
|
||||
'@codemirror/language': 6.12.1
|
||||
'@lezer/json': 1.0.3
|
||||
|
||||
'@codemirror/language@6.12.1':
|
||||
dependencies:
|
||||
'@codemirror/state': 6.5.4
|
||||
'@codemirror/view': 6.39.12
|
||||
'@lezer/common': 1.5.1
|
||||
'@lezer/highlight': 1.2.3
|
||||
'@lezer/lr': 1.4.8
|
||||
style-mod: 4.1.3
|
||||
|
||||
'@codemirror/lint@6.9.3':
|
||||
dependencies:
|
||||
'@codemirror/state': 6.5.4
|
||||
'@codemirror/view': 6.39.12
|
||||
crelt: 1.0.6
|
||||
|
||||
'@codemirror/search@6.6.0':
|
||||
dependencies:
|
||||
'@codemirror/state': 6.5.4
|
||||
'@codemirror/view': 6.39.12
|
||||
crelt: 1.0.6
|
||||
|
||||
'@codemirror/state@6.5.4':
|
||||
dependencies:
|
||||
'@marijn/find-cluster-break': 1.0.2
|
||||
|
||||
'@codemirror/theme-one-dark@6.1.3':
|
||||
dependencies:
|
||||
'@codemirror/language': 6.12.1
|
||||
'@codemirror/state': 6.5.4
|
||||
'@codemirror/view': 6.39.12
|
||||
'@lezer/highlight': 1.2.3
|
||||
|
||||
'@codemirror/view@6.39.12':
|
||||
dependencies:
|
||||
'@codemirror/state': 6.5.4
|
||||
crelt: 1.0.6
|
||||
style-mod: 4.1.3
|
||||
w3c-keyname: 2.2.8
|
||||
|
||||
'@date-fns/tz@1.4.1': {}
|
||||
|
||||
'@emnapi/runtime@1.8.1':
|
||||
@@ -2362,6 +2502,24 @@ snapshots:
|
||||
'@kevisual/load': 0.0.6
|
||||
dotenv: 17.2.3
|
||||
|
||||
'@lezer/common@1.5.1': {}
|
||||
|
||||
'@lezer/highlight@1.2.3':
|
||||
dependencies:
|
||||
'@lezer/common': 1.5.1
|
||||
|
||||
'@lezer/json@1.0.3':
|
||||
dependencies:
|
||||
'@lezer/common': 1.5.1
|
||||
'@lezer/highlight': 1.2.3
|
||||
'@lezer/lr': 1.4.8
|
||||
|
||||
'@lezer/lr@1.4.8':
|
||||
dependencies:
|
||||
'@lezer/common': 1.5.1
|
||||
|
||||
'@marijn/find-cluster-break@1.0.2': {}
|
||||
|
||||
'@next/env@16.1.6': {}
|
||||
|
||||
'@next/swc-darwin-arm64@16.1.6':
|
||||
@@ -3607,6 +3765,33 @@ snapshots:
|
||||
dependencies:
|
||||
csstype: 3.2.3
|
||||
|
||||
'@uiw/codemirror-extensions-basic-setup@4.25.4(@codemirror/autocomplete@6.20.0)(@codemirror/commands@6.10.2)(@codemirror/language@6.12.1)(@codemirror/lint@6.9.3)(@codemirror/search@6.6.0)(@codemirror/state@6.5.4)(@codemirror/view@6.39.12)':
|
||||
dependencies:
|
||||
'@codemirror/autocomplete': 6.20.0
|
||||
'@codemirror/commands': 6.10.2
|
||||
'@codemirror/language': 6.12.1
|
||||
'@codemirror/lint': 6.9.3
|
||||
'@codemirror/search': 6.6.0
|
||||
'@codemirror/state': 6.5.4
|
||||
'@codemirror/view': 6.39.12
|
||||
|
||||
'@uiw/react-codemirror@4.25.4(@babel/runtime@7.28.6)(@codemirror/autocomplete@6.20.0)(@codemirror/language@6.12.1)(@codemirror/lint@6.9.3)(@codemirror/search@6.6.0)(@codemirror/state@6.5.4)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.39.12)(codemirror@6.0.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.6
|
||||
'@codemirror/commands': 6.10.2
|
||||
'@codemirror/state': 6.5.4
|
||||
'@codemirror/theme-one-dark': 6.1.3
|
||||
'@codemirror/view': 6.39.12
|
||||
'@uiw/codemirror-extensions-basic-setup': 4.25.4(@codemirror/autocomplete@6.20.0)(@codemirror/commands@6.10.2)(@codemirror/language@6.12.1)(@codemirror/lint@6.9.3)(@codemirror/search@6.6.0)(@codemirror/state@6.5.4)(@codemirror/view@6.39.12)
|
||||
codemirror: 6.0.2
|
||||
react: 19.2.4
|
||||
react-dom: 19.2.4(react@19.2.4)
|
||||
transitivePeerDependencies:
|
||||
- '@codemirror/autocomplete'
|
||||
- '@codemirror/language'
|
||||
- '@codemirror/lint'
|
||||
- '@codemirror/search'
|
||||
|
||||
antd@6.2.3(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
|
||||
dependencies:
|
||||
'@ant-design/colors': 8.0.1
|
||||
@@ -3692,12 +3877,24 @@ snapshots:
|
||||
- '@types/react'
|
||||
- '@types/react-dom'
|
||||
|
||||
codemirror@6.0.2:
|
||||
dependencies:
|
||||
'@codemirror/autocomplete': 6.20.0
|
||||
'@codemirror/commands': 6.10.2
|
||||
'@codemirror/language': 6.12.1
|
||||
'@codemirror/lint': 6.9.3
|
||||
'@codemirror/search': 6.6.0
|
||||
'@codemirror/state': 6.5.4
|
||||
'@codemirror/view': 6.39.12
|
||||
|
||||
compute-scroll-into-view@3.1.1: {}
|
||||
|
||||
copy-to-clipboard@3.3.3:
|
||||
dependencies:
|
||||
toggle-selection: 1.0.6
|
||||
|
||||
crelt@1.0.6: {}
|
||||
|
||||
csstype@3.2.3: {}
|
||||
|
||||
date-fns-jalali@4.1.0-0: {}
|
||||
@@ -4008,6 +4205,8 @@ snapshots:
|
||||
|
||||
string-convert@0.2.1: {}
|
||||
|
||||
style-mod@4.1.3: {}
|
||||
|
||||
styled-jsx@5.1.6(react@19.2.4):
|
||||
dependencies:
|
||||
client-only: 0.0.1
|
||||
@@ -4070,6 +4269,8 @@ snapshots:
|
||||
- '@types/react'
|
||||
- '@types/react-dom'
|
||||
|
||||
w3c-keyname@2.2.8: {}
|
||||
|
||||
zustand@5.0.11(@types/react@19.2.7)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)):
|
||||
optionalDependencies:
|
||||
'@types/react': 19.2.7
|
||||
|
||||
@@ -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