Skip to content

Commit 71d54cf

Browse files
committed
refactor(tsx): convert PushDetails view
1 parent 35bbdea commit 71d54cf

File tree

4 files changed

+228
-140
lines changed

4 files changed

+228
-140
lines changed

src/ui/views/PushDetails/PushDetails.jsx renamed to src/ui/views/PushDetails/PushDetails.tsx

Lines changed: 95 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import GridContainer from '../../components/Grid/GridContainer';
77
import Card from '../../components/Card/Card';
88
import CardIcon from '../../components/Card/CardIcon';
99
import CardBody from '../../components/Card/CardBody';
10-
import CardHeader from '../../components/Card/CardHeader';
10+
import CardHeader, { CardHeaderColor } from '../../components/Card/CardHeader';
1111
import CardFooter from '../../components/Card/CardFooter';
1212
import Button from '../../components/CustomButtons/Button';
1313
import Diff from './components/Diff';
@@ -23,51 +23,100 @@ import { CheckCircle, Visibility, Cancel, Block } from '@material-ui/icons';
2323
import Snackbar from '@material-ui/core/Snackbar';
2424
import Tooltip from '@material-ui/core/Tooltip';
2525

26-
export default function Dashboard() {
27-
const { id } = useParams();
28-
const [data, setData] = useState([]);
26+
interface CommitData {
27+
commitTs?: number;
28+
commitTimestamp?: number;
29+
committer: string;
30+
author: string;
31+
authorEmail?: string;
32+
message: string;
33+
}
34+
35+
interface Reviewer {
36+
username: string;
37+
gitAccount: string;
38+
}
39+
40+
interface AttestationData {
41+
reviewer: Reviewer;
42+
timestamp: string | Date;
43+
questions: Array<{ label: string; checked: boolean }>;
44+
}
45+
46+
interface PushData {
47+
id: string;
48+
repo: string;
49+
branch: string;
50+
commitFrom: string;
51+
commitTo: string;
52+
commitData: CommitData[];
53+
diff: {
54+
content: string;
55+
};
56+
canceled?: boolean;
57+
rejected?: boolean;
58+
authorised?: boolean;
59+
attestation?: AttestationData;
60+
autoApproved?: boolean;
61+
timestamp: string | Date;
62+
}
63+
64+
const Dashboard: React.FC = () => {
65+
const { id } = useParams<{ id: string }>();
66+
const [data, setData] = useState<PushData | null>(null);
2967
const [, setAuth] = useState(true);
3068
const [isLoading, setIsLoading] = useState(true);
3169
const [isError, setIsError] = useState(false);
3270
const [message, setMessage] = useState('');
3371
const [attestation, setAttestation] = useState(false);
3472
const navigate = useNavigate();
73+
3574
let isUserAllowedToApprove = true;
3675
let isUserAllowedToReject = true;
37-
function setUserAllowedToApprove(userAllowedToApprove) {
76+
77+
const setUserAllowedToApprove = (userAllowedToApprove: boolean) => {
3878
isUserAllowedToApprove = userAllowedToApprove;
3979
console.log('isUserAllowedToApprove:' + isUserAllowedToApprove);
40-
}
41-
function setUserAllowedToReject(userAllowedToReject) {
80+
};
81+
82+
const setUserAllowedToReject = (userAllowedToReject: boolean) => {
4283
isUserAllowedToReject = userAllowedToReject;
4384
console.log({ isUserAllowedToReject });
44-
}
85+
};
86+
4587
useEffect(() => {
46-
getPush(id, setIsLoading, setData, setAuth, setIsError);
88+
if (id) {
89+
getPush(id, setIsLoading, setData, setAuth, setIsError);
90+
}
4791
}, [id]);
48-
const authorise = async (attestationData) => {
92+
93+
const authorise = async (attestationData: Array<{ label: string; checked: boolean }>) => {
94+
if (!id) return;
4995
await authorisePush(id, setMessage, setUserAllowedToApprove, attestationData);
5096
if (isUserAllowedToApprove) {
5197
navigate('/dashboard/push/');
5298
}
5399
};
54100

55101
const reject = async () => {
102+
if (!id) return;
56103
await rejectPush(id, setMessage, setUserAllowedToReject);
57104
if (isUserAllowedToReject) {
58105
navigate('/dashboard/push/');
59106
}
60107
};
61108

62109
const cancel = async () => {
110+
if (!id) return;
63111
await cancelPush(id, setAuth, setIsError);
64112
navigate(`/dashboard/push/`);
65113
};
66114

67115
if (isLoading) return <div>Loading...</div>;
68116
if (isError) return <div>Something went wrong ...</div>;
117+
if (!data) return <div>No data found</div>;
69118

70-
let headerData = {
119+
let headerData: { title: string; color: CardHeaderColor } = {
71120
title: 'Pending',
72121
color: 'warning',
73122
};
@@ -96,18 +145,18 @@ export default function Dashboard() {
96145
const repoFullName = data.repo.replace('.git', '');
97146
const repoBranch = data.branch.replace('refs/heads/', '');
98147

99-
const generateIcon = (title) => {
148+
const generateIcon = (title: string) => {
100149
switch (title) {
101150
case 'Approved':
102-
return <CheckCircle></CheckCircle>;
151+
return <CheckCircle />;
103152
case 'Pending':
104-
return <Visibility></Visibility>;
153+
return <Visibility />;
105154
case 'Canceled':
106-
return <Cancel></Cancel>;
155+
return <Cancel />;
107156
case 'Rejected':
108-
return <Block></Block>;
157+
return <Block />;
109158
default:
110-
return <Icon></Icon>;
159+
return <Icon />;
111160
}
112161
};
113162

@@ -131,28 +180,18 @@ export default function Dashboard() {
131180
{generateIcon(headerData.title)}
132181
<h3>{headerData.title}</h3>
133182
</CardIcon>
134-
{!(data.canceled || data.rejected || data.authorised) ? (
183+
{!(data.canceled || data.rejected || data.authorised) && (
135184
<div style={{ display: 'inline-flex', padding: '20px' }}>
136-
<Button
137-
color='warning'
138-
onClick={async () => {
139-
await cancel();
140-
}}
141-
>
185+
<Button color='warning' onClick={cancel}>
142186
Cancel
143187
</Button>
144-
<Button
145-
color='danger'
146-
onClick={async () => {
147-
await reject();
148-
}}
149-
>
188+
<Button color='danger' onClick={reject}>
150189
Reject
151190
</Button>
152-
<Attestation approveFn={authorise}></Attestation>
191+
<Attestation approveFn={authorise} />
153192
</div>
154-
) : null}
155-
{data.attestation && data.authorised ? (
193+
)}
194+
{data.attestation && data.authorised && (
156195
<div
157196
style={{
158197
background: '#eee',
@@ -165,13 +204,7 @@ export default function Dashboard() {
165204
textAlign: 'left',
166205
}}
167206
>
168-
<span
169-
style={{
170-
position: 'absolute',
171-
top: 0,
172-
right: 0,
173-
}}
174-
>
207+
<span style={{ position: 'absolute', top: 0, right: 0 }}>
175208
<CheckCircle
176209
style={{
177210
cursor: data.autoApproved ? 'default' : 'pointer',
@@ -188,19 +221,18 @@ export default function Dashboard() {
188221
</span>
189222

190223
{data.autoApproved ? (
191-
<>
192-
<div style={{ paddingTop: '15px' }}>
193-
<p>
194-
<strong>Auto-approved by system</strong>
195-
</p>
196-
</div>
197-
</>
224+
<div style={{ paddingTop: '15px' }}>
225+
<p>
226+
<strong>Auto-approved by system</strong>
227+
</p>
228+
</div>
198229
) : (
199230
<>
200231
<a href={`/dashboard/user/${data.attestation.reviewer.username}`}>
201232
<img
202233
style={{ width: '45px', borderRadius: '20px' }}
203234
src={`https://github.com/${data.attestation.reviewer.gitAccount}.png`}
235+
alt='Reviewer'
204236
/>
205237
</a>
206238
<div>
@@ -225,17 +257,15 @@ export default function Dashboard() {
225257
</kbd>
226258
</Tooltip>
227259

228-
{data.autoApproved ? (
229-
<></>
230-
) : (
260+
{!data.autoApproved && (
231261
<AttestationView
232262
data={data.attestation}
233263
attestation={attestation}
234264
setAttestation={setAttestation}
235265
/>
236266
)}
237267
</div>
238-
) : null}
268+
)}
239269
</CardHeader>
240270
<CardBody>
241271
<GridContainer>
@@ -297,17 +327,19 @@ export default function Dashboard() {
297327
<CardBody>
298328
<Table>
299329
<TableHead>
300-
<TableCell>Timestamp</TableCell>
301-
<TableCell>Committer</TableCell>
302-
<TableCell>Author</TableCell>
303-
<TableCell>Author E-mail</TableCell>
304-
<TableCell>Message</TableCell>
330+
<TableRow>
331+
<TableCell>Timestamp</TableCell>
332+
<TableCell>Committer</TableCell>
333+
<TableCell>Author</TableCell>
334+
<TableCell>Author E-mail</TableCell>
335+
<TableCell>Message</TableCell>
336+
</TableRow>
305337
</TableHead>
306338
<TableBody>
307339
{data.commitData.map((c) => (
308-
<TableRow key={c.commitTimestamp}>
340+
<TableRow key={c.commitTimestamp || c.commitTs}>
309341
<TableCell>
310-
{moment.unix(c.commitTs || c.commitTimestamp).toString()}
342+
{moment.unix(c.commitTs || c.commitTimestamp || 0).toString()}
311343
</TableCell>
312344
<TableCell>
313345
<a
@@ -340,14 +372,16 @@ export default function Dashboard() {
340372
</GridItem>
341373
<GridItem xs={12} sm={12} md={12}>
342374
<Card>
343-
<CardHeader></CardHeader>
375+
<CardHeader />
344376
<CardBody>
345377
<Diff diff={data.diff.content} />
346378
</CardBody>
347-
<CardFooter></CardFooter>
379+
<CardFooter />
348380
</Card>
349381
</GridItem>
350382
</GridContainer>
351383
</div>
352384
);
353-
}
385+
};
386+
387+
export default Dashboard;

src/ui/views/PushDetails/components/Attestation.jsx renamed to src/ui/views/PushDetails/components/Attestation.tsx

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
import React, { useEffect } from 'react';
1+
import React, { useEffect, useState } from 'react';
22
import Dialog from '@material-ui/core/Dialog';
33
import DialogContent from '@material-ui/core/DialogContent';
44
import DialogActions from '@material-ui/core/DialogActions';
55
import { CheckCircle, ErrorOutline } from '@material-ui/icons';
66
import Button from '../../../components/CustomButtons/Button';
7-
import AttestationForm from './AttestationForm';
8-
7+
import AttestationForm, { FormQuestion } from './AttestationForm';
98
import { getAttestationConfig, getURLShortener, getEmailContact } from '../../../services/config';
109

11-
export default function Attestation(props) {
12-
const [open, setOpen] = React.useState(false);
13-
const [formData, setFormData] = React.useState([]);
14-
const [urlShortener, setURLShortener] = React.useState('');
15-
const [contactEmail, setContactEmail] = React.useState('');
10+
interface AttestationProps {
11+
approveFn: (data: { label: string; checked: boolean }[]) => void;
12+
}
13+
14+
const Attestation: React.FC<AttestationProps> = ({ approveFn }) => {
15+
const [open, setOpen] = useState(false);
16+
const [formData, setFormData] = useState<FormQuestion[]>([]);
17+
const [urlShortener, setURLShortener] = useState<string>('');
18+
const [contactEmail, setContactEmail] = useState<string>('');
1619

1720
useEffect(() => {
1821
if (!open) {
@@ -27,7 +30,7 @@ export default function Attestation(props) {
2730
getEmailContact(setContactEmail);
2831
}
2932
}
30-
}, [open]);
33+
}, [open, urlShortener, contactEmail]);
3134

3235
const handleClickOpen = () => {
3336
setOpen(true);
@@ -38,13 +41,11 @@ export default function Attestation(props) {
3841
};
3942

4043
const handleApprove = () => {
41-
const data = formData.map((question) => {
42-
return {
43-
label: question.label,
44-
checked: question.checked,
45-
};
46-
});
47-
props.approveFn(data);
44+
const data = formData.map((question) => ({
45+
label: question.label,
46+
checked: question.checked,
47+
}));
48+
approveFn(data);
4849
};
4950

5051
return (
@@ -95,12 +96,14 @@ export default function Attestation(props) {
9596
color='success'
9697
onClick={handleApprove}
9798
autoFocus
98-
disabled={!formData.every((question) => !!question.checked)}
99+
disabled={!formData.every((question) => question.checked)}
99100
>
100101
<CheckCircle /> Approve
101102
</Button>
102103
</DialogActions>
103104
</Dialog>
104105
</div>
105106
);
106-
}
107+
};
108+
109+
export default Attestation;

0 commit comments

Comments
 (0)