From 11021e4e0665435f020e0008dca6aef4b4b950da Mon Sep 17 00:00:00 2001 From: Gaosong Date: Tue, 17 Jan 2023 21:12:32 +0800 Subject: [PATCH 1/2] feat: string's request function --- src/backend/StringOperation.ts | 46 ++++++ src/comps/Table.tsx | 260 ++++++++++++++++++++++++++------- 2 files changed, 251 insertions(+), 55 deletions(-) create mode 100644 src/backend/StringOperation.ts diff --git a/src/backend/StringOperation.ts b/src/backend/StringOperation.ts new file mode 100644 index 0000000..f9a2cca --- /dev/null +++ b/src/backend/StringOperation.ts @@ -0,0 +1,46 @@ +import axios from 'axios'; + +let token = localStorage.getItem('token'); +let ip = localStorage.getItem('ip'); +let port = localStorage.getItem('port'); + +function loadData(){ + token = localStorage.getItem('token'); + ip = localStorage.getItem('ip'); + port = localStorage.getItem('port'); +} + +// Delete a specific kV +export async function DeleteSingleValue(bucket: string, key: string): Promise { + loadData() + const Url = `http://${ip}:${port}`; + return await axios.delete( + `${Url}/string/delete/${bucket}/${key}?token=${token}`, + ); +} + +// Update a specific kV +export async function UpdateSingleValue(bucket: string, key: string, value: string,ttl:number): Promise { + loadData() + const Url = `http://${ip}:${port}`; + return await axios.post( + `${Url}/string/update/${bucket}/${key}?token=${token}`, + { + value: value, + ttl: ttl + } + ); +} + +// Add a specific kV +export async function AddSingleValue(bucket: string, key: string, value: string,ttl:number): Promise { + loadData() + const Url = `http://${ip}:${port}`; + return await axios.post( + `${Url}/string/update/${bucket}/${key}?token=${token}`, + { + value: value, + ttl: ttl + } + ); +} diff --git a/src/comps/Table.tsx b/src/comps/Table.tsx index 81b714d..ebe68c9 100644 --- a/src/comps/Table.tsx +++ b/src/comps/Table.tsx @@ -18,10 +18,18 @@ import Tooltip from '@mui/material/Tooltip'; import FormControlLabel from '@mui/material/FormControlLabel'; import Switch from '@mui/material/Switch'; import DeleteIcon from '@mui/icons-material/Delete'; +import AddCircleIcon from '@mui/icons-material/AddCircle'; import { visuallyHidden } from '@mui/utils'; import Message from './Message'; import SearchIcon from '@mui/icons-material/Search'; -import { InputBase } from '@mui/material'; +import { Alert, Button, InputBase, Snackbar } from '@mui/material'; +import TextField from '@mui/material/TextField'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import DialogTitle from '@mui/material/DialogTitle'; +import EditIcon from '@mui/icons-material/Edit'; interface Data { key: string; @@ -172,10 +180,11 @@ function EnhancedTableHead(props: EnhancedTableProps) { interface EnhancedTableToolbarProps { numSelected: number; + ds: string; + selected: string[]; } - function CustomizedInputBase(props: { prop: any; }) { const [keyword, setKeyword] = React.useState(''); return ( @@ -191,11 +200,11 @@ function CustomizedInputBase(props: { prop: any; }) { onChange={e => setKeyword(e.target.value)} /> { - let { rows, setRows,back} = props.prop; + let { rows, setRows, back } = props.prop; rows = rows as Data[]; - if (keyword==''){ - setRows(back) - return + if (keyword == '') { + setRows(back); + return; } let tmp: Data[] = []; for (let i = 0; i < rows.length; i++) { @@ -214,57 +223,195 @@ function CustomizedInputBase(props: { prop: any; }) { const EnhancedTableToolbar = (props: EnhancedTableToolbarProps) => { - const { numSelected, ...other } = props; + const { numSelected, ds, selected, ...other } = props; + const [open, setOpen] = React.useState(false); + const [operateType, setOperateType] = React.useState(''); + const [openAlert, setOpenAlert] = React.useState(false); + + const [key, setKey] = React.useState(''); + const [value, setValue] = React.useState(''); + const [ttl, setTTL] = React.useState(0); + + // @ts-ignore + const handleTextInputChange = (type: string,event) => { + switch (type) { + case 'key': + setKey(event.target.value); + break; + case 'value': + setValue(event.target.value); + break; + case 'ttl': + setTTL(event.target.value); + break; + } + }; + + const handleClickOpen = (type: string) => { + if (type == 'update' && numSelected != 1) { + setOpenAlert(true); + return; + } + setOpen(true); + setOperateType(type); + }; + + const handleClose = () => { + setOpen(false); + }; + //@ts-ignore + const handleSubmit = (event) => { + event.preventDefault(); + const data = new FormData(event.currentTarget); + console.log(data); + const form = { + key: key, + value: value, + ttl: ttl, + }; + if (operateType == 'add') { + + } else if (operateType == 'update') { + + } + //reset + setKey(''); + setValue(''); + setTTL(0); + setOpen(false);//close dialog + }; + + // @ts-ignore return ( - 0 && { - bgcolor: (theme) => - alpha(theme.palette.primary.main, theme.palette.action.activatedOpacity), - }), - }} - > + <> + 0 && { + bgcolor: (theme) => + alpha(theme.palette.primary.main, theme.palette.action.activatedOpacity), + }), + }} + > + + {numSelected > 0 ? ( + + {numSelected} selected + + ) : ( + + Data List + + + )} + + {numSelected == 0 ? ( + + { + handleClickOpen('add'); + }}> + + + ) + : ( + + { + handleClickOpen('update'); + }}> + + + ) + } - {numSelected > 0 ? ( - - {numSelected} selected - - ) : ( - - Data List - - - )} - - {numSelected > 0 ? ( - - - - - - ) : ( - - - - - - )} - + {numSelected > 0 ? ( + + + + + + ) : ( + + + + + + )} + + + + {operateType.toUpperCase()} + + + + {operateType == 'add' ? 'Add a new key-value pair' : 'Update the selected key-value pair'} + + {handleTextInputChange('key',e)}} + /> + {handleTextInputChange('value',e)}} + /> + {handleTextInputChange('value',e)}} + /> + + + + + + + + + + + + { + setOpenAlert(false); + }} severity='error' sx={{ width: '100%' }}> + Please select one key to update + + + ); }; @@ -355,13 +502,16 @@ export default function EnhancedTable(props: any) { const emptyRows = page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0; + return ( <> + numSelected={selected.length} rows={rows} setRows={setRows} back={back} ds={props.condition.ds} + // @ts-ignore + selected={selected} /> Date: Tue, 17 Jan 2023 23:39:58 +0800 Subject: [PATCH 2/2] feat: support add and update kv TODO: render after operation in sync --- src/comps/Table.tsx | 96 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 80 insertions(+), 16 deletions(-) diff --git a/src/comps/Table.tsx b/src/comps/Table.tsx index ebe68c9..d73581c 100644 --- a/src/comps/Table.tsx +++ b/src/comps/Table.tsx @@ -30,6 +30,7 @@ import DialogContent from '@mui/material/DialogContent'; import DialogContentText from '@mui/material/DialogContentText'; import DialogTitle from '@mui/material/DialogTitle'; import EditIcon from '@mui/icons-material/Edit'; +import { AddSingleValue, UpdateSingleValue } from '../backend/StringOperation'; interface Data { key: string; @@ -182,6 +183,7 @@ interface EnhancedTableToolbarProps { numSelected: number; ds: string; selected: string[]; + bucket: string; } @@ -223,17 +225,22 @@ function CustomizedInputBase(props: { prop: any; }) { const EnhancedTableToolbar = (props: EnhancedTableToolbarProps) => { - const { numSelected, ds, selected, ...other } = props; + // @ts-ignore + const { numSelected,rows,setRows,ds, selected, bucket, ...other } = props; const [open, setOpen] = React.useState(false); const [operateType, setOperateType] = React.useState(''); const [openAlert, setOpenAlert] = React.useState(false); + const [level, setLevel] = React.useState(''); + const [message, setMessage] = React.useState(''); + + const [key, setKey] = React.useState(''); const [value, setValue] = React.useState(''); const [ttl, setTTL] = React.useState(0); // @ts-ignore - const handleTextInputChange = (type: string,event) => { + const handleTextInputChange = (type: string, event) => { switch (type) { case 'key': setKey(event.target.value); @@ -250,8 +257,14 @@ const EnhancedTableToolbar = (props: EnhancedTableToolbarProps) => { const handleClickOpen = (type: string) => { if (type == 'update' && numSelected != 1) { setOpenAlert(true); + setMessage('Please select one item to update'); + setLevel('error'); + setTimeout(() => { + setOpenAlert(false); + }, 2000); return; } + setKey(selected[0]); setOpen(true); setOperateType(type); }; @@ -261,19 +274,63 @@ const EnhancedTableToolbar = (props: EnhancedTableToolbarProps) => { }; //@ts-ignore const handleSubmit = (event) => { + let success =false; event.preventDefault(); - const data = new FormData(event.currentTarget); - console.log(data); const form = { key: key, value: value, ttl: ttl, }; if (operateType == 'add') { - - + AddSingleValue(bucket, form.key, form.value, form.ttl).then((res) => { + if (res.data.code == 200) { + setOpenAlert(true); + setMessage('Add Success'); + setLevel('success'); + success = true; + } else { + setOpenAlert(true); + setMessage('Add Failed'); + setLevel('error'); + } + }); } else if (operateType == 'update') { - + UpdateSingleValue(bucket, form.key, form.value, form.ttl).then((res) => { + if (res.data.code == 200) { + setOpenAlert(true); + setMessage('Update Success'); + setLevel('success'); + setTimeout(() => { + setOpenAlert(false); + }, 2000); + setOpen(false); + success = true; + } else { + setOpenAlert(true); + setMessage('Update Failed'); + setLevel('error'); + } + }); + } + setTimeout(() => { + setOpenAlert(false); + }, 2000); + + if(success){ + //find key from rows and update + let tmp = rows as Data[]; + let index = tmp.findIndex((item) => item.key == key); + if (index != -1) { + tmp[index].value = value; + tmp[index].length = value.length; + }else { + tmp.push({key:key,value:value,length:value.length}); + } + setRows(tmp); + setTimeout(() => { + setOpenAlert(false); + }, 2000); + setOpen(false); } //reset setKey(''); @@ -368,7 +425,9 @@ const EnhancedTableToolbar = (props: EnhancedTableToolbarProps) => { variant='standard' value={operateType == 'add' ? null : selected[0]} disabled={operateType == 'add' ? false : true} - onChange={(e)=>{handleTextInputChange('key',e)}} + onChange={(e) => { + handleTextInputChange('key', e); + }} /> { label='VALUE' fullWidth variant='standard' - onChange={(e)=>{handleTextInputChange('value',e)}} + onChange={(e) => { + handleTextInputChange('value', e); + }} /> { type='number' fullWidth variant='standard' - onChange={(e)=>{handleTextInputChange('value',e)}} + onChange={(e) => { + handleTextInputChange('value', e); + }} /> @@ -403,12 +466,12 @@ const EnhancedTableToolbar = (props: EnhancedTableToolbarProps) => { { setOpenAlert(false); - }} severity='error' sx={{ width: '100%' }}> - Please select one key to update + }} // @ts-ignore + severity={level} sx={{ width: '100%' }}> + {message} @@ -417,7 +480,7 @@ const EnhancedTableToolbar = (props: EnhancedTableToolbarProps) => { export default function EnhancedTable(props: any) { - const [rows, setRows] = React.useState([]); + let [rows, setRows] = React.useState([]); const [back, setBack] = React.useState([]); const [order, setOrder] = React.useState('asc'); @@ -447,7 +510,7 @@ export default function EnhancedTable(props: any) { let ds = props.condition.ds; if (ds == 'string') { headCells[0].label = 'Key'; - } else if (ds == 'list' || ds == 'set') { + } else if (ds == 'list' || ds == 'set' || ds == 'zset') { headCells[0].label = 'Preview'; } } @@ -510,6 +573,7 @@ export default function EnhancedTable(props: any) { @@ -579,7 +643,7 @@ export default function EnhancedTable(props: any) { {emptyRows > 0 && (