Skip to content

Commit cdeec69

Browse files
committed
refactor(tsx): convert RepoList view
1 parent 74eb072 commit cdeec69

File tree

5 files changed

+160
-95
lines changed

5 files changed

+160
-95
lines changed

src/ui/views/RepoList/Components/NewRepo.jsx renamed to src/ui/views/RepoList/Components/NewRepo.tsx

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React, { useState } from 'react';
2-
import PropTypes from 'prop-types';
32
import InputLabel from '@material-ui/core/InputLabel';
43
import Input from '@material-ui/core/Input';
54
import FormControl from '@material-ui/core/FormControl';
@@ -17,15 +16,35 @@ import { makeStyles } from '@material-ui/core/styles';
1716
import styles from '../../../assets/jss/material-dashboard-react/views/dashboardStyle';
1817
import { RepoIcon } from '@primer/octicons-react';
1918

20-
const useStyles = makeStyles(styles);
19+
interface AddRepositoryDialogProps {
20+
open: boolean;
21+
onClose: () => void;
22+
onSuccess: (data: RepositoryData) => void;
23+
}
24+
25+
export interface RepositoryData {
26+
_id?: string;
27+
project: string;
28+
name: string;
29+
url: string;
30+
maxUser: number;
31+
lastModified?: string;
32+
dateCreated?: string;
33+
proxyURL?: string;
34+
}
2135

22-
function AddRepositoryDialog(props) {
36+
interface NewRepoProps {
37+
onSuccess: (data: RepositoryData) => void;
38+
}
39+
40+
const useStyles = makeStyles(styles as any);
41+
42+
const AddRepositoryDialog: React.FC<AddRepositoryDialogProps> = ({ open, onClose, onSuccess }) => {
2343
const [project, setProject] = useState('');
2444
const [name, setName] = useState('');
2545
const [url, setUrl] = useState('');
2646
const [error, setError] = useState('');
2747
const [tip, setTip] = useState(false);
28-
const { onClose, open, onSuccess } = props;
2948
const classes = useStyles();
3049

3150
const handleClose = () => {
@@ -34,7 +53,7 @@ function AddRepositoryDialog(props) {
3453
onClose();
3554
};
3655

37-
const handleSuccess = (data) => {
56+
const handleSuccess = (data: RepositoryData) => {
3857
onSuccess(data);
3958
setTip(true);
4059
};
@@ -46,27 +65,27 @@ function AddRepositoryDialog(props) {
4665
};
4766

4867
const add = async () => {
49-
const data = {
50-
project: project,
51-
name: name,
52-
url: url,
68+
const data: RepositoryData = {
69+
project: project.trim(),
70+
name: name.trim(),
71+
url: url.trim(),
5372
maxUser: 1,
5473
};
5574

56-
if (data.project.trim().length == 0 || data.project.length > 100) {
57-
setError('project name length unexpected');
75+
if (data.project.length === 0 || data.project.length > 100) {
76+
setError('Project name length must be between 1 and 100 characters');
5877
return;
5978
}
6079

61-
if (data.name.trim().length == 0 || data.name.length > 100) {
62-
setError('Repo name length unexpected');
80+
if (data.name.length === 0 || data.name.length > 100) {
81+
setError('Repository name length must be between 1 and 100 characters');
6382
return;
6483
}
6584

6685
try {
6786
new URL(data.url);
6887
} catch {
69-
setError('Invalid URL');
88+
setError('Invalid URL format');
7089
return;
7190
}
7291

@@ -75,15 +94,15 @@ function AddRepositoryDialog(props) {
7594
handleSuccess(data);
7695
handleClose();
7796
} catch (e) {
78-
if (e.message) {
97+
if (e instanceof Error) {
7998
setError(e.message);
8099
} else {
81-
setError(e.toString());
100+
setError('An unexpected error occurred');
82101
}
83102
}
84103
};
85104

86-
const inputStyle = {
105+
const inputStyle: React.CSSProperties = {
87106
width: '100%',
88107
};
89108

@@ -106,9 +125,11 @@ function AddRepositoryDialog(props) {
106125
fullWidth
107126
maxWidth='md'
108127
>
109-
<DialogTitle style={{ color: 'red' }} id='simple-dialog-title'>
110-
{error}
111-
</DialogTitle>
128+
{error && (
129+
<DialogTitle style={{ color: 'red' }} id='simple-dialog-title'>
130+
{error}
131+
</DialogTitle>
132+
)}
112133
<DialogTitle style={{ textAlign: 'left' }} className={classes.cardTitle}>
113134
Add a repository...
114135
</DialogTitle>
@@ -123,6 +144,7 @@ function AddRepositoryDialog(props) {
123144
inputProps={{ maxLength: 200, minLength: 3 }}
124145
aria-describedby='project-helper-text'
125146
onChange={(e) => setProject(e.target.value)}
147+
value={project}
126148
/>
127149
<FormHelperText id='project-helper-text'>GitHub Organization</FormHelperText>
128150
</FormControl>
@@ -135,6 +157,7 @@ function AddRepositoryDialog(props) {
135157
id='name'
136158
aria-describedby='name-helper-text'
137159
onChange={(e) => setName(e.target.value)}
160+
value={name}
138161
/>
139162
<FormHelperText id='name-helper-text'>GitHub Repository Name</FormHelperText>
140163
</FormControl>
@@ -148,6 +171,7 @@ function AddRepositoryDialog(props) {
148171
id='url'
149172
aria-describedby='url-helper-text'
150173
onChange={(e) => setUrl(e.target.value)}
174+
value={url}
151175
/>
152176
<FormHelperText id='url-helper-text'>GitHub Repository URL</FormHelperText>
153177
</FormControl>
@@ -168,20 +192,11 @@ function AddRepositoryDialog(props) {
168192
</Dialog>
169193
</>
170194
);
171-
}
172-
173-
AddRepositoryDialog.propTypes = {
174-
onClose: PropTypes.func.isRequired,
175-
open: PropTypes.bool.isRequired,
176-
onSuccess: PropTypes.func.isRequired,
177195
};
178196

179-
NewRepo.propTypes = {
180-
onSuccess: PropTypes.func.isRequired,
181-
};
197+
const NewRepo: React.FC<NewRepoProps> = ({ onSuccess }) => {
198+
const [open, setOpen] = useState(false);
182199

183-
export default function NewRepo(props) {
184-
const [open, setOpen] = React.useState(false);
185200
const handleClickOpen = () => {
186201
setOpen(true);
187202
};
@@ -193,9 +208,11 @@ export default function NewRepo(props) {
193208
return (
194209
<div>
195210
<Button color='success' onClick={handleClickOpen}>
196-
<RepoIcon></RepoIcon>Add repository
211+
<RepoIcon /> Add repository
197212
</Button>
198-
<AddRepositoryDialog open={open} onClose={handleClose} onSuccess={props.onSuccess} />
213+
<AddRepositoryDialog open={open} onClose={handleClose} onSuccess={onSuccess} />
199214
</div>
200215
);
201-
}
216+
};
217+
218+
export default NewRepo;

src/ui/views/RepoList/Components/RepoOverview.jsx renamed to src/ui/views/RepoList/Components/RepoOverview.tsx

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,40 @@
1-
import React, { useEffect } from 'react';
1+
import React, { useEffect, useState } from 'react';
22
import { Snackbar, TableCell, TableRow } from '@material-ui/core';
33
import GridContainer from '../../../components/Grid/GridContainer';
44
import GridItem from '../../../components/Grid/GridItem';
55
import { CodeReviewIcon, LawIcon, PeopleIcon } from '@primer/octicons-react';
6+
import axios from 'axios';
7+
import moment from 'moment';
8+
import CodeActionButton from '../../../components/CustomButtons/CodeActionButton';
69

7-
const colors = {
10+
interface RepositoriesProps {
11+
data: {
12+
project: string;
13+
name: string;
14+
proxyURL: string;
15+
users?: {
16+
canPush?: string[];
17+
canAuthorise?: string[];
18+
};
19+
};
20+
}
21+
22+
interface GitHubRepository {
23+
description?: string;
24+
language?: string;
25+
license?: {
26+
spdx_id: string;
27+
};
28+
parent?: {
29+
full_name: string;
30+
html_url: string;
31+
};
32+
created_at?: string;
33+
updated_at?: string;
34+
pushed_at?: string;
35+
}
36+
37+
const colors: Record<string, string> = {
838
'1C Enterprise': '#814CCC',
939
'2-Dimensional Array': '#38761D',
1040
'4D': '#004289',
@@ -564,12 +594,8 @@ const colors = {
564594
Zimpl: '#d67711',
565595
};
566596

567-
import axios from 'axios';
568-
import moment from 'moment';
569-
import CodeActionButton from '../../../components/CustomButtons/CodeActionButton';
570-
571-
export default function Repositories(props) {
572-
const [github, setGitHub] = React.useState({});
597+
const Repositories: React.FC<RepositoriesProps> = (props) => {
598+
const [github, setGitHub] = useState<GitHubRepository>({});
573599

574600
const [errorMessage, setErrorMessage] = React.useState('');
575601
const [snackbarOpen, setSnackbarOpen] = React.useState(false);
@@ -585,7 +611,9 @@ export default function Repositories(props) {
585611
setGitHub(res.data);
586612
})
587613
.catch((error) => {
588-
setErrorMessage(`Error fetching GitHub repository ${props.data.project}/${props.data.name}: ${error}`);
614+
setErrorMessage(
615+
`Error fetching GitHub repository ${props.data.project}/${props.data.name}: ${error}`,
616+
);
589617
setSnackbarOpen(true);
590618
});
591619
};
@@ -630,7 +658,7 @@ export default function Repositories(props) {
630658
style={{
631659
height: '12px',
632660
width: '12px',
633-
backgroundColor: `${colors[github.language]}`,
661+
backgroundColor: `${colors[github.language] || '#ccc'}`,
634662
borderRadius: '50px',
635663
display: 'inline-block',
636664
marginRight: '5px',
@@ -660,9 +688,9 @@ export default function Repositories(props) {
660688
Last updated{' '}
661689
{moment
662690
.max([
663-
moment(github.created_at),
664-
moment(github.updated_at),
665-
moment(github.pushed_at),
691+
moment(github.created_at || 0),
692+
moment(github.updated_at || 0),
693+
moment(github.pushed_at || 0),
666694
])
667695
.fromNow()}
668696
</GridItem>
@@ -684,4 +712,6 @@ export default function Repositories(props) {
684712
/>
685713
</TableRow>
686714
);
687-
}
715+
};
716+
717+
export default Repositories;

0 commit comments

Comments
 (0)