+ {/* Page title - hidden on dashboard to give more space to search */}
+ {location.pathname !== "/" && (
+
+
diff --git a/frontend/src/pages/Dashboard.jsx b/frontend/src/pages/Dashboard.jsx
index 922d98a..fcfc20c 100644
--- a/frontend/src/pages/Dashboard.jsx
+++ b/frontend/src/pages/Dashboard.jsx
@@ -1150,23 +1150,46 @@ const Dashboard = () => {
callbacks: {
title: (context) => {
const label = context[0].label;
+
+ // Handle empty or invalid labels
+ if (!label || typeof label !== "string") {
+ return "Unknown Date";
+ }
+
// Format hourly labels (e.g., "2025-10-07T14" -> "Oct 7, 2:00 PM")
if (label.includes("T")) {
- const date = new Date(`${label}:00:00`);
+ try {
+ const date = new Date(`${label}:00:00`);
+ // Check if date is valid
+ if (isNaN(date.getTime())) {
+ return label; // Return original label if date is invalid
+ }
+ return date.toLocaleDateString("en-US", {
+ month: "short",
+ day: "numeric",
+ hour: "numeric",
+ minute: "2-digit",
+ hour12: true,
+ });
+ } catch (error) {
+ return label; // Return original label if parsing fails
+ }
+ }
+
+ // Format daily labels (e.g., "2025-10-07" -> "Oct 7")
+ try {
+ const date = new Date(label);
+ // Check if date is valid
+ if (isNaN(date.getTime())) {
+ return label; // Return original label if date is invalid
+ }
return date.toLocaleDateString("en-US", {
month: "short",
day: "numeric",
- hour: "numeric",
- minute: "2-digit",
- hour12: true,
});
+ } catch (error) {
+ return label; // Return original label if parsing fails
}
- // Format daily labels (e.g., "2025-10-07" -> "Oct 7")
- const date = new Date(label);
- return date.toLocaleDateString("en-US", {
- month: "short",
- day: "numeric",
- });
},
},
},
@@ -1186,24 +1209,49 @@ const Dashboard = () => {
},
callback: function (value, _index, _ticks) {
const label = this.getLabelForValue(value);
+
+ // Handle empty or invalid labels
+ if (!label || typeof label !== "string") {
+ return "Unknown";
+ }
+
// Format hourly labels (e.g., "2025-10-07T14" -> "2 PM")
if (label.includes("T")) {
- const hour = label.split("T")[1];
- const hourNum = parseInt(hour, 10);
- return hourNum === 0
- ? "12 AM"
- : hourNum < 12
- ? `${hourNum} AM`
- : hourNum === 12
- ? "12 PM"
- : `${hourNum - 12} PM`;
+ try {
+ const hour = label.split("T")[1];
+ const hourNum = parseInt(hour, 10);
+
+ // Validate hour number
+ if (isNaN(hourNum) || hourNum < 0 || hourNum > 23) {
+ return hour; // Return original hour if invalid
+ }
+
+ return hourNum === 0
+ ? "12 AM"
+ : hourNum < 12
+ ? `${hourNum} AM`
+ : hourNum === 12
+ ? "12 PM"
+ : `${hourNum - 12} PM`;
+ } catch (error) {
+ return label; // Return original label if parsing fails
+ }
}
+
// Format daily labels (e.g., "2025-10-07" -> "Oct 7")
- const date = new Date(label);
- return date.toLocaleDateString("en-US", {
- month: "short",
- day: "numeric",
- });
+ try {
+ const date = new Date(label);
+ // Check if date is valid
+ if (isNaN(date.getTime())) {
+ return label; // Return original label if date is invalid
+ }
+ return date.toLocaleDateString("en-US", {
+ month: "short",
+ day: "numeric",
+ });
+ } catch (error) {
+ return label; // Return original label if parsing fails
+ }
},
},
grid: {
diff --git a/frontend/src/pages/Hosts.jsx b/frontend/src/pages/Hosts.jsx
index 462c543..7c5f34d 100644
--- a/frontend/src/pages/Hosts.jsx
+++ b/frontend/src/pages/Hosts.jsx
@@ -1570,6 +1570,7 @@ const BulkAssignModal = ({
isLoading,
}) => {
const [selectedGroupId, setSelectedGroupId] = useState("");
+ const bulkHostGroupId = useId();
// Fetch host groups for selection
const { data: hostGroups } = useQuery({
@@ -1588,28 +1589,31 @@ const BulkAssignModal = ({
return (
-
+
-
+
Assign to Host Group
-
+
Assigning {selectedHosts.length} host
{selectedHosts.length !== 1 ? "s" : ""}:
-
+
{selectedHostNames.map((friendlyName) => (
-
+
• {friendlyName}
))}
@@ -1620,7 +1624,7 @@ const BulkAssignModal = ({
@@ -1628,7 +1632,7 @@ const BulkAssignModal = ({
id={bulkHostGroupId}
value={selectedGroupId}
onChange={(e) => setSelectedGroupId(e.target.value)}
- className="w-full px-3 py-2 border border-secondary-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500"
+ className="w-full px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-white dark:bg-secondary-700 text-secondary-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500"
>
{hostGroups?.map((group) => (
@@ -1637,7 +1641,7 @@ const BulkAssignModal = ({
))}
-
+
Select a group to assign these hosts to, or leave ungrouped.
diff --git a/frontend/src/utils/osIcons.jsx b/frontend/src/utils/osIcons.jsx
index 1bc6b42..a6c33e3 100644
--- a/frontend/src/utils/osIcons.jsx
+++ b/frontend/src/utils/osIcons.jsx
@@ -29,12 +29,11 @@ export const getOSIcon = (osType) => {
os.includes("rhel") ||
os.includes("red hat") ||
os.includes("almalinux") ||
- os.includes("rocky") ||
- os === "ol" ||
- os.includes("oraclelinux") ||
- os.includes("oracle linux")
+ os.includes("rocky")
)
return SiCentos;
+ if (os === "ol" || os.includes("oraclelinux") || os.includes("oracle linux"))
+ return SiLinux; // Use generic Linux icon for Oracle Linux
if (os.includes("fedora")) return SiFedora;
if (os.includes("arch")) return SiArchlinux;
if (os.includes("alpine")) return SiAlpinelinux;