From 79e10f9cadf556f417343832d0ccf8b0b9bb736e Mon Sep 17 00:00:00 2001 From: George Date: Wed, 9 Sep 2026 16:04:34 +0530 Subject: [PATCH] feat: --Added delete funct --Added uuid funct --- src/App.css | 28 +++++++++-- src/App.tsx | 134 ++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 128 insertions(+), 34 deletions(-) diff --git a/src/App.css b/src/App.css index c6a506f..216639d 100644 --- a/src/App.css +++ b/src/App.css @@ -265,7 +265,8 @@ } .primary-button, -.secondary-button { +.secondary-button, +.danger-button { display: inline-flex; align-items: center; justify-content: center; @@ -292,7 +293,8 @@ } .primary-button:disabled, -.secondary-button:disabled { +.secondary-button:disabled, +.danger-button:disabled { cursor: not-allowed; opacity: 0.65; } @@ -315,11 +317,31 @@ .primary-button:focus-visible, .secondary-button:focus-visible, +.danger-button:focus-visible, .register-form input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } +.danger-button { + min-height: 34px; + border: 1px solid #ef4444; + background: #ef4444; + color: #ffffff; + font-size: 14px; + padding-inline: 12px; +} + +.danger-button:hover { + border-color: #dc2626; + background: #dc2626; +} + +.danger-button:disabled:hover { + border-color: #ef4444; + background: #ef4444; +} + .status-message { width: fit-content; margin-bottom: 18px; @@ -410,7 +432,7 @@ .nodes-table { width: 100%; - min-width: 720px; + min-width: 820px; border-collapse: collapse; color: var(--text-h); font-size: 14px; diff --git a/src/App.tsx b/src/App.tsx index 8629521..8c37e9f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -37,6 +37,7 @@ type NodeInterface = { port: number dbname: string user: string + uuid: string } type NodeInterfacesResponse = { @@ -46,6 +47,11 @@ type NodeInterfacesResponse = { message?: string } +type DeleteNodeInterfaceResponse = { + status: string + message?: string +} + const getSavedTheme = (): Theme => { try { return localStorage.getItem('theme') === 'dark' ? 'dark' : 'light' @@ -154,6 +160,34 @@ const getNodeInterfaces = async (): Promise => { return response.json() as Promise } +const deleteNodeInterface = async ( + node: NodeInterface, +): Promise => { + const accessToken = localStorage.getItem('access_token') + const headers: Record = {} + const params = new URLSearchParams({ + uuid: node.uuid, + }) + + if (accessToken) { + headers.Authorization = `Bearer ${accessToken}` + } + + const response = await fetch( + `${API_BASE_URL}/spock/del-node-interfaces?${params.toString()}`, + { + method: 'DELETE', + headers, + }, + ) + + if (!response.ok) { + throw new Error('Failed to delete node interface') + } + + return response.json() as Promise +} + function App() { const [isCollapsed, setIsCollapsed] = useState(false) const [activePage, setActivePage] = useState(getSavedPage) @@ -166,6 +200,7 @@ function App() { const [nodes, setNodes] = useState([]) const [nodesStatus, setNodesStatus] = useState('idle') const [nodesError, setNodesError] = useState('') + const [deletingNodeId, setDeletingNodeId] = useState(null) const nextTheme = theme === 'light' ? 'dark' : 'light' const loadNodeInterfaces = async () => { @@ -270,6 +305,28 @@ function App() { } } + const handleDeleteNodeClick = async (node: NodeInterface) => { + setDeletingNodeId(node.if_id) + setNodesError('') + + try { + const deleteResponse = await deleteNodeInterface(node) + + if (deleteResponse.status !== 'success') { + throw new Error(deleteResponse.message ?? 'Failed to delete node') + } + + await loadNodeInterfaces() + } catch (error) { + setNodesStatus('error') + setNodesError( + error instanceof Error ? error.message : 'Failed to delete node', + ) + } finally { + setDeletingNodeId(null) + } + } + return (
) : null} -
- {nodesStatus === 'loading' ? ( -

Loading nodes...

- ) : nodes.length > 0 ? ( - - - - - - - - - - - - - {nodes.map((node) => ( - - - - - - - + {!isRegisterFormOpen && ( +
+ {nodesStatus === 'loading' ? ( +

Loading nodes...

+ ) : nodes.length > 0 ? ( +
Node IDNode NameHostPortDB NameDB Username
{node.if_nodeid}{node.if_name}{node.host}{node.port}{node.dbname}{node.user}
+ + + + + + + + + - ))} - -
Node IDNode NameHostPortDB NameDB UsernameActions
- ) : ( -

No nodes found.

- )} -
+ + + {nodes.map((node) => ( + + {node.if_nodeid} + {node.if_name} + {node.host} + {node.port} + {node.dbname} + {node.user} + + + + + ))} + + + ) : ( +

No nodes found.

+ )} +
+ )} )}