Skip to content

Commit b14ceae

Browse files
committed
feat(core-api): add host assets endpoint and refresh dashboard stats
- getHostAssets: list distinct asset hosts with service counts and discovery time, sortable by value/count/createdAt - statistic: drop inventory-changes endpoint, enrich top technologies with icon URLs via TechnologyForwarderService - console: rework dashboard widgets (recent assets, inventory changes, top technologies), sync orval-generated hooks and msw handlers
1 parent bb0c015 commit b14ceae

16 files changed

Lines changed: 216 additions & 474 deletions

.open-api/open-api.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

console/src/pages/dashboard/components/inventory-changes.tsx

Lines changed: 0 additions & 112 deletions
This file was deleted.

console/src/pages/dashboard/components/recent-assets.tsx

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
CardTitle,
66
} from '@/components/ui/card';
77
import { useWorkspaceState } from '@/hooks/useWorkspaceSelector';
8-
import { useStatisticControllerGetInventoryChanges } from '@/services/apis/gen/queries';
8+
import { useAssetsControllerGetHostAssets } from '@/services/apis/gen/queries';
99
import { ChevronRight, Clock } from 'lucide-react';
1010
import { useNavigate } from '@tanstack/react-router';
1111
import dayjs from 'dayjs';
@@ -18,21 +18,29 @@ const RecentAssets = () => {
1818
const {
1919
state: { selectedWorkspaceId },
2020
} = useWorkspaceState();
21-
const { data, isLoading, error } = useStatisticControllerGetInventoryChanges({
22-
query: {
23-
queryKey: ['inventory-changes', selectedWorkspaceId],
21+
const { data, isLoading, error } = useAssetsControllerGetHostAssets(
22+
{
23+
page: 1,
24+
limit: 10,
25+
sortBy: 'createdAt',
26+
sortOrder: 'DESC',
2427
},
25-
});
28+
{
29+
query: {
30+
queryKey: ['recent-hosts', selectedWorkspaceId],
31+
},
32+
},
33+
);
2634

27-
const recentAssets = data?.recentAssets ?? [];
35+
const recentHosts = data?.data ?? [];
2836

2937
if (isLoading) {
3038
return (
3139
<Card className="h-full">
3240
<CardHeader>
3341
<CardTitle className="flex items-center gap-2">
3442
<Clock className="h-5 w-5 text-primary" />
35-
Recent Assets
43+
Recent Hosts
3644
</CardTitle>
3745
</CardHeader>
3846
<CardContent className="flex h-full items-center justify-center text-sm text-muted-foreground">
@@ -48,7 +56,7 @@ const RecentAssets = () => {
4856
<CardHeader>
4957
<CardTitle className="flex items-center gap-2">
5058
<Clock className="h-5 w-5 text-primary" />
51-
Recent Assets
59+
Recent Hosts
5260
</CardTitle>
5361
</CardHeader>
5462
<CardContent className="flex h-full items-center justify-center text-sm text-red-600">
@@ -63,34 +71,35 @@ const RecentAssets = () => {
6371
<CardHeader>
6472
<CardTitle className="flex items-center gap-2">
6573
<Clock className="h-5 w-5 text-primary" />
66-
Recent Assets
74+
Recent Hosts
6775
</CardTitle>
6876
</CardHeader>
6977
<CardContent className="min-h-0 flex-1">
70-
{recentAssets.length === 0 ? (
78+
{recentHosts.length === 0 ? (
7179
<div className="flex h-full items-center justify-center text-sm text-muted-foreground">
72-
No new assets discovered
80+
No new hosts discovered
7381
</div>
7482
) : (
7583
<div className="min-h-0 h-full space-y-0.5 overflow-y-auto pr-1">
76-
{recentAssets.map((asset) => (
84+
{recentHosts.map((host) => (
7785
<button
78-
key={asset.id}
86+
key={host.id}
7987
className="group flex w-full items-center justify-between gap-2 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-muted/50"
8088
onClick={() =>
8189
navigate({
8290
to: '/assets',
8391
search: {
8492
tab: 'host',
8593
page: 1,
86-
hosts: asset.value,
94+
pageSize: 1,
95+
filter: host.host,
8796
},
8897
})
8998
}
9099
>
91-
<span className="truncate text-sm">{asset.value}</span>
100+
<span className="truncate text-sm">{host.host}</span>
92101
<span className="flex shrink-0 items-center gap-1 text-xs text-muted-foreground">
93-
{dayjs(asset.createdAt).fromNow()}
102+
{dayjs(host.createdAt).fromNow()}
94103
<ChevronRight className="h-3.5 w-3.5 opacity-0 transition-opacity group-hover:opacity-100" />
95104
</span>
96105
</button>

console/src/pages/dashboard/components/top-technologies.tsx

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
22
import { useWorkspaceState } from '@/hooks/useWorkspaceSelector';
33
import { useStatisticControllerGetTopTechnologies } from '@/services/apis/gen/queries';
4-
import { ChevronRight, Layers } from 'lucide-react';
4+
import { ChevronRight, Layers, Boxes } from 'lucide-react';
55
import { useNavigate } from '@tanstack/react-router';
66

77
const TopTechnologies = () => {
@@ -77,14 +77,29 @@ const TopTechnologies = () => {
7777
search: {
7878
tab: 'technology',
7979
page: 1,
80-
techs: item.name,
80+
pageSize: 1,
81+
filter: item.name,
8182
},
8283
})
8384
}
8485
>
85-
<div className="flex items-center justify-between text-sm">
86-
<span className="truncate pr-2 font-medium">{item.name}</span>
87-
<span className="flex items-center gap-1 font-mono text-muted-foreground">
86+
<div className="flex items-center justify-between gap-2 text-sm">
87+
<span className="flex min-w-0 items-center gap-2">
88+
{item.iconUrl ? (
89+
<img
90+
src={item.iconUrl}
91+
alt={item.name}
92+
className="size-4 shrink-0"
93+
onError={(e) => {
94+
e.currentTarget.style.display = 'none';
95+
}}
96+
/>
97+
) : (
98+
<Boxes className="size-4 shrink-0 text-muted-foreground" />
99+
)}
100+
<span className="truncate font-medium">{item.name}</span>
101+
</span>
102+
<span className="flex shrink-0 items-center gap-1 font-mono text-muted-foreground">
88103
{item.count}
89104
<ChevronRight className="h-3.5 w-3.5 opacity-0 transition-opacity group-hover:opacity-100" />
90105
</span>

console/src/pages/dashboard/dashboard.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { useStatisticControllerGetAssetLocations } from '@/services/apis/gen/que
55
import { useState } from 'react';
66
import CreateWorkspace from '../workspaces/create-workspace';
77
import { AssetTrends } from './components/asset-trends';
8-
import InventoryChanges from './components/inventory-changes';
98
import IpLocationsCard from './components/ip-locations-card';
109
import IssuesTimeline from './components/issues-timeline';
1110
import RecentAssets from './components/recent-assets';
@@ -73,8 +72,7 @@ export default function Dashboard() {
7372
<RecentAssets />
7473
</div>
7574
</div>
76-
<div className="grid grid-cols-1 xl:grid-cols-3 gap-4">
77-
<InventoryChanges />
75+
<div className="grid grid-cols-1 xl:grid-cols-2 gap-4">
7876
<TopPorts />
7977
<TopTechnologies />
8078
</div>

0 commit comments

Comments
 (0)