Skip to content

Commit

Permalink
Merge branch 'Aiven-Open:main' into 2001-use-id-instead-of-name-for-q…
Browse files Browse the repository at this point in the history
…uerying-teams
  • Loading branch information
MovieTone authored Jan 10, 2024
2 parents 593ea48 + b0d10df commit c696919
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 72 deletions.
1 change: 1 addition & 0 deletions coral/src/app/features/dashboard/Dasboard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ describe("Dashboard.tsx", () => {
component = customRender(<Dashboard />, {
memoryRouter: true,
queryClient: true,
aquariumContext: true,
});
});

Expand Down
108 changes: 38 additions & 70 deletions coral/src/app/features/dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,37 @@
import { Alert, Box, Card, Grid, Icon, Template } from "@aivenio/aquarium";
import { Box, Card, Grid, Icon, Template, useToast } from "@aivenio/aquarium";
import { AreaChart, Axis, BarChart, Tooltip } from "@aivenio/aquarium/charts";
import loading from "@aivenio/aquarium/icons/loading";
import { useQuery } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import StatsDisplay from "src/app/components/StatsDisplay";
import { useAuthContext } from "src/app/context-provider/AuthProvider";
import { usePendingRequests } from "src/app/hooks/usePendingRequests";
import {
DashboardsAnalyticsData,
getActivityLogForTeamOverview,
getDashboardStats,
} from "src/domain/analytics";
import { parseErrorMsg } from "src/services/mutation-utils";
import { useDashboardData } from "src/app/features/dashboard/hooks/useDashboardData";

const Dashboard = () => {
const {
data: chartData,
isLoading: isLoadingChartData,
isError: isErrorChartData,
error: errorChartData,
} = useQuery<DashboardsAnalyticsData, Error>(
["getActivityLogForTeamOverview"],
{
queryFn: () => getActivityLogForTeamOverview(),
}
);
data: { chartsData, statsData },
isLoading,
isError,
error,
} = useDashboardData();

const {
data: statsData,
isLoading: isLoadingStatsData,
isError: isErrorStatsData,
error: errorStatsData,
} = useQuery(["getDashboardStats"], {
queryFn: getDashboardStats,
});
const toast = useToast();

const { TOPIC, ACL, SCHEMA, CONNECTOR } = usePendingRequests();

const { totalTeamTopics, totalOrgTopics } = useAuthContext();
useEffect(() => {
if (isError) {
toast({
message: error,
position: "bottom-left",
variant: "default",
});
}
}, [isError]);

// The following contraption is to allow charts to be responsive despite being rendered in a Card
// Without it, the size of the charts calculated by the ResponsiveContainer they are crapped in under the hood
// will only be calculated on the first render, which makes the entire Dashboard layout unresponsive on viewport resize
// This will remove the Chart components and show the loading state while resizing, and then render them again with the proper size
// Source: https://github.com/recharts/recharts/issues/1423#issuecomment-538670179
const [forceLoading, setForceLoading] = useState(false);

useEffect(() => {
let resizeThrottleTimeout: NodeJS.Timeout;
let skip = false;
Expand All @@ -70,69 +57,56 @@ const Dashboard = () => {
return (
<Template columns={1} gap={"l2"}>
<Card title="Topics" fullWidth>
{isErrorStatsData && (
<Box marginBottom={"l1"}>
<Alert type={"error"}>
Could not gather the topics data: {parseErrorMsg(errorStatsData)}
</Alert>
</Box>
)}
<Grid cols={"4"}>
<StatsDisplay
isLoading={false}
amount={totalTeamTopics}
isLoading={isLoading}
amount={statsData.totalTeamTopics}
entity={"My team's topics"}
/>
<StatsDisplay
isLoading={false}
amount={totalOrgTopics}
isLoading={isLoading}
amount={statsData.totalOrgTopics}
entity={"My organization's topics"}
/>
<StatsDisplay
isLoading={isLoadingStatsData}
amount={statsData?.producerCount}
isLoading={isLoading}
amount={statsData.producerCount}
entity={"My producer topics"}
/>
<StatsDisplay
isLoading={isLoadingStatsData}
amount={statsData?.consumerCount}
isLoading={isLoading}
amount={statsData.consumerCount}
entity={"My consumer topics"}
/>
</Grid>
</Card>
<Card title="My team's pending requests" fullWidth>
<Grid cols={"4"}>
<StatsDisplay
isLoading={TOPIC === undefined}
amount={TOPIC}
isLoading={isLoading}
amount={statsData.pendingTopicRequests}
entity={"Topic requests"}
/>
<StatsDisplay
isLoading={ACL === undefined}
amount={ACL}
isLoading={isLoading}
amount={statsData.pendingAclRequests}
entity={"ACL requests"}
/>
<StatsDisplay
isLoading={SCHEMA === undefined}
amount={SCHEMA}
isLoading={isLoading}
amount={statsData.pendingSchemaRequests}
entity={"Schema requests"}
/>
<StatsDisplay
isLoading={CONNECTOR === undefined}
amount={CONNECTOR}
isLoading={isLoading}
amount={statsData.pendingConnectorRequests}
entity={"Connector requests"}
/>
</Grid>
</Card>

<Card title="My team's requests per day" fullWidth>
{isErrorChartData && (
<Alert type={"error"}>
Could not gather the requests per day data :{" "}
{parseErrorMsg(errorChartData)}
</Alert>
)}
{isLoadingChartData || forceLoading ? (
{isLoading || forceLoading ? (
<Box.Flex
justifyContent={"center"}
alignContent={"center"}
Expand All @@ -142,7 +116,7 @@ const Dashboard = () => {
<Icon icon={loading} fontSize={"30px"} />
</Box.Flex>
) : (
<AreaChart height={250} data={chartData?.requestsPerDay}>
<AreaChart height={250} data={chartsData?.requestsPerDay}>
<Axis.XAxis dataKey="date" interval={"equidistantPreserveStart"} />
<Axis.YAxis width={10} />
<AreaChart.Area dataKey="Requests" />
Expand All @@ -152,13 +126,7 @@ const Dashboard = () => {
</Card>

<Card title="My team's topics per environment" fullWidth>
{isErrorChartData && (
<Alert type={"error"}>
Could not gather the topics per environment data:{" "}
{parseErrorMsg(errorChartData)}
</Alert>
)}
{isLoadingChartData || forceLoading ? (
{isLoading || forceLoading ? (
<Box.Flex
justifyContent={"center"}
alignContent={"center"}
Expand All @@ -171,7 +139,7 @@ const Dashboard = () => {
<BarChart
height={250}
layout={"vertical"}
data={chartData?.topicsPerEnv}
data={chartsData?.topicsPerEnv}
>
<Axis.XAxis dataKey="environment" />
<Axis.YAxis width={10} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,16 @@ exports[`Dashboard.tsx renders correct DOM according to data received from getRe
<div
class="typography-heading text-grey-70"
>
0
<span
class="visually-hidden"
>
Loading information
</span>
<div
aria-label="Loading..."
class="Aquarium-Skeleton bg-grey-5 h-auto before:content-['_'] whitespace-pre origin-[0%_45%] scale-[0.55] block animate-pulse"
role="progressbar"
/>
</div>
<div
class="typography-small text-grey-50"
Expand All @@ -42,7 +51,16 @@ exports[`Dashboard.tsx renders correct DOM according to data received from getRe
<div
class="typography-heading text-grey-70"
>
0
<span
class="visually-hidden"
>
Loading information
</span>
<div
aria-label="Loading..."
class="Aquarium-Skeleton bg-grey-5 h-auto before:content-['_'] whitespace-pre origin-[0%_45%] scale-[0.55] block animate-pulse"
role="progressbar"
/>
</div>
<div
class="typography-small text-grey-50"
Expand Down Expand Up @@ -264,5 +282,6 @@ exports[`Dashboard.tsx renders correct DOM according to data received from getRe
</div>
</div>
</div>
<div />
</div>
`;
88 changes: 88 additions & 0 deletions coral/src/app/features/dashboard/hooks/useDashboardData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { useQuery } from "@tanstack/react-query";
import {
DashboardsAnalyticsData,
getActivityLogForTeamOverview,
getDashboardStats,
} from "src/domain/analytics";
import { AuthUser, getAuth } from "src/domain/auth-user";
import { getRequestsWaitingForApproval } from "src/domain/requests";

type DashboardData = {
chartsData?: DashboardsAnalyticsData;
statsData: {
producerCount?: number;
consumerCount?: number;
totalTeamTopics?: number;
totalOrgTopics?: number;
pendingTopicRequests?: number;
pendingAclRequests?: number;
pendingSchemaRequests?: number;
pendingConnectorRequests?: number;
};
};

export const useDashboardData = (): {
data: DashboardData;
isLoading: boolean;
isError: boolean;
error: string;
} => {
const {
data: chartsData,
isLoading: isLoadingChartsData,
isError: isErrorChartsData,
} = useQuery<DashboardsAnalyticsData, Error>(
["getActivityLogForTeamOverview"],
{
queryFn: () => getActivityLogForTeamOverview(),
}
);

const {
data: statsData,
isLoading: isLoadingStatsData,
isError: isErrorStatsData,
} = useQuery(["getDashboardStats"], {
queryFn: getDashboardStats,
});

const {
data: pendingRequestsData,
isLoading: isLoadingPendingRequestsData,
isError: isErrorPendingRequestsData,
} = useQuery(["getRequestsWaitingForApproval"], {
queryFn: getRequestsWaitingForApproval,
});

const {
data: authUserData,
isLoading: isLoadingAuthUserData,
isError: isErrorAuthUserData,
} = useQuery<AuthUser | undefined>(["user-getAuth-data"], getAuth);

return {
data: {
chartsData,
statsData: {
...statsData,
totalTeamTopics: authUserData?.totalTeamTopics,
totalOrgTopics: authUserData?.totalOrgTopics,
pendingTopicRequests: pendingRequestsData?.TOPIC,
pendingAclRequests: pendingRequestsData?.ACL,
pendingSchemaRequests: pendingRequestsData?.SCHEMA,
pendingConnectorRequests: pendingRequestsData?.CONNECTOR,
},
},
isLoading:
isLoadingChartsData ||
isLoadingStatsData ||
isLoadingAuthUserData ||
isLoadingPendingRequestsData,
isError:
isErrorChartsData ||
isErrorStatsData ||
isErrorAuthUserData ||
isErrorPendingRequestsData,
error: "Dashboard data could not be loaded",
};
};

0 comments on commit c696919

Please sign in to comment.