Skip to content

Commit

Permalink
Merge branch 'main' into zywang/fix/control-plane-deployment-display-…
Browse files Browse the repository at this point in the history
…error
  • Loading branch information
kuangxiang20240501 authored Nov 15, 2024
2 parents 2e7f5ce + 681c03d commit 0ddaf61
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 75 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import ActivityDiagrams from '@/pages/HomePage/components/ActivityDiagrams';
import { queryClient } from "@/utils/helpers/reactQuery";
import { QueryClientProvider } from "@tanstack/react-query";
import { fireEvent, render } from "@testing-library/react";
import { BrowserRouter } from "react-router-dom";
import { fireEvent } from "@testing-library/react";
import * as homepageHooks from '@/hooks/homepage'
import { render } from "@/__test__/utils";

test("ActivityDiagrams test", () => {
test("ActivityDiagrams test with data", () => {
const envs = {
data: [
{
Expand All @@ -16,14 +15,89 @@ test("ActivityDiagrams test", () => {
],
};

vi.spyOn(homepageHooks, "useGetErrorBrakedown").mockReturnValue({
data: {
errorBreakdowns: [
{
date: "2024-05-30T13:02:03.224486Z",
errors: {
400: 1,
401: 1,
404: 1,
500: 1,
}
},
],
},
isLoading: false,
refetch: vi.fn()
} as any);


vi.spyOn(homepageHooks, "useGetActivityRequests").mockReturnValue({
data: {
requestStatistics: [
{
date: "2024-05-30T13:02:03.224486Z",
success: 1,
error: 2,
},
],
},
isLoading: false,
refetch: vi.fn(),
isRefetching: false
} as any);

const { container, getByTestId } = render(
<QueryClientProvider client={queryClient}>
<BrowserRouter>
<ActivityDiagrams envs={envs.data} />
</BrowserRouter>
</QueryClientProvider>
<ActivityDiagrams envs={envs.data} />
);
expect(container).toBeInTheDocument();
const recentButton = getByTestId('recent-7-days');
const recentButton = getByTestId('recent-90-days');
fireEvent.click(recentButton);
});

test("ActivityDiagrams test with no data", () => {
const envs = {
data: [
{
id: "32b4832f-fb2f-4c99-b89a-c5c995b18dfc",
productId: "mef.sonata",
createdAt: "2024-05-30T13:02:03.224486Z",
name: "stage",
},
],
};

vi.spyOn(homepageHooks, "useGetErrorBrakedown").mockReturnValue({
data: {
errorBreakdowns: [],
},
isLoading: false,
refetch: vi.fn()
} as any);


vi.spyOn(homepageHooks, "useGetActivityRequests").mockReturnValue({
data: {},
isLoading: false,
refetch: vi.fn(),
isRefetching: false
} as any);

const { container } = render(
<ActivityDiagrams envs={envs.data} />
);
expect(container).toBeInTheDocument();
});

test("ActivityDiagrams test with no data", () => {
const envs = {
data: [],
};

const { container } = render(
<ActivityDiagrams envs={envs.data} />
);
expect(container).toBeInTheDocument();
});
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ const ApiActivityDiagram = ({ props }: Props) => {
}, [props]);

const activityData = useMemo(
() => data?.requestStatistics,
() => (data?.requestStatistics || []).map(entry => ({
...entry,
error: entry.error || 0,
success: entry.success || 0,
})),
[isLoading, data]
);

Expand All @@ -49,7 +53,7 @@ const ApiActivityDiagram = ({ props }: Props) => {
</Flex>
<Spin spinning={isLoading || isRefetching}>
{!isLoading && !activityData
? <NoData icon={EmptyBin}/>
? <NoData icon={EmptyBin} />
: <ResponsiveContainer width="100%" height="100%">
<LineChart width={500} height={300} data={activityData}>
<XAxis
Expand All @@ -74,14 +78,14 @@ const ApiActivityDiagram = ({ props }: Props) => {
/>
<Legend align="right" formatter={(value) => capitalize(value)} />
<Line
type="monotone"
type="bumpX"
dot={false}
dataKey="success"
strokeWidth={5}
stroke="#7AD6BE"
/>
<Line
type="natural"
type="bumpX"
dot={false}
dataKey="error"
strokeWidth={5}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const ErrorDiagram = ({ errorData }: { errorData: Array<unknown> }) => (
barSize={10}
stackId="error"
dataKey={key}
fill={["#A8071A", "#F5222D", "#FF7875", "#FFF1F0"][index]}
fill={["#A8071A", "#F5222D", "#FF7875", "#FFA39E"][index]}
radius={key === "400" ? [10, 10, 0, 0] : 0}
/>
))}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Text } from "@/components/Text";
import {
getCurrentTimeWithZone,
parseDateStartOrEnd,
recentXDays,
TIME_ZONE_FORMAT,
} from "@/utils/constants/format";
import { IEnv } from "@/utils/types/env.type";
import {
Expand All @@ -16,7 +15,7 @@ import {
Select,
} from "antd";
import dayjs from "dayjs";
import { useCallback, useMemo, useState } from "react";
import { useMemo, useState } from "react";
import ApiActivityDiagram from "./ApiActivityDiagram";
import ErrorBrakedownDiagram from "./ErrorDiagram";
import MostPopularEndpoints from "./MostPopularEndpoints";
Expand All @@ -25,9 +24,9 @@ import { capitalize } from 'lodash';

export type DiagramProps = {
envId: string;
requestStartTime: string;
requestEndTime: string;
buyer: string | undefined;
requestStartTime?: string;
requestEndTime?: string;
buyer?: string;
requestTime?: any;
};

Expand All @@ -37,42 +36,30 @@ type Props = {

const { RangePicker } = DatePicker;

const DiagramWrapper = ({ envs }: Props) => {
const ActivityDiagrams = ({ envs }: Props) => {
const stageEnvId =
envs?.find((env: IEnv) => env.name?.toLowerCase() === "stage")?.id ?? "";
const currentTime = getCurrentTimeWithZone();
const [form] = Form.useForm();
const [selectedRecentDate, setSelectedRecentDate] = useState<number | undefined>(7);
const { requestStartTime, requestEndTime } = recentXDays(selectedRecentDate);

const [params, setParams] = useState<DiagramProps>({
envId: stageEnvId,
requestStartTime: currentTime,
requestEndTime: currentTime,
requestStartTime,
requestEndTime,
buyer: undefined,
});

const handleFormValues = useCallback(
(values: DiagramProps) => {
const { requestTime = [] } = values ?? {};
setParams({
envId: values.envId || params.envId,
buyer: values.buyer || params.buyer,
requestStartTime: requestTime?.[0]
? dayjs(requestTime[0]).startOf("day").format(TIME_ZONE_FORMAT)
: currentTime,
requestEndTime: requestTime?.[1]
? dayjs(requestTime[1]).endOf("day").format(TIME_ZONE_FORMAT)
: currentTime,
});
},
[setParams, params]
);

const handleFormValuesChange = useCallback(
(t: any, values: any) => {
if (t.path) return;
handleFormValues(values);
},
[setParams]
);
const handleFormValues = (_: unknown, values: DiagramProps) => {
const { requestTime = [] } = values ?? {};
if(requestTime?.[0]) setSelectedRecentDate(undefined);
setParams({
envId: values.envId || params.envId,
buyer: values.buyer || params.buyer,
requestStartTime: parseDateStartOrEnd(requestTime?.[0], "start") || params.requestStartTime,
requestEndTime: parseDateStartOrEnd(requestTime?.[1], "end") || params.requestEndTime
});
}

const envOptions = useMemo(() => {
return (
Expand All @@ -83,9 +70,16 @@ const DiagramWrapper = ({ envs }: Props) => {
);
}, [envs]);

const setRecentDate = (e: RadioChangeEvent) => {
const { requestStartTime, requestEndTime } = recentXDays(e);
setParams({ ...params, requestStartTime, requestEndTime });
const setRecentDate = ({ target: { value } }: RadioChangeEvent) => {
form.setFieldsValue({ requestTime: null });
const { requestStartTime, requestEndTime } = recentXDays(value);

setSelectedRecentDate(Number(value));
setParams({
...params,
requestStartTime,
requestEndTime,
});
};

return (
Expand All @@ -95,7 +89,7 @@ const DiagramWrapper = ({ envs }: Props) => {
form={form}
layout="inline"
colon={false}
onValuesChange={handleFormValuesChange}
onValuesChange={handleFormValues}
>
<Flex
style={{ width: "100%", paddingBottom: "16px" }}
Expand All @@ -104,28 +98,19 @@ const DiagramWrapper = ({ envs }: Props) => {
>
<Flex gap={12} align="center">
<Text.BoldMedium>Activity diagrams</Text.BoldMedium>

<Form.Item name="envId">
<Select

value={params.envId}
value={form.getFieldValue("envId")}
options={envOptions}
popupMatchSelectWidth={false}
size="middle"
variant="borderless"
placeholder="Stage"
/>
</Form.Item>

<Form.Item name="buyer">
<Select
options={[
{
value: "all",
label: "All buyers",
},
]}
value={params.buyer}
options={[{ value: "all", label: "All buyers" }]}
placeholder="All buyers"
popupMatchSelectWidth={false}
size="middle"
Expand All @@ -137,13 +122,14 @@ const DiagramWrapper = ({ envs }: Props) => {
</Flex>
<Flex align="center">
<Form.Item>
<Radio.Group onChange={setRecentDate} size="middle" >
<Radio.Button value="7" data-testid="recent-7-days">Recent 7 days</Radio.Button>
<Radio.Button value="90">Recent 3 months</Radio.Button>
<Radio.Group onChange={setRecentDate} value={selectedRecentDate} size="middle" >
<Radio.Button value={7}>Recent 7 days</Radio.Button>
<Radio.Button value={90} data-testid="recent-90-days">Recent 3 months</Radio.Button>
</Radio.Group>
</Form.Item>
<Form.Item name="requestTime">
<RangePicker
value={[dayjs(params.requestStartTime), dayjs(params.requestEndTime)]}
size="middle"
placeholder={["Select time", "Select time"]}
/>
Expand All @@ -166,4 +152,4 @@ const DiagramWrapper = ({ envs }: Props) => {
);
};

export default DiagramWrapper;
export default ActivityDiagrams;
4 changes: 2 additions & 2 deletions kraken-app/kraken-app-portal/src/pages/HomePage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import QuickStartGuide from "./components/QuickStartGuide";

const HomePage = () => {
const { currentProduct } = useAppStore();
const { data: envs } = useGetProductEnvs(currentProduct);
const { data: envs, isLoading } = useGetProductEnvs(currentProduct);

return (
<PageLayout title="" style={{ background: "#F0F2F5", paddingTop: "15px" }}>
<QuickStartGuide />
{envs && <ActivityDiagrams envs={envs.data} />}
{(!isLoading && envs) && <ActivityDiagrams envs={envs.data} />}
</PageLayout>
);
};
Expand Down
14 changes: 10 additions & 4 deletions kraken-app/kraken-app-portal/src/utils/constants/format.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { RadioChangeEvent } from 'antd';
import dayjs from "dayjs";
import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";
Expand All @@ -18,11 +17,18 @@ export const formatDiagramDate = (value: any): string => {
return dayjs(value).format("D-M");
};

export const recentXDays = (e: RadioChangeEvent) => {
export const recentXDays = (value?: number) => {
if(!value) return {}

const requestEndTime = getCurrentTimeWithZone();
const requestStartTime =
e.target.value === "7"
value === 7
? dayjs().subtract(7, "days").format(TIME_ZONE_FORMAT)
: dayjs().subtract(7, "months").format(TIME_ZONE_FORMAT);
: dayjs().subtract(3, "months").format(TIME_ZONE_FORMAT);
return { requestStartTime, requestEndTime }
};

export const parseDateStartOrEnd = (date: string | undefined, type: "start" | "end") =>
date
? dayjs(date)[type === "start" ? "startOf" : "endOf"]("day").format(TIME_ZONE_FORMAT)
: getCurrentTimeWithZone();

0 comments on commit 0ddaf61

Please sign in to comment.