feat:
--Added delete funct --Added uuid funct
This commit is contained in:
1 parent
eb16c93fb0
commit
79e10f9cad
2 files changed
+128
-34
No files matched your search
+103
-31
@@ -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<NodeInterfacesResponse> => {
|
||||
return response.json() as Promise<NodeInterfacesResponse>
|
||||
}
|
||||
|
||||
const deleteNodeInterface = async (
|
||||
node: NodeInterface,
|
||||
): Promise<DeleteNodeInterfaceResponse> => {
|
||||
const accessToken = localStorage.getItem('access_token')
|
||||
const headers: Record<string, string> = {}
|
||||
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<DeleteNodeInterfaceResponse>
|
||||
}
|
||||
|
||||
function App() {
|
||||
const [isCollapsed, setIsCollapsed] = useState(false)
|
||||
const [activePage, setActivePage] = useState<PageId>(getSavedPage)
|
||||
@@ -166,6 +200,7 @@ function App() {
|
||||
const [nodes, setNodes] = useState<NodeInterface[]>([])
|
||||
const [nodesStatus, setNodesStatus] = useState<NodesStatus>('idle')
|
||||
const [nodesError, setNodesError] = useState('')
|
||||
const [deletingNodeId, setDeletingNodeId] = useState<number | null>(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 (
|
||||
<div
|
||||
className={`app-shell theme-${theme} ${isCollapsed ? 'nav-collapsed' : ''}`}
|
||||
@@ -442,38 +499,53 @@ function App() {
|
||||
</form>
|
||||
) : null}
|
||||
|
||||
<div className="nodes-table-wrap">
|
||||
{nodesStatus === 'loading' ? (
|
||||
<p className="table-state">Loading nodes...</p>
|
||||
) : nodes.length > 0 ? (
|
||||
<table className="nodes-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Node ID</th>
|
||||
<th>Node Name</th>
|
||||
<th>Host</th>
|
||||
<th>Port</th>
|
||||
<th>DB Name</th>
|
||||
<th>DB Username</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{nodes.map((node) => (
|
||||
<tr key={node.if_id}>
|
||||
<td>{node.if_nodeid}</td>
|
||||
<td>{node.if_name}</td>
|
||||
<td>{node.host}</td>
|
||||
<td>{node.port}</td>
|
||||
<td>{node.dbname}</td>
|
||||
<td>{node.user}</td>
|
||||
{!isRegisterFormOpen && (
|
||||
<div className="nodes-table-wrap">
|
||||
{nodesStatus === 'loading' ? (
|
||||
<p className="table-state">Loading nodes...</p>
|
||||
) : nodes.length > 0 ? (
|
||||
<table className="nodes-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Node ID</th>
|
||||
<th>Node Name</th>
|
||||
<th>Host</th>
|
||||
<th>Port</th>
|
||||
<th>DB Name</th>
|
||||
<th>DB Username</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
) : (
|
||||
<p className="table-state">No nodes found.</p>
|
||||
)}
|
||||
</div>
|
||||
</thead>
|
||||
<tbody>
|
||||
{nodes.map((node) => (
|
||||
<tr key={node.if_id}>
|
||||
<td>{node.if_nodeid}</td>
|
||||
<td>{node.if_name}</td>
|
||||
<td>{node.host}</td>
|
||||
<td>{node.port}</td>
|
||||
<td>{node.dbname}</td>
|
||||
<td>{node.user}</td>
|
||||
<td>
|
||||
<button
|
||||
type="button"
|
||||
className="danger-button"
|
||||
disabled={deletingNodeId === node.if_id}
|
||||
onClick={() => handleDeleteNodeClick(node)}
|
||||
>
|
||||
{deletingNodeId === node.if_id
|
||||
? 'Deleting'
|
||||
: 'Delete'}
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
) : (
|
||||
<p className="table-state">No nodes found.</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
)}
|
||||
|
||||
|
||||
Reference in new issue
Block a user