Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(portal): display 0 instead of gap on charts when no data from API #140

Merged
merged 22 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5c49eb3
fix(portal): display 0 instead of gap on charts when no data from API
KsiBart Nov 13, 2024
4d4b687
fix(portal): adjust useMemo to not allow undefined values
KsiBart Nov 14, 2024
6546486
Merge branch 'main' into 19-feature-control-plane-fix-null-chart
KsiBart Nov 14, 2024
d389284
fix(portal): adjust recent date on charts
KsiBart Nov 14, 2024
9056c56
fix(portal): reset range time if recent date selected
KsiBart Nov 14, 2024
d773b54
fix(portal): add test data
KsiBart Nov 15, 2024
c3aac65
Merge branch 'main' into 19-feature-control-plane-fix-null-chart
KsiBart Nov 15, 2024
c3f3317
fix(portal): add test data for activity diagram
KsiBart Nov 15, 2024
90e73fc
fix(portal): add test case with no data
KsiBart Nov 15, 2024
52f99e5
fix(portal): adjust coverage
KsiBart Nov 15, 2024
df5e1ac
Merge branch 'main' into 19-feature-control-plane-fix-null-chart
KsiBart Nov 15, 2024
7fa8cd5
fix(portal): remove unnecesary fn
KsiBart Nov 15, 2024
661b3db
Add another case for 0,5% coverage
KsiBart Nov 15, 2024
85c1733
fix(portal): env selection
KsiBart Nov 15, 2024
e133c91
Merge branch 'main' into 19-feature-control-plane-fix-null-chart
KsiBart Nov 15, 2024
e652de0
fix(portal): adjust code in tests
KsiBart Nov 15, 2024
310bd12
fix(portal): adjust setting params and dates
KsiBart Nov 15, 2024
b912f3d
fix(portal): reduce code in tests
KsiBart Nov 15, 2024
08f4479
Merge branch 'main' into 19-feature-control-plane-fix-null-chart
KsiBart Nov 15, 2024
bb902b5
fix(portal): reduce code in callbacks, fix date picker
KsiBart Nov 15, 2024
05182b3
fix(portal): add fire event for setting recent days
KsiBart Nov 15, 2024
eee9655
Merge branch 'main' into 19-feature-control-plane-fix-null-chart
KsiBart Nov 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
Loading