diff --git a/Data/Server/WebUI/src/Devices/Device_Details.jsx b/Data/Server/WebUI/src/Devices/Device_Details.jsx
index 9dd1cee..b103856 100644
--- a/Data/Server/WebUI/src/Devices/Device_Details.jsx
+++ b/Data/Server/WebUI/src/Devices/Device_Details.jsx
@@ -209,7 +209,7 @@ export default function DeviceDetails({ device, onBack }) {
const summary = details.summary || {};
const summaryItems = [
- { label: "Device Name", value: summary.hostname || agent.hostname || device?.hostname || "unknown" },
+ { label: "Hostname", value: summary.hostname || agent.hostname || device?.hostname || "unknown" },
{ label: "Operating System", value: summary.operating_system || agent.agent_operating_system || "unknown" },
{ label: "Device Type", value: summary.device_type || "unknown" },
{ label: "Last User", value: (
diff --git a/Data/Server/WebUI/src/Devices/Device_List.jsx b/Data/Server/WebUI/src/Devices/Device_List.jsx
index 1fb8a26..93c80f3 100644
--- a/Data/Server/WebUI/src/Devices/Device_List.jsx
+++ b/Data/Server/WebUI/src/Devices/Device_List.jsx
@@ -17,10 +17,12 @@ import {
Menu,
MenuItem,
Popover,
- TextField
+ TextField,
+ Tooltip
} from "@mui/material";
import MoreVertIcon from "@mui/icons-material/MoreVert";
import FilterListIcon from "@mui/icons-material/FilterList";
+import ViewColumnIcon from "@mui/icons-material/ViewColumn";
import { DeleteDeviceDialog } from "../Dialogs.jsx";
import QuickJob from "../Scheduling/Quick_Job.jsx";
@@ -59,26 +61,44 @@ export default function DeviceList({ onSelectDevice }) {
const [quickJobOpen, setQuickJobOpen] = useState(false);
// Column configuration and rearranging state
+ const COL_LABELS = useMemo(
+ () => ({
+ status: "Status",
+ hostname: "Hostname",
+ description: "Description",
+ lastUser: "Last User",
+ type: "Type",
+ os: "OS",
+ internalIp: "Internal IP",
+ externalIp: "External IP",
+ lastReboot: "Last Reboot",
+ created: "Created",
+ lastSeen: "Last Seen",
+ }),
+ []
+ );
+
const defaultColumns = useMemo(
() => [
- { id: "status", label: "Status" },
- { id: "hostname", label: "Hostname" },
- { id: "lastUser", label: "Last User" },
- { id: "type", label: "Type" },
- { id: "os", label: "OS" },
- { id: "created", label: "Created" }
+ { id: "status", label: COL_LABELS.status },
+ { id: "hostname", label: COL_LABELS.hostname },
+ { id: "description", label: COL_LABELS.description },
+ { id: "lastUser", label: COL_LABELS.lastUser },
+ { id: "type", label: COL_LABELS.type },
+ { id: "os", label: COL_LABELS.os },
],
- []
+ [COL_LABELS]
);
const [columns, setColumns] = useState(defaultColumns);
const dragColId = useRef(null);
+ const [colChooserAnchor, setColChooserAnchor] = useState(null);
// Per-column filters
const [filters, setFilters] = useState({});
const [filterAnchor, setFilterAnchor] = useState(null); // { id, anchorEl }
// Cache device details to avoid re-fetching every refresh
- const [detailsByHost, setDetailsByHost] = useState({}); // hostname -> { lastUser, created, createdTs }
+ const [detailsByHost, setDetailsByHost] = useState({}); // hostname -> cached fields
const fetchAgents = useCallback(async () => {
try {
@@ -98,6 +118,10 @@ export default function DeviceList({ onSelectDevice }) {
type: a.device_type || details.type || "",
created: details.created || "",
createdTs: details.createdTs || 0,
+ internalIp: details.internalIp || "",
+ externalIp: details.externalIp || "",
+ lastReboot: details.lastReboot || "",
+ description: details.description || "",
};
});
setRows(arr);
@@ -129,9 +153,22 @@ export default function DeviceList({ onSelectDevice }) {
createdTs = isNaN(parsed) ? 0 : Math.floor(parsed / 1000);
}
const deviceType = (summary.device_type || "").trim();
+ const internalIp = summary.internal_ip || "";
+ const externalIp = summary.external_ip || "";
+ const lastReboot = summary.last_reboot || "";
+ const description = summary.description || "";
setDetailsByHost((prev) => ({
...prev,
- [h]: { lastUser, created: createdRaw, createdTs, type: deviceType },
+ [h]: {
+ lastUser,
+ created: createdRaw,
+ createdTs,
+ type: deviceType,
+ internalIp,
+ externalIp,
+ lastReboot,
+ description,
+ },
}));
} catch {
// ignore per-host failure
@@ -150,6 +187,10 @@ export default function DeviceList({ onSelectDevice }) {
type: det.type || r.type,
created: det.created || r.created,
createdTs: det.createdTs || r.createdTs,
+ internalIp: det.internalIp || r.internalIp,
+ externalIp: det.externalIp || r.externalIp,
+ lastReboot: det.lastReboot || r.lastReboot,
+ description: det.description || r.description,
};
})
);
@@ -176,14 +217,24 @@ export default function DeviceList({ onSelectDevice }) {
return row.status || "";
case "hostname":
return row.hostname || "";
+ case "description":
+ return row.description || "";
case "lastUser":
return row.lastUser || "";
case "type":
return row.type || "";
case "os":
return row.os || "";
+ case "internalIp":
+ return row.internalIp || "";
+ case "externalIp":
+ return row.externalIp || "";
+ case "lastReboot":
+ return row.lastReboot || "";
case "created":
return formatCreated(row.created, row.createdTs);
+ case "lastSeen":
+ return formatLastSeen(row.lastSeen);
default:
return "";
}
@@ -310,7 +361,16 @@ export default function DeviceList({ onSelectDevice }) {
Devices
-
+
+
+ setColChooserAnchor(e.currentTarget)}
+ sx={{ color: "#bbb", mr: 1 }}
+ >
+
+
+