Implemented multi-select functionality and basic context-menu for session table.
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
import times
|
||||
import imguin/[cimgui, glfw_opengl, simple]
|
||||
import ../utils/appImGui
|
||||
import ../../common/[types]
|
||||
import ../../common/[types, utils]
|
||||
|
||||
type
|
||||
SessionsTableComponent = ref object of RootObj
|
||||
title: string
|
||||
agents: seq[Agent]
|
||||
|
||||
selection: ptr ImGuiSelectionBasicStorage
|
||||
|
||||
let exampleAgents: seq[Agent] = @[
|
||||
Agent(
|
||||
@@ -43,6 +43,40 @@ let exampleAgents: seq[Agent] = @[
|
||||
firstCheckin: now() - initDuration(hours = 1, minutes = 30),
|
||||
latestCheckin: now() - initDuration(minutes = 5),
|
||||
sessionKey: [byte 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
|
||||
),
|
||||
Agent(
|
||||
agentId: "C9D8E7F6",
|
||||
listenerId: "L2468135",
|
||||
username: "charlie",
|
||||
hostname: "SERVER-03",
|
||||
domain: "IT",
|
||||
ip: "172.16.0.20",
|
||||
os: "Windows Server 2019",
|
||||
process: "powershell.exe",
|
||||
pid: 7890,
|
||||
elevated: true,
|
||||
sleep: 30,
|
||||
tasks: @[],
|
||||
firstCheckin: now() - initDuration(hours = 3, minutes = 15),
|
||||
latestCheckin: now() - initDuration(minutes = 10),
|
||||
sessionKey: [byte 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
),
|
||||
Agent(
|
||||
agentId: "G1H2I3J4",
|
||||
listenerId: "L1357924",
|
||||
username: "diana",
|
||||
hostname: "WORKSTATION-04",
|
||||
domain: "HR",
|
||||
ip: "192.168.2.15",
|
||||
os: "Windows 10",
|
||||
process: "chrome.exe",
|
||||
pid: 3210,
|
||||
elevated: false,
|
||||
sleep: 90,
|
||||
tasks: @[],
|
||||
firstCheckin: now() - initDuration(hours = 4),
|
||||
latestCheckin: now() - initDuration(minutes = 2),
|
||||
sessionKey: [byte 5, 4, 3, 2, 1, 0, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6]
|
||||
)
|
||||
]
|
||||
|
||||
@@ -50,6 +84,7 @@ proc SessionsTable*(title: string): SessionsTableComponent =
|
||||
result = new SessionsTableComponent
|
||||
result.title = title
|
||||
result.agents = exampleAgents
|
||||
result.selection = ImGuiSelectionBasicStorage_ImGuiSelectionBasicStorage()
|
||||
|
||||
proc draw*(component: SessionsTableComponent, showComponent: ptr bool) =
|
||||
igSetNextWindowSize(vec2(800, 600), ImGuiCond_Once.int32)
|
||||
@@ -62,13 +97,12 @@ proc draw*(component: SessionsTableComponent, showComponent: ptr bool) =
|
||||
ImGuiTableFlags_Reorderable.int32 or
|
||||
ImGuiTableFlags_Hideable.int32 or
|
||||
ImGuiTableFlags_HighlightHoveredColumn.int32 or
|
||||
ImGuiTableFlags_ContextMenuInBody.int32 or
|
||||
ImGuiTableFlags_RowBg.int32 or
|
||||
ImGuiTableFlags_BordersV.int32 or
|
||||
ImGuiTableFlags_BordersH.int32 or
|
||||
ImGuiTableFlags_ScrollY.int32 or
|
||||
ImGuiTableFlags_ScrollX.int32 or
|
||||
ImGuiTableFlags_NoBordersInBodyUntilResize.int32 or
|
||||
ImGuiTableFlags_NoBordersInBodyUntilResize.int32 or
|
||||
ImGui_TableFlags_SizingStretchProp.int32
|
||||
)
|
||||
|
||||
@@ -86,12 +120,20 @@ proc draw*(component: SessionsTableComponent, showComponent: ptr bool) =
|
||||
|
||||
igTableSetupScrollFreeze(0, 1)
|
||||
igTableHeadersRow()
|
||||
|
||||
var multiSelectIO = igBeginMultiSelect(ImGuiMultiSelectFlags_ClearOnEscape.int32 or ImGuiMultiSelectFlags_BoxSelect1d.int32, component.selection[].Size, int32(component.agents.len()))
|
||||
ImGuiSelectionBasicStorage_ApplyRequests(component.selection, multiSelectIO)
|
||||
|
||||
for row in 0..< component.agents.len():
|
||||
|
||||
igTableNextRow(ImGuiTableRowFlags_None.int32, 0.0f)
|
||||
let agent = component.agents[row]
|
||||
if igTableSetColumnIndex(0):
|
||||
igText(agent.agentId)
|
||||
|
||||
if igTableSetColumnIndex(0):
|
||||
# Enable multi-select functionality
|
||||
igSetNextItemSelectionUserData(row)
|
||||
var isSelected = ImGuiSelectionBasicStorage_Contains(component.selection, cast[ImGuiID](row))
|
||||
discard igSelectable_Bool(agent.agentId, isSelected, ImGuiSelectableFlags_SpanAllColumns.int32, vec2(0.0f, 0.0f))
|
||||
if igTableSetColumnIndex(1):
|
||||
igText(agent.ip)
|
||||
if igTableSetColumnIndex(2):
|
||||
@@ -107,6 +149,23 @@ proc draw*(component: SessionsTableComponent, showComponent: ptr bool) =
|
||||
if igTableSetColumnIndex(7):
|
||||
igText(agent.latestCheckin.format("yyyy-MM-dd HH:mm:ss"))
|
||||
|
||||
# Handle right-click context menu
|
||||
# Right-clicking the table header to hide/show columns or reset the layout is only possible when no sessions are selected
|
||||
if component.selection[].Size > 0 and igBeginPopupContextWindow("TableContextMenu", ImGui_PopupFlags_MouseButtonRight.int32):
|
||||
|
||||
if igMenuItem("Interact", "ENTER", false, true):
|
||||
igCloseCurrentPopup()
|
||||
|
||||
if igMenuItem("Remove", "DELETE", false, true):
|
||||
igCloseCurrentPopup()
|
||||
|
||||
igEndPopup()
|
||||
|
||||
|
||||
multiSelectIO = igEndMultiSelect()
|
||||
ImGuiSelectionBasicStorage_ApplyRequests(component.selection, multiSelectIO)
|
||||
|
||||
igEndTable()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user