Skip to content

Commit 3be05a1

Browse files
authored
Merge pull request #270 from middlewarehq/GROW-1467
Add SomethingWentWrong component and first team load done flag
2 parents f3b1d2b + 383403b commit 3be05a1

File tree

4 files changed

+138
-3
lines changed

4 files changed

+138
-3
lines changed

web-server/pages/api/internal/team/[team_id]/dora_metrics.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ endpoint.handle.GET(getSchema, async (req, res) => {
4545
team_id: teamId,
4646
from_date: rawFromDate,
4747
to_date: rawToDate,
48-
branches,
48+
branches
4949
} = req.payload;
5050

5151
const teamProdBranchesMap =
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { Button, Card, Link } from '@mui/material';
2+
import { useRouter } from 'next/router';
3+
import { FC, useEffect, useMemo } from 'react';
4+
5+
import { track } from '@/constants/events';
6+
import { useAuth } from '@/hooks/useAuth';
7+
8+
import Error from './error.svg';
9+
10+
import errPattern from '../ErrorBoundaryFallback/err-pattern.png';
11+
import { FlexBox } from '../FlexBox';
12+
import { Line } from '../Text';
13+
14+
const helpdeskPrefill = (error: string, details: string) => {
15+
if (typeof window === 'undefined') return;
16+
// @ts-ignore
17+
window.FreshworksWidget?.('prefill', 'ticketForm', {
18+
subject: error,
19+
description: details
20+
});
21+
};
22+
23+
export const useHelpdeskPrefill = (error: string, details: string) => {
24+
useEffect(() => {
25+
helpdeskPrefill(error, details);
26+
}, [details, error]);
27+
};
28+
29+
export const useDebug = (
30+
error = 'Something went wrong',
31+
desc = '<<Enter error description>>'
32+
) => {
33+
const router = useRouter();
34+
const { org } = useAuth();
35+
36+
const debugData = useMemo(
37+
() =>
38+
Object.entries({
39+
Page: router.asPath,
40+
'Current Org': `${org?.name} - ${org?.domain}`,
41+
'Current Org ID': `${org?.id}`,
42+
'Time of error': new Date().toString(),
43+
Environment: process.env.NEXT_PUBLIC_APP_ENVIRONMENT
44+
})
45+
.map(([key, value]) => `${key}: ${value}`)
46+
.join('\n'),
47+
[router.asPath, org?.name, org?.domain, org?.id]
48+
);
49+
50+
const details = useMemo(
51+
() =>
52+
`${
53+
typeof desc === 'string' ? desc : JSON.stringify(desc)
54+
}\n\n\nDEBUG DATA:\n\n${debugData}`,
55+
[debugData, desc]
56+
);
57+
58+
useHelpdeskPrefill(error, details);
59+
60+
const mailtoLink = getMailtoLink(error, details.replaceAll('\n', '%0A'));
61+
62+
return { details, debugData, mailtoLink };
63+
};
64+
65+
export const SomethingWentWrong: FC<{ error?: string; desc?: string }> = ({
66+
error = 'Something went wrong',
67+
desc = '<<Enter error description>>',
68+
children
69+
}) => {
70+
const { mailtoLink } = useDebug(error, desc);
71+
72+
useEffect(() => {
73+
track('SOMETHING_WENT_WRONG', { meta: { error, desc } });
74+
}, [desc, error]);
75+
76+
return (
77+
<Card
78+
component={Card}
79+
sx={{
80+
backgroundImage: `url(${errPattern})`,
81+
backgroundSize: '250px',
82+
position: 'relative',
83+
maxWidth: '500px',
84+
m: '2px'
85+
}}
86+
>
87+
<FlexBox bgfy bgcolor="#0003" sx={{ backdropFilter: 'blur(2px)' }} />
88+
<FlexBox relative col centered p={4} gap1 textAlign="center">
89+
<Error width="300px" />
90+
<Line huge bold mt={1} white>
91+
{error}
92+
</Line>
93+
<Line>{desc ?? "We'll fix it shortly"}</Line>
94+
{children ? (
95+
<FlexBox col p={1}>
96+
{children}
97+
</FlexBox>
98+
) : null}
99+
<Line bigish semibold mt={3}>
100+
Feel free to reach out to us
101+
</Line>
102+
<Button component={Link} href={mailtoLink} size="small" target="_blank">
103+
Click here to send an email
104+
</Button>
105+
<Line mt={-1}>or</Line>
106+
<Button
107+
onClick={() => window.location.reload()}
108+
size="small"
109+
color="secondary"
110+
variant="outlined"
111+
>
112+
Click here to reload
113+
</Button>
114+
</FlexBox>
115+
</Card>
116+
);
117+
};
118+
119+
export const getMailtoLink = (subject: string, body: string) =>
120+
`mailto:[email protected][email protected],[email protected]&subject=${subject}&body=<Add details/screenshots here>%0A${body}`;

web-server/src/content/DoraMetrics/DoraMetricsBody.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
useSingleTeamConfig,
1818
useStateBranchConfig
1919
} from '@/hooks/useStateTeamConfig';
20-
import { fetchTeamDoraMetrics } from '@/slices/dora_metrics';
20+
import { doraMetricsSlice, fetchTeamDoraMetrics } from '@/slices/dora_metrics';
2121
import { useDispatch, useSelector } from '@/store';
2222
import { ActiveBranchMode } from '@/types/resources';
2323
import { getRandomLoadMsg } from '@/utils/loading-messages';
@@ -27,6 +27,7 @@ import { ChangeFailureRateCard } from './DoraCards/ChangeFailureRateCard';
2727
import { ChangeTimeCard } from './DoraCards/ChangeTimeCard';
2828
import { MeanTimeToRestoreCard } from './DoraCards/MeanTimeToRestoreCard';
2929
import { WeeklyDeliveryVolumeCard } from './DoraCards/WeeklyDeliveryVolumeCard';
30+
import { SomethingWentWrong } from '@/components/SomethingWentWrong/SomethingWentWrong';
3031

3132
export const DoraMetricsBody = () => {
3233
const dispatch = useDispatch();
@@ -39,7 +40,12 @@ export const DoraMetricsBody = () => {
3940
const isLoading = useSelector(
4041
(s) => s.doraMetrics.requests?.metrics_summary === FetchState.REQUEST
4142
);
43+
const isErrored = useSelector(
44+
(s) => s.doraMetrics.requests?.metrics_summary === FetchState.FAILURE
45+
);
46+
4247
const firstLoadDone = useSelector((s) => s.doraMetrics.firstLoadDone);
48+
4349
const activeBranchMode = useSelector((s) => s.app.branchMode);
4450

4551
const isTeamInsightsEmpty = useSelector(
@@ -85,8 +91,14 @@ export const DoraMetricsBody = () => {
8591

8692
const { isFreshOrg } = useFreshOrgCalculator();
8793

94+
if (isErrored)
95+
return (
96+
<SomethingWentWrong
97+
error="Dora metrics data could not be loaded"
98+
desc="Hey there! Sorry about that, the intern that was supposed to deliver your metrics got lost on the way"
99+
/>
100+
);
88101
if (!firstLoadDone) return <MiniLoader label={getRandomLoadMsg()} />;
89-
90102
if (isTeamInsightsEmpty)
91103
if (isFreshOrg)
92104
return (

web-server/src/slices/dora_metrics.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ export const doraMetricsSlice = createSlice({
6767
state.deploymentPrs = [];
6868
state.team_deployments = initialState.team_deployments;
6969
},
70+
setFirstTeamLoadDone(state: State) {
71+
state.firstLoadDone = true;
72+
},
7073
toggleActiveModeValue(
7174
state: State,
7275
action: PayloadAction<ChangeTimeModes>

0 commit comments

Comments
 (0)