Improve dashboard data handling and visualization. Updated data fetching and chart configurations for better data display.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 705f2157-ef97-4fbd-89e4-8c7f2ecaea90
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7ed01c5f-a82d-405a-b728-b2e3d127c60c/0ab49ba3-2a0b-4884-9cf6-dbdb4748e98c.jpg
This commit is contained in:
alphaeusmote
2025-04-10 00:26:14 +00:00
4 changed files with 41 additions and 31 deletions
@@ -84,10 +84,12 @@ export function DashboardLayout({
type: widget.type,
dataSource: widget.data[0]?.dataSource || "",
config: {
xAxis: widget.config.xAxis,
yAxis: Array.isArray(widget.config.yAxis) ? widget.config.yAxis : [widget.config.yAxis].filter(Boolean),
dimensions: widget.config.dimensions || [],
metrics: widget.config.metrics || [],
xAxis: widget.config.xAxis || "",
yAxis: Array.isArray(widget.config.yAxis)
? widget.config.yAxis.filter(Boolean) as string[]
: (widget.config.yAxis ? [widget.config.yAxis as string] : []),
dimensions: (widget.config.dimensions || []).filter(Boolean) as string[],
metrics: (widget.config.metrics || []).filter(Boolean) as string[],
showLegend: widget.config.showLegend ?? true,
stacked: widget.config.stacked ?? false,
precision: widget.config.precision ?? 2,
@@ -125,6 +125,7 @@ export function DashboardWidget({ id, title, type, data, config, onEdit, onDelet
if (!data || data.length === 0) return <p className="text-muted-foreground text-center py-4">No data available</p>;
const { xAxis, yAxis, dimensions, metrics, colors = COLORS, showLegend = true, stacked = false } = config;
const xAxisKey = xAxis as string;
switch (type) {
case 'bar':
@@ -132,7 +133,7 @@ export function DashboardWidget({ id, title, type, data, config, onEdit, onDelet
<ResponsiveContainer width="100%" height={300}>
<BarChart data={data} margin={{ top: 20, right: 30, left: 20, bottom: 30 }}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey={xAxis} />
<XAxis dataKey={xAxisKey} />
<YAxis />
<Tooltip />
{showLegend && <Legend />}
@@ -140,12 +141,12 @@ export function DashboardWidget({ id, title, type, data, config, onEdit, onDelet
? yAxis.map((axis, index) => (
<Bar
key={axis}
dataKey={axis}
dataKey={axis as string}
stackId={stacked ? "a" : undefined}
fill={colors[index % colors.length]}
/>
))
: yAxis ? <Bar dataKey={yAxis} fill={colors[0]} /> : null
: yAxis ? <Bar dataKey={yAxis as string} fill={colors[0]} /> : null
}
</BarChart>
</ResponsiveContainer>
@@ -156,7 +157,7 @@ export function DashboardWidget({ id, title, type, data, config, onEdit, onDelet
<ResponsiveContainer width="100%" height={300}>
<LineChart data={data} margin={{ top: 20, right: 30, left: 20, bottom: 30 }}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey={xAxis} />
<XAxis dataKey={xAxisKey} />
<YAxis />
<Tooltip />
{showLegend && <Legend />}
@@ -165,12 +166,12 @@ export function DashboardWidget({ id, title, type, data, config, onEdit, onDelet
<Line
key={axis}
type="monotone"
dataKey={axis}
dataKey={axis as string}
stroke={colors[index % colors.length]}
activeDot={{ r: 8 }}
/>
))
: yAxis ? <Line type="monotone" dataKey={yAxis} stroke={colors[0]} activeDot={{ r: 8 }} /> : null
: yAxis ? <Line type="monotone" dataKey={yAxis as string} stroke={colors[0]} activeDot={{ r: 8 }} /> : null
}
</LineChart>
</ResponsiveContainer>
@@ -181,7 +182,7 @@ export function DashboardWidget({ id, title, type, data, config, onEdit, onDelet
<ResponsiveContainer width="100%" height={300}>
<AreaChart data={data} margin={{ top: 20, right: 30, left: 20, bottom: 30 }}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey={xAxis} />
<XAxis dataKey={xAxisKey} />
<YAxis />
<Tooltip />
{showLegend && <Legend />}
@@ -190,13 +191,13 @@ export function DashboardWidget({ id, title, type, data, config, onEdit, onDelet
<Area
key={axis}
type="monotone"
dataKey={axis}
dataKey={axis as string}
stackId={stacked ? "a" : `${index}`}
fill={colors[index % colors.length]}
stroke={colors[index % colors.length]}
/>
))
: yAxis ? <Area type="monotone" dataKey={yAxis} fill={colors[0]} stroke={colors[0]} /> : null
: yAxis ? <Area type="monotone" dataKey={yAxis as string} fill={colors[0]} stroke={colors[0]} /> : null
}
</AreaChart>
</ResponsiveContainer>
@@ -210,8 +211,8 @@ export function DashboardWidget({ id, title, type, data, config, onEdit, onDelet
(Array.isArray(yAxis) && yAxis.length > 0 ? yAxis[0] :
(typeof yAxis === 'string' ? yAxis : "value"));
const name = item[dimensionField];
const value = item[metricField];
const name = item[dimensionField as string];
const value = item[metricField as string];
return { name, value: Number(value) };
}).filter(item => !isNaN(item.value));
+18 -11
View File
@@ -64,19 +64,20 @@ export default function DashboardPage() {
const { data: usersData, isLoading: isLoadingUsers } = useQuery<any>({
queryKey: ['/api/user-dashboard-data'],
queryFn: async () => {
// This would normally come from an API endpoint
// Here we're implementing a mock data fetcher for the dashboard
const response = await fetch('/api/ad/users?properties=name,mail,title,department,employeeId,manager,memberOf,whenCreated');
const response = await fetch('/api/user-dashboard-data');
if (!response.ok) throw new Error('Failed to fetch users');
const users = await response.json();
// Get the structure of the data to determine field types
const fields = getFieldTypes(users.data || []);
const userData = users.data || [];
const fields = getFieldTypes(userData);
console.log('User data fields:', fields);
return {
id: 'users',
name: 'Active Directory Users',
data: users.data || [],
data: userData,
fields,
};
},
@@ -87,17 +88,20 @@ export default function DashboardPage() {
const { data: computersData, isLoading: isLoadingComputers } = useQuery<any>({
queryKey: ['/api/computer-dashboard-data'],
queryFn: async () => {
const response = await fetch('/api/ad/computers?properties=name,operatingSystem,operatingSystemVersion,whenCreated,lastLogonTimestamp,enabled,memberOf');
const response = await fetch('/api/computer-dashboard-data');
if (!response.ok) throw new Error('Failed to fetch computers');
const computers = await response.json();
// Get the structure of the data to determine field types
const fields = getFieldTypes(computers.data || []);
const computerData = computers.data || [];
const fields = getFieldTypes(computerData);
console.log('Computer data fields:', fields);
return {
id: 'computers',
name: 'Active Directory Computers',
data: computers.data || [],
data: computerData,
fields,
};
},
@@ -108,17 +112,20 @@ export default function DashboardPage() {
const { data: groupsData, isLoading: isLoadingGroups } = useQuery<any>({
queryKey: ['/api/group-dashboard-data'],
queryFn: async () => {
const response = await fetch('/api/ad/groups?properties=name,description,whenCreated,member,memberOf');
const response = await fetch('/api/group-dashboard-data');
if (!response.ok) throw new Error('Failed to fetch groups');
const groups = await response.json();
// Get the structure of the data to determine field types
const fields = getFieldTypes(groups.data || []);
const groupData = groups.data || [];
const fields = getFieldTypes(groupData);
console.log('Group data fields:', fields);
return {
id: 'groups',
name: 'Active Directory Groups',
data: groups.data || [],
data: groupData,
fields,
};
},
+5 -5
View File
@@ -5090,19 +5090,19 @@ export async function registerRoutes(app: Express): Promise<Server> {
const connectionId = connections[0].id;
// Get counts from all AD objects
const usersCount = await db.select({ count: sql`count(*)` }).from(adUsers)
const usersCount = await db.select({ count: count() }).from(adUsers)
.where(eq(adUsers.connectionId, connectionId));
const computersCount = await db.select({ count: sql`count(*)` }).from(adComputers)
const computersCount = await db.select({ count: count() }).from(adComputers)
.where(eq(adComputers.connectionId, connectionId));
const groupsCount = await db.select({ count: sql`count(*)` }).from(adGroups)
const groupsCount = await db.select({ count: count() }).from(adGroups)
.where(eq(adGroups.connectionId, connectionId));
const sitesCount = await db.select({ count: sql`count(*)` }).from(adSites)
const sitesCount = await db.select({ count: count() }).from(adSites)
.where(eq(adSites.connectionId, connectionId));
const domainsCount = await db.select({ count: sql`count(*)` }).from(adDomains)
const domainsCount = await db.select({ count: count() }).from(adDomains)
.where(eq(adDomains.connectionId, connectionId));
// Return the counts