Skip to content

Commit 98716aa

Browse files
committed
fix: load correct selected directory (source/release)
1 parent 3dfd649 commit 98716aa

File tree

1 file changed

+170
-42
lines changed

1 file changed

+170
-42
lines changed

src/components/coursemanage/files/files.tsx

Lines changed: 170 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,28 @@ import * as React from 'react';
88
import { useEffect } from 'react';
99
import { Assignment } from '../../../model/assignment';
1010
import { Lecture } from '../../../model/lecture';
11-
import { generateAssignment, getAssignment, pullAssignment, pushAssignment } from '../../../services/assignments.service';
11+
import {
12+
generateAssignment,
13+
getAssignment,
14+
pullAssignment,
15+
pushAssignment
16+
} from '../../../services/assignments.service';
1217
import GetAppRoundedIcon from '@mui/icons-material/GetAppRounded';
1318
import OpenInBrowserIcon from '@mui/icons-material/OpenInBrowser';
1419
import { CommitDialog } from '../../util/dialog';
15-
import { Box, Button, Card, CardActions, CardContent, CardHeader, Chip, IconButton, Tab, Tabs, Tooltip } from '@mui/material';
20+
import {
21+
Box,
22+
Button,
23+
Card,
24+
CardActions,
25+
CardContent,
26+
CardHeader,
27+
Chip,
28+
IconButton,
29+
Tab,
30+
Tabs,
31+
Tooltip
32+
} from '@mui/material';
1633
import ReplayIcon from '@mui/icons-material/Replay';
1734
import TerminalIcon from '@mui/icons-material/Terminal';
1835
import AddIcon from '@mui/icons-material/Add';
@@ -24,7 +41,10 @@ import { Contents } from '@jupyterlab/services';
2441
import { openBrowser, openTerminal } from '../overview/util';
2542
import { PageConfig } from '@jupyterlab/coreutils';
2643
import PublishRoundedIcon from '@mui/icons-material/PublishRounded';
27-
import { getRemoteStatus, lectureBasePath } from '../../../services/file.service';
44+
import {
45+
getRemoteStatus,
46+
lectureBasePath
47+
} from '../../../services/file.service';
2848
import { RepoType } from '../../util/repo-type';
2949
import { enqueueSnackbar } from 'notistack';
3050
import { useNavigate } from 'react-router-dom';
@@ -34,59 +54,80 @@ import { loadString, storeString } from '../../../services/storage.service';
3454
import { queryClient } from '../../../widgets/assignmentmanage';
3555
import { RemoteFileStatus } from '../../../model/remoteFileStatus';
3656
import { GitLogModal } from './git-log';
57+
import moment from 'moment';
3758

3859
export interface IFilesProps {
3960
lecture: Lecture;
4061
assignment: Assignment;
4162
onAssignmentChange: (assignment: Assignment) => void;
4263
}
4364

44-
export const Files = ({ lecture, assignment, onAssignmentChange }: IFilesProps) => {
65+
export const Files = ({
66+
lecture,
67+
assignment,
68+
onAssignmentChange
69+
}: IFilesProps) => {
4570
const navigate = useNavigate();
4671
const reloadPage = () => navigate(0);
4772
const serverRoot = PageConfig.getOption('serverRoot');
48-
73+
4974
const { data: updatedLecture = lecture } = useQuery({
5075
queryKey: ['lecture', lecture.id],
51-
queryFn: () => getLecture(lecture.id, true),
76+
queryFn: () => getLecture(lecture.id, true)
5277
});
5378

5479
const { data: updatedAssignment = assignment } = useQuery({
5580
queryKey: ['assignment', lecture.id, assignment.id],
56-
queryFn: () => getAssignment(lecture.id, assignment.id, true),
81+
queryFn: () => getAssignment(lecture.id, assignment.id, true)
5782
});
5883

59-
const { data: selectedDir = 'source', refetch: refetchSelectedDir } = useQuery({
60-
queryKey: ['selectedDir'],
61-
queryFn: async () => {
62-
const data = await loadString('files-selected-dir');
63-
return data || 'source';
64-
},
65-
});
84+
const { data: selectedDir = 'source', refetch: refetchSelectedDir } =
85+
useQuery({
86+
queryKey: ['selectedDir'],
87+
queryFn: async () => {
88+
const data = loadString('files-selected-dir');
89+
if (data) {
90+
return data as 'source' | 'release';
91+
} else {
92+
return 'source';
93+
}
94+
}
95+
});
6696

6797
const { data: repoStatus, refetch: refetchRepoStatus } = useQuery({
6898
queryKey: ['repoStatus', lecture.id, assignment.id],
6999
queryFn: async () => {
70-
const response = await getRemoteStatus(lecture, assignment, RepoType.SOURCE, true);
100+
const response = await getRemoteStatus(
101+
lecture,
102+
assignment,
103+
RepoType.SOURCE,
104+
true
105+
);
71106
return response.status;
72-
},
107+
}
73108
});
74109

75-
76-
useEffect(() => {
110+
openBrowser(
111+
`${lectureBasePath}${lecture.code}/${selectedDir}/${assignment.id}`
112+
);
113+
114+
React.useEffect(() => {
77115
const srcPath = `${lectureBasePath}${lecture.code}/source/${assignment.id}`;
78116
GlobalObjects.docManager.services.contents.fileChanged.connect(
79117
(sender: Contents.IManager, change: Contents.IChangedArgs) => {
80118
const { oldValue, newValue } = change;
81-
if ((newValue && !newValue.path.includes(srcPath)) || (oldValue && !oldValue.path.includes(srcPath))) {
119+
if (
120+
(newValue && !newValue.path.includes(srcPath)) ||
121+
(oldValue && !oldValue.path.includes(srcPath))
122+
) {
82123
return;
83124
}
84125
reloadPage();
85126
refetchRepoStatus();
86127
},
87128
this
88129
);
89-
}, [assignment.id, lecture.id]);
130+
}, [assignment, lecture]);
90131

91132
/**
92133
* Switches between source and release directory.
@@ -111,20 +152,39 @@ export const Files = ({ lecture, assignment, onAssignmentChange }: IFilesProps)
111152
);
112153
});
113154
} else {
114-
setSelectedDir(dir);
155+
await setSelectedDir(dir);
115156
}
116157
};
117158

118159
const setSelectedDir = async (dir: 'source' | 'release') => {
119160
storeString('files-selected-dir', dir);
120-
refetchSelectedDir();
161+
refetchSelectedDir().then(() => {
162+
openBrowser(
163+
`${lectureBasePath}${lecture.code}/${selectedDir}/${assignment.id}`
164+
);
165+
});
121166
};
122167

123-
const handlePushAssignment = async (commitMessage: string, selectedFiles: string[]) => {
168+
const handlePushAssignment = async (
169+
commitMessage: string,
170+
selectedFiles: string[]
171+
) => {
124172
try {
125173
// Note: has to be in this order (release -> source)
126-
await pushAssignment(lecture.id, assignment.id, 'release', commitMessage, selectedFiles);
127-
await pushAssignment(lecture.id, assignment.id, 'source', commitMessage, selectedFiles);
174+
await pushAssignment(
175+
lecture.id,
176+
assignment.id,
177+
'release',
178+
commitMessage,
179+
selectedFiles
180+
);
181+
await pushAssignment(
182+
lecture.id,
183+
assignment.id,
184+
'source',
185+
commitMessage,
186+
selectedFiles
187+
);
128188
await queryClient.invalidateQueries({ queryKey: ['assignments'] });
129189
enqueueSnackbar('Successfully Pushed Assignment', { variant: 'success' });
130190
refetchRepoStatus();
@@ -137,7 +197,7 @@ export const Files = ({ lecture, assignment, onAssignmentChange }: IFilesProps)
137197
try {
138198
await pullAssignment(lecture.id, assignment.id, 'source');
139199
enqueueSnackbar('Successfully Pulled Assignment', { variant: 'success' });
140-
refetchRepoStatus();
200+
await refetchRepoStatus();
141201
} catch (err) {
142202
enqueueSnackbar(`Error Pulling Assignment: ${err}`, { variant: 'error' });
143203
}
@@ -154,7 +214,7 @@ export const Files = ({ lecture, assignment, onAssignmentChange }: IFilesProps)
154214
case RemoteFileStatus.StatusEnum.Divergent:
155215
return 'The local and remote files are divergent.';
156216
case RemoteFileStatus.StatusEnum.NoRemoteRepo:
157-
return 'There is no remote repository yet. Push your assignment to create it.'
217+
return 'There is no remote repository yet. Push your assignment to create it.';
158218
default:
159219
return '';
160220
}
@@ -170,23 +230,73 @@ export const Files = ({ lecture, assignment, onAssignmentChange }: IFilesProps)
170230

171231
const getStatusChip = (status: RemoteFileStatus.StatusEnum) => {
172232
// Define the statusMap with allowed `Chip` color values
173-
const statusMap: Record<RemoteFileStatus.StatusEnum, { label: string, color: "default" | "primary" | "secondary" | "error" | "warning" | "info" | "success", icon: JSX.Element }> = {
174-
UP_TO_DATE: { label: 'Up To Date', color: 'success', icon: <CheckIcon /> },
175-
PULL_NEEDED: { label: 'Pull Needed', color: 'warning', icon: <GetAppRoundedIcon /> },
176-
PUSH_NEEDED: { label: 'Push Needed', color: 'warning', icon: <PublishRoundedIcon /> },
177-
DIVERGENT: { label: 'Divergent', color: 'error', icon: <ErrorOutlineIcon /> },
178-
NO_REMOTE_REPO: { label: 'No Remote Repository', color: 'primary', icon: <CheckIcon /> }
233+
const statusMap: Record<
234+
RemoteFileStatus.StatusEnum,
235+
{
236+
label: string;
237+
color:
238+
| 'default'
239+
| 'primary'
240+
| 'secondary'
241+
| 'error'
242+
| 'warning'
243+
| 'info'
244+
| 'success';
245+
icon: JSX.Element;
246+
}
247+
> = {
248+
UP_TO_DATE: {
249+
label: 'Up To Date',
250+
color: 'success',
251+
icon: <CheckIcon />
252+
},
253+
PULL_NEEDED: {
254+
label: 'Pull Needed',
255+
color: 'warning',
256+
icon: <GetAppRoundedIcon />
257+
},
258+
PUSH_NEEDED: {
259+
label: 'Push Needed',
260+
color: 'warning',
261+
icon: <PublishRoundedIcon />
262+
},
263+
DIVERGENT: {
264+
label: 'Divergent',
265+
color: 'error',
266+
icon: <ErrorOutlineIcon />
267+
},
268+
NO_REMOTE_REPO: {
269+
label: 'No Remote Repository',
270+
color: 'primary',
271+
icon: <CheckIcon />
272+
}
179273
};
180-
274+
181275
// Fallback if the status is not in the statusMap (it should be)
182276
const { label, color, icon } = statusMap[status] || {};
183-
277+
184278
// Return the Chip component with appropriate props or null if status is invalid
185-
return label ? <Chip sx={{ mb: 1 }} label={label} color={color} size="small" icon={icon} /> : null;
279+
return label ? (
280+
<Chip
281+
sx={{ mb: 1 }}
282+
label={label}
283+
color={color}
284+
size="small"
285+
icon={icon}
286+
/>
287+
) : null;
186288
};
187-
289+
188290
return (
189-
<Card sx={{ overflowX: 'auto', m: 3, flex: 1, display: 'flex', flexDirection: 'column' }}>
291+
<Card
292+
sx={{
293+
overflowX: 'auto',
294+
m: 3,
295+
flex: 1,
296+
display: 'flex',
297+
flexDirection: 'column'
298+
}}
299+
>
190300
<CardHeader
191301
title="Files"
192302
titleTypographyProps={{ display: 'inline' }}
@@ -207,7 +317,11 @@ export const Files = ({ lecture, assignment, onAssignmentChange }: IFilesProps)
207317
subheaderTypographyProps={{ display: 'inline', ml: 2 }}
208318
/>
209319
<CardContent sx={{ overflow: 'auto' }}>
210-
<Tabs variant="fullWidth" value={selectedDir} onChange={(e, dir) => handleSwitchDir(dir)}>
320+
<Tabs
321+
variant="fullWidth"
322+
value={selectedDir}
323+
onChange={(e, dir) => handleSwitchDir(dir)}
324+
>
211325
<Tab label="Source" value="source" />
212326
<Tab label="Release" value="release" />
213327
</Tabs>
@@ -221,16 +335,30 @@ export const Files = ({ lecture, assignment, onAssignmentChange }: IFilesProps)
221335
</Box>
222336
</CardContent>
223337
<CardActions sx={{ marginTop: 'auto' }}>
224-
<CommitDialog handleCommit={handlePushAssignment} lecture={lecture} assignment={assignment}>
338+
<CommitDialog
339+
handleCommit={handlePushAssignment}
340+
lecture={lecture}
341+
assignment={assignment}
342+
>
225343
<Tooltip title="Commit Changes">
226-
<Button variant="outlined" size="small" color="primary">
344+
<Button
345+
variant="outlined"
346+
size="small"
347+
color="primary"
348+
sx={{ mt: -1 }}
349+
>
227350
<PublishRoundedIcon fontSize="small" sx={{ mr: 1 }} />
228351
Push
229352
</Button>
230353
</Tooltip>
231354
</CommitDialog>
232355
<Tooltip title="Pull from Remote">
233-
<Button variant="outlined" size="small" onClick={handlePullAssignment}>
356+
<Button
357+
variant="outlined"
358+
size="small"
359+
onClick={handlePullAssignment}
360+
sx={{ mt: -1 }}
361+
>
234362
<GetAppRoundedIcon fontSize="small" sx={{ mr: 1 }} />
235363
Pull
236364
</Button>

0 commit comments

Comments
 (0)