Skip to content

Commit 7cf65c4

Browse files
authored
Add code comments (#437)
* Add code comments * Set rows per page to 25 * Update handle row change comment * Revert radix value
1 parent 9fe72c2 commit 7cf65c4

File tree

7 files changed

+111
-44
lines changed

7 files changed

+111
-44
lines changed

src/App.tsx

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,43 @@ import ValueEditor from './ValueEditor';
1212
import GlobalStyles from './GlobalStyles';
1313
import { clearFailedAuthRequestsQueue, retryFailedAuthRequests } from './api';
1414

15-
// Initialize Google Analytics
15+
// Initialize Google Analytics with the given tracking ID
1616
ReactGA.initialize('G-7XJBCP6P75');
17+
// Track the initial page load event
1718
ReactGA.send({ hitType: 'pageview', page: window.location.pathname });
1819

1920
const App: FC = () => {
20-
// Need to call forceUpdate if SciGateway tells us to rerender but there's no
21-
// forceUpdate in functional components, so this is the hooks equivalent. See
22-
// https://reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate
21+
// Force update mechanism using React's useReducer hook
22+
// This is used to trigger a re-render when necessary (e.g. when SciGateway requests it)
23+
// There is no direct forceUpdate in functional components, so we increment a state variable instead
2324
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2425
const [_, forceUpdate] = React.useReducer((x) => x + 1, 0);
2526

2627
function handler(e: Event): void {
27-
// Attempt to re-render the plugin if we get told to
28+
// Handle custom SciGateway events for triggering actions in the app
2829
const action = (e as CustomEvent).detail;
30+
31+
// If SciGateway requests a plugin re-render, trigger a re-render
2932
if ('scigateway:api:plugin_rerender'.match(action)) {
3033
forceUpdate();
3134
}
35+
36+
// If SciGateway invalidates the token, retry failed authentication requests
3237
if ('scigateway:api:invalidate_token'.match(action)) {
3338
retryFailedAuthRequests();
3439
}
40+
41+
// If SciGateway requests signout, clear the authentication request queue
3542
if ('scigateway:api:signout'.match(action)) {
3643
clearFailedAuthRequestsQueue();
3744
}
3845
}
3946

47+
// Attach event listener for SciGateway events when the component mounts
4048
React.useEffect(() => {
4149
document.addEventListener('scigateway', handler);
50+
51+
// Remove event listener when the component unmounts
4252
return () => {
4353
document.removeEventListener('scigateway', handler);
4454
};
@@ -48,20 +58,21 @@ const App: FC = () => {
4858
<GlobalStyles>
4959
<Router basename="/fia">
5060
<Switch>
61+
{/* Define application routes */}
5162
<Route exact path="/">
52-
<HomePage />
63+
<HomePage /> {/* Renders the HomePage component on the root path */}
5364
</Route>
5465
<Route path="/instruments">
55-
<Instruments />
66+
<Instruments /> {/* Renders the Instruments page */}
5667
</Route>
5768
<Route path="/reduction-history/ALL">
58-
<JobsAll />
69+
<JobsAll /> {/* Displays all reduction jobs */}
5970
</Route>
6071
<Route path="/reduction-history/:instrumentName">
61-
<JobsGeneral />
72+
<JobsGeneral /> {/* Displays reduction jobs filtered by instrument name */}
6273
</Route>
6374
<Route path="/value-editor/:jobId">
64-
<ValueEditor />
75+
<ValueEditor /> {/* Opens the ValueEditor for a specific job */}
6576
</Route>
6677
</Switch>
6778
</Router>

src/ConfigSettings/ConfigSettingsLOQ.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,32 @@ import React from 'react';
55
import { Box, Button } from '@mui/material';
66
import { UploadFile, Edit } from '@mui/icons-material';
77

8-
// Local data
8+
// Local components
99
import ConfigSettingsGeneral from './ConfigSettingsGeneral';
1010
import FileUploader from './FileUploader';
1111

12+
// API base URL for LOQ-specific requests
1213
const fiaApiUrl = process.env.REACT_APP_FIA_REST_API_URL;
1314
const instrument_url = `${fiaApiUrl}/extras/loq`;
15+
1416
const ConfigSettingsLOQ: React.FC = () => {
15-
// Insert LOQ specifc buttons into the ConfigSettingsGeneral component
17+
// File uploader logic for LOQ
1618
const { selectedFile, uploadMessage, handleFileSelection, handleFileUpload } = FileUploader(instrument_url);
19+
1720
return (
21+
// Render ConfigSettingsGeneral with additional LOQ-specific elements
1822
<ConfigSettingsGeneral onFileUpload={handleFileUpload}>
23+
{/* File upload button */}
1924
<Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 2 }}>
2025
<Button component="label" variant="contained" startIcon={<UploadFile />}>
2126
Upload file...
2227
<input type="file" multiple hidden onChange={handleFileSelection} />
2328
</Button>
29+
{/* Display upload message if a file is selected */}
2430
{selectedFile && <Box sx={{ mt: 1, ml: 2 }}>{uploadMessage}</Box>}
2531
</Box>
2632

27-
{/* Change script button -- disabled for now */}
33+
{/* Change script button (currently disabled) */}
2834
<Box>
2935
<Button variant="contained" disabled startIcon={<Edit />}>
3036
Change script...

src/ConfigSettings/FileUploader.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
import axios from 'axios';
1+
// React components
22
import { useState } from 'react';
33

4+
// Axios components
5+
import axios from 'axios';
6+
47
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
58
const FileUploader = (instrument_url: string) => {
69
const [selectedFile, setSelectedFile] = useState<File | null>(null);

src/GlobalStyles.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,19 @@ import React from 'react';
44
// Material UI components
55
import { ThemeProvider, StyledEngineProvider, Theme, createTheme } from '@mui/material/styles';
66

7+
// Initialize a default theme
78
let theme: Theme = createTheme();
89

10+
// Listen for theme changes from SciGateway and update the theme dynamically
911
document.addEventListener('scigateway', (e) => {
1012
const action = (e as CustomEvent).detail;
13+
// If the event contains theme options, update the theme
1114
if (action.type === 'scigateway:api:send_themeoptions' && action.payload && action.payload.theme) {
1215
theme = action.payload.theme;
1316
}
1417
});
1518

19+
// GlobalStyles component wraps the app in a theme provider
1620
class GlobalStyles extends React.Component<{ children: React.ReactNode }> {
1721
public constructor(props: { children: React.ReactNode }) {
1822
super(props);
@@ -21,6 +25,7 @@ class GlobalStyles extends React.Component<{ children: React.ReactNode }> {
2125
public render(): React.ReactElement {
2226
return (
2327
<StyledEngineProvider injectFirst>
28+
{/* Apply the theme to all children components */}
2429
<ThemeProvider theme={theme}>{this.props.children}</ThemeProvider>
2530
</StyledEngineProvider>
2631
);

src/Instruments.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@ import { instruments } from './InstrumentData';
1313

1414
const Instruments: React.FC = () => {
1515
const theme = useTheme();
16+
// State for tracking expanded instruments
1617
const [expandedIds, setExpandedIds] = React.useState<number[]>([]);
18+
// State for tracking favorite instruments
1719
const [favoriteIds, setFavoriteIds] = React.useState<number[]>([]);
1820

21+
// Toggle expansion state of an instrument
1922
const handleToggleExpand = (id: number, event?: React.MouseEvent): void => {
2023
if (event) {
2124
event.stopPropagation();
@@ -27,6 +30,7 @@ const Instruments: React.FC = () => {
2730
);
2831
};
2932

33+
// Toggle favorite state of an instrument
3034
const handleToggleFavorite = (id: number, event: React.MouseEvent): void => {
3135
event.stopPropagation();
3236
setFavoriteIds((prevFavoriteIds) =>
@@ -36,6 +40,7 @@ const Instruments: React.FC = () => {
3640
);
3741
};
3842

43+
// Sort instruments based on favorite status
3944
const sortedInstruments = [...instruments].sort((a, b) => {
4045
if (favoriteIds.includes(a.id) && !favoriteIds.includes(b.id)) {
4146
return -1;
@@ -48,6 +53,7 @@ const Instruments: React.FC = () => {
4853

4954
return (
5055
<>
56+
{/* Page title */}
5157
<Typography variant="h3" component="h1" style={{ color: theme.palette.text.primary, padding: '20px' }}>
5258
ISIS instruments
5359
</Typography>
@@ -70,6 +76,7 @@ const Instruments: React.FC = () => {
7076
>
7177
<Box display="flex" alignItems="center" justifyContent="space-between">
7278
<Box display="flex" alignItems="center">
79+
{/* Expand button */}
7380
<IconButton
7481
aria-expanded={expandedIds.includes(instrument.id)}
7582
aria-label="show more"
@@ -80,6 +87,7 @@ const Instruments: React.FC = () => {
8087
/>
8188
</IconButton>
8289
<Box sx={{ marginLeft: 2 }}>
90+
{/* Instrument name and type */}
8391
<Typography
8492
variant="h6"
8593
component="h1"
@@ -97,6 +105,7 @@ const Instruments: React.FC = () => {
97105
</Typography>
98106
</Box>
99107
</Box>
108+
{/* Favorite button */}
100109
<IconButton
101110
aria-label="add to favorites"
102111
onClick={(event) => handleToggleFavorite(instrument.id, event)}
@@ -111,6 +120,7 @@ const Instruments: React.FC = () => {
111120
<Collapse in={expandedIds.includes(instrument.id)} timeout="auto" unmountOnExit>
112121
<Box marginTop={2}>
113122
<Box display="flex" justifyContent="space-between" alignItems="flex-start">
123+
{/* Instrument description */}
114124
<Typography
115125
variant="body2"
116126
paragraph
@@ -119,6 +129,7 @@ const Instruments: React.FC = () => {
119129
{instrument.description}
120130
</Typography>
121131
<Box sx={{ flex: 1, marginLeft: 4 }}>
132+
{/* List of associated scientists */}
122133
<Typography variant="body2" sx={{ fontWeight: 'bold', color: theme.palette.text.primary }}>
123134
Scientists:
124135
</Typography>
@@ -131,10 +142,12 @@ const Instruments: React.FC = () => {
131142
</List>
132143
</Box>
133144
</Box>
145+
{/* Link to more information */}
134146
<Link href={instrument.infoPage} target="_blank" rel="noopener" underline="always">
135147
{instrument.infoPage}
136148
</Link>
137149
<Box marginTop={2}>
150+
{/* Button to view reduction history */}
138151
<Button
139152
variant="contained"
140153
component={RouterLink}

src/Jobs/JobsAll.tsx

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,35 @@ import { useHistory, useParams, Link } from 'react-router-dom';
66
import { useTheme } from '@mui/material/styles';
77
import { TableCell } from '@mui/material';
88

9-
// Local data
9+
// Local data and utilities
1010
import JobsBase, { useFetchJobs, useFetchTotalCount, Job, headerStyles } from './JobsBase';
1111

1212
const JobsAll: React.FC = () => {
13+
// Extract instrument name from URL parameters
1314
const { instrumentName } = useParams<{ instrumentName: string }>();
15+
16+
// Retrieve the current theme for styling
1417
const theme = useTheme();
18+
19+
// Hook for handling navigation within the app
1520
const history = useHistory();
16-
const [jobs, setJobs] = useState<Job[]>([]);
17-
const [totalRows, setTotalRows] = useState(0);
18-
const [currentPage, setCurrentPage] = useState(0);
19-
const [rowsPerPage, setRowsPerPage] = useState(25);
20-
const [orderDirection, setOrderDirection] = useState<'asc' | 'desc'>('desc');
21-
const [selectedInstrument, setSelectedInstrument] = useState(instrumentName || 'ALL');
22-
const [orderBy, setOrderBy] = useState<string>('run_start');
21+
22+
// State variables for job data and table pagination
23+
const [jobs, setJobs] = useState<Job[]>([]); // Stores fetched job data
24+
const [totalRows, setTotalRows] = useState(0); // Stores total number of job entries
25+
const [currentPage, setCurrentPage] = useState(0); // Current page in pagination
26+
const [rowsPerPage, setRowsPerPage] = useState(25); // Number of rows displayed per page
27+
const [orderDirection, setOrderDirection] = useState<'asc' | 'desc'>('desc'); // Sorting order (ascending/descending)
28+
const [selectedInstrument, setSelectedInstrument] = useState(instrumentName || 'ALL'); // Selected instrument filter
29+
const [orderBy, setOrderBy] = useState<string>('run_start'); // Column to sort by
30+
31+
// Calculate the offset for API query based on current page
2332
const offset = currentPage * rowsPerPage;
33+
34+
// Construct API query string with pagination and sorting parameters
2435
const query = `limit=${rowsPerPage}&offset=${offset}&order_by=${orderBy}&order_direction=${orderDirection}&include_run=true`;
36+
37+
// Fetch job data and total count using custom hooks
2538
const fetchJobs = useFetchJobs(`/jobs`, query, setJobs);
2639
const fetchTotalCount = useFetchTotalCount(`/jobs/count`, setTotalRows);
2740

@@ -32,25 +45,27 @@ const JobsAll: React.FC = () => {
3245
const newInstrument = event.target.value;
3346
setSelectedInstrument(newInstrument);
3447
setCurrentPage(0);
35-
history.push(`/reduction-history/${newInstrument}`);
48+
history.push(`/reduction-history/${newInstrument}`); // Navigate to selected instrument's history
3649
}}
3750
jobs={jobs}
3851
totalRows={totalRows}
3952
currentPage={currentPage}
4053
rowsPerPage={rowsPerPage}
41-
handleChangePage={(_, newPage) => setCurrentPage(newPage)}
42-
handleChangeRowsPerPage={(e) => setRowsPerPage(parseInt(e.target.value, 10))}
54+
handleChangePage={(_, newPage) => setCurrentPage(newPage)} // Update page number
55+
handleChangeRowsPerPage={(e) => setRowsPerPage(parseInt(e.target.value, 10))} // Update rows per page based on what the user has selected (10 is the radix, do not confuse for number of rows)
4356
handleSort={(property) => {
4457
const isAsc = orderBy === property && orderDirection === 'asc';
45-
setOrderDirection(isAsc ? 'desc' : 'asc');
58+
setOrderDirection(isAsc ? 'desc' : 'asc'); // Toggle sorting order
4659
setOrderBy(property);
47-
setCurrentPage(0);
60+
setCurrentPage(0); // Reset to first page after sorting
4861
}}
4962
orderBy={orderBy}
5063
orderDirection={orderDirection}
5164
fetchJobs={fetchJobs}
5265
fetchTotalCount={fetchTotalCount}
66+
// Custom table header for instrument column
5367
customHeaders={<TableCell sx={{ width: '10%', ...headerStyles(theme) }}>Instrument</TableCell>}
68+
// Custom rendering of job row cells for instrument name with a clickable link
5469
customRowCells={(job: Job) => (
5570
<TableCell sx={{ width: '10%' }}>
5671
{job.run?.instrument_name ? (
@@ -60,17 +75,17 @@ const JobsAll: React.FC = () => {
6075
color: theme.palette.mode === 'dark' ? '#86b4ff' : theme.palette.primary.main,
6176
textDecoration: 'none',
6277
}}
63-
onMouseEnter={(e) => (e.currentTarget.style.textDecoration = 'underline')}
64-
onMouseLeave={(e) => (e.currentTarget.style.textDecoration = 'none')}
78+
onMouseEnter={(e) => (e.currentTarget.style.textDecoration = 'underline')} // Underline on hover
79+
onMouseLeave={(e) => (e.currentTarget.style.textDecoration = 'none')} // Remove underline on hover out
6580
>
6681
{job.run.instrument_name}
6782
</Link>
6883
) : (
69-
'Unknown'
84+
'Unknown' // Display 'Unknown' if no instrument name exists
7085
)}
7186
</TableCell>
7287
)}
73-
maxHeight={650}
88+
maxHeight={650} // Limit table height
7489
/>
7590
);
7691
};

0 commit comments

Comments
 (0)