Skip to content

Commit 2672b57

Browse files
tcnichollongshuicy
andauthored
701 improve file version selection (#743)
* placeholder for where new version select will go * not clickable, new imports * select no longer in version chip new dropdown on filepage problem - current version not selected on file load * does not look good select and file details end up at bottom * clean up the logic * fix bug * make it look nicer * add snackbar * change to half width * change history to details * remove width --------- Co-authored-by: Chen Wang <[email protected]>
1 parent db316ed commit 2672b57

File tree

9 files changed

+199
-204
lines changed

9 files changed

+199
-204
lines changed

frontend/src/components/files/File.tsx

Lines changed: 83 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
import React, { useEffect, useState } from "react";
22
import config from "../../app.config";
3-
import { Box, Button, Grid, Tab, Tabs } from "@mui/material";
3+
import {
4+
Box,
5+
Button,
6+
FormControl,
7+
Grid,
8+
MenuItem,
9+
Snackbar,
10+
Tab,
11+
Tabs,
12+
} from "@mui/material";
413
import { downloadResource } from "../../utils/common";
514
import { PreviewConfiguration, RootState } from "../../types/data";
615
import { useParams, useSearchParams } from "react-router-dom";
@@ -39,6 +48,8 @@ import { ErrorModal } from "../errors/ErrorModal";
3948
import { FileHistory } from "./FileHistory";
4049
import { VersionChip } from "../versions/VersionChip";
4150
import RoleChip from "../auth/RoleChip";
51+
import Typography from "@mui/material/Typography";
52+
import { ClowderSelect } from "../styledComponents/ClowderSelect";
4253

4354
export const File = (): JSX.Element => {
4455
// path parameter
@@ -70,29 +81,36 @@ export const File = (): JSX.Element => {
7081
dispatch(fetchFolderPath(folderId));
7182

7283
const file = useSelector((state: RootState) => state.file);
73-
const version_num = useSelector(
84+
const latestVersionNum = useSelector(
7485
(state: RootState) => state.file.fileSummary.version_num
7586
);
76-
const [selectedVersion, setSelectedVersion] = useState(version_num);
87+
const [selectedVersionNum, setSelectedVersionNum] = useState(
88+
latestVersionNum ?? 1
89+
);
7790
const fileSummary = useSelector((state: RootState) => state.file.fileSummary);
7891
const filePreviews = useSelector((state: RootState) => state.file.previews);
7992
const fileVersions = useSelector(
8093
(state: RootState) => state.file.fileVersions
8194
);
8295
const folderPath = useSelector((state: RootState) => state.folder.folderPath);
83-
const [selectedFileVersionDetails, setSelectedFileVersionDetails] = useState(
84-
fileVersions[0]
85-
);
8696
const fileRole = useSelector((state: RootState) => state.file.fileRole);
8797

8898
const [selectedTabIndex, setSelectedTabIndex] = useState(0);
8999
const [previews, setPreviews] = useState([]);
90100
const [enableAddMetadata, setEnableAddMetadata] =
91101
React.useState<boolean>(false);
92102
const [metadataRequestForms, setMetadataRequestForms] = useState({});
93-
const [allowSubmit, setAllowSubmit] = React.useState<boolean>(false);
94103
const [paths, setPaths] = useState([]);
95104

105+
// Error msg dialog
106+
const [errorOpen, setErrorOpen] = useState(false);
107+
const [showForbiddenPage, setShowForbiddenPage] = useState(false);
108+
const [showNotFoundPage, setShowNotFoundPage] = useState(false);
109+
110+
// snack bar
111+
const [snackBarOpen, setSnackBarOpen] = useState(false);
112+
const [snackBarMessage, setSnackBarMessage] = useState("");
113+
96114
// component did mount
97115
useEffect(() => {
98116
// load file information
@@ -137,31 +155,10 @@ export const File = (): JSX.Element => {
137155
}, [about, fileSummary, folderPath]);
138156

139157
useEffect(() => {
140-
if (version_num !== undefined && version_num !== null) {
141-
setSelectedVersion(version_num);
158+
if (latestVersionNum !== undefined && latestVersionNum !== null) {
159+
setSelectedVersionNum(latestVersionNum);
142160
}
143-
}, [version_num]);
144-
145-
useEffect(() => {
146-
if (
147-
version_num !== undefined &&
148-
version_num !== null &&
149-
fileVersions !== undefined &&
150-
fileVersions !== null &&
151-
fileVersions.length > 0
152-
) {
153-
fileVersions.map((fileVersion, idx) => {
154-
if (fileVersion.version_num == version_num) {
155-
setSelectedFileVersionDetails(fileVersion);
156-
}
157-
});
158-
}
159-
}, [version_num]);
160-
161-
// Error msg dialog
162-
const [errorOpen, setErrorOpen] = useState(false);
163-
const [showForbiddenPage, setShowForbiddenPage] = useState(false);
164-
const [showNotFoundPage, setShowNotFoundPage] = useState(false);
161+
}, [latestVersionNum]);
165162

166163
useEffect(() => {
167164
(async () => {
@@ -246,11 +243,6 @@ export const File = (): JSX.Element => {
246243
setEnableAddMetadata(false);
247244
};
248245

249-
// const submitToListener = ()=> {
250-
// const filename = fileSummary['name']
251-
// history(`/listeners?fileId=${fileId}&fileName=${filename}`);
252-
// }
253-
254246
if (showForbiddenPage) {
255247
return <Forbidden />;
256248
} else if (showNotFoundPage) {
@@ -261,25 +253,29 @@ export const File = (): JSX.Element => {
261253
<Layout>
262254
{/*Error Message dialogue*/}
263255
<ErrorModal errorOpen={errorOpen} setErrorOpen={setErrorOpen} />
256+
{/*snackbar*/}
257+
<Snackbar
258+
open={snackBarOpen}
259+
autoHideDuration={6000}
260+
onClose={() => {
261+
setSnackBarOpen(false);
262+
setSnackBarMessage("");
263+
}}
264+
message={snackBarMessage}
265+
/>
264266
<Grid container>
265267
<Grid item xs={10} sx={{ display: "flex", alignItems: "center" }}>
266268
<MainBreadcrumbs paths={paths} />
267269
<Grid item>
268-
<VersionChip
269-
selectedVersion={selectedVersion}
270-
setSelectedVersion={setSelectedVersion}
271-
versionNumbers={fileVersions}
272-
isClickable={true}
273-
/>
270+
<VersionChip selectedVersion={selectedVersionNum} />
274271
<RoleChip role={fileRole} />
275272
</Grid>
276273
</Grid>
277274
<Grid item xs={2} sx={{ display: "flex-top", alignItems: "center" }}>
278275
<FileActionsMenu
279-
filename={fileSummary.name}
280276
fileId={fileId}
281277
datasetId={datasetId}
282-
setSelectedVersion={setSelectedVersion}
278+
setSelectedVersion={setSelectedVersionNum}
283279
/>
284280
</Grid>
285281
</Grid>
@@ -411,31 +407,49 @@ export const File = (): JSX.Element => {
411407
<ExtractionHistoryTab fileId={fileId} />
412408
</TabPanel>
413409
</Grid>
414-
{version_num == selectedVersion ? (
415-
<Grid item xs={2}>
416-
{Object.keys(fileSummary).length > 0 && (
417-
<FileDetails fileSummary={fileSummary} />
418-
)}
419-
</Grid>
420-
) : (
421-
<Grid item xs={2}>
422-
{Object.keys(fileSummary).length > 0 && (
423-
<FileHistory
424-
id={fileId}
425-
created={file.fileSummary.created}
426-
name={file.fileSummary.name}
427-
creator={file.fileSummary.creator}
428-
version_id={file.fileSummary.version_id}
429-
bytes={file.fileSummary.bytes}
430-
content_type={file.fileSummary.content_type}
431-
views={file.fileSummary.views}
432-
downloads={file.fileSummary.downloads}
433-
current_version={selectedVersion}
434-
fileSummary={file.fileSummary}
435-
/>
436-
)}
437-
</Grid>
438-
)}
410+
<Grid item xs={2}>
411+
{latestVersionNum == selectedVersionNum ? (
412+
// latest version
413+
<>
414+
{Object.keys(fileSummary).length > 0 && (
415+
<FileDetails fileSummary={fileSummary} />
416+
)}
417+
</>
418+
) : (
419+
// history version
420+
<>
421+
{Object.keys(fileSummary).length > 0 && (
422+
<FileHistory
423+
name={file.fileSummary.name}
424+
contentType={file.fileSummary.content_type?.content_type}
425+
selectedVersionNum={selectedVersionNum}
426+
/>
427+
)}
428+
</>
429+
)}
430+
<>
431+
<Typography sx={{ wordBreak: "break-all" }}>Version</Typography>
432+
<FormControl>
433+
<ClowderSelect
434+
value={String(selectedVersionNum)}
435+
defaultValue={"viewer"}
436+
onChange={(event) => {
437+
setSelectedVersionNum(event.target.value);
438+
setSnackBarMessage("Viewing version " + event.target.value);
439+
setSnackBarOpen(true);
440+
}}
441+
>
442+
{fileVersions.map((fileVersion) => {
443+
return (
444+
<MenuItem value={fileVersion.version_num}>
445+
{fileVersion.version_num}
446+
</MenuItem>
447+
);
448+
})}
449+
</ClowderSelect>
450+
</FormControl>
451+
</>
452+
</Grid>
439453
</Grid>
440454
</Layout>
441455
);

frontend/src/components/files/FileActionsMenu.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import config from "../../app.config";
3030

3131
type FileActionsMenuProps = {
3232
fileId?: string;
33-
filename?: string;
3433
datasetId?: string;
3534
setSelectedVersion: any;
3635
};

frontend/src/components/files/FileDetails.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export function FileDetails(props: FileAboutProps) {
3232
details.set("Downloads", downloads);
3333

3434
return (
35-
<Box sx={{ mt: 5 }}>
35+
<Box sx={{ mt: 5, mb: 2 }}>
3636
<Typography variant="h5" gutterBottom>
3737
Details
3838
</Typography>

frontend/src/components/files/FileHistory.tsx

Lines changed: 46 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,69 @@
1-
import React, {useEffect, useState} from "react";
1+
import React, { useEffect, useState } from "react";
22
import { Box, Typography } from "@mui/material";
33
import { parseDate } from "../../utils/common";
4-
import {ContentType, FileOut, FileVersion, UserOut} from "../../openapi/v2";
4+
import { FileVersion } from "../../openapi/v2";
55
import prettyBytes from "pretty-bytes";
66
import { StackedList } from "../util/StackedList";
7-
import {useSelector} from "react-redux";
8-
import {RootState} from "../../types/data";
7+
import { useSelector } from "react-redux";
8+
import { RootState } from "../../types/data";
99

1010
type FileHistoryAboutProps = {
11-
id: string;
12-
created:any;
13-
name:string;
14-
creator:UserOut;
15-
version_id:string;
16-
bytes:number;
17-
content_type:ContentType;
18-
views:number;
19-
downloads:number;
20-
current_version:number|undefined;
21-
fileSummary:FileOut;
11+
name?: string;
12+
selectedVersionNum?: number;
13+
contentType?: string;
2214
};
2315

2416
export function FileHistory(props: FileHistoryAboutProps) {
25-
const {
26-
id,
27-
created,
28-
name,
29-
creator,
30-
version_id,
31-
bytes,
32-
content_type,
33-
views,
34-
downloads,
35-
current_version,
36-
fileSummary,
37-
} = props;
17+
const { name, selectedVersionNum, contentType } = props;
3818

3919
const fileVersions = useSelector(
4020
(state: RootState) => state.file.fileVersions
4121
);
42-
const [currentSelectedFileVersion, setCurrentSelectedFileVersion] = useState(fileVersions[0]);
43-
44-
useEffect( () =>
45-
{
46-
if (current_version !== undefined && current_version !== null
47-
&& fileVersions !== undefined && fileVersions !== null
48-
&& fileVersions.length > 0) {
49-
fileVersions.map((fileVersion: FileVersion, idx: number) => {
50-
if (fileVersion.version_num == current_version){
51-
setCurrentSelectedFileVersion(fileVersion);
52-
}
53-
})
54-
}
55-
}, [current_version]
56-
)
22+
const [selectedFileVersionDetail, setSelectedFileVersionDetail] = useState(
23+
fileVersions[0]
24+
);
5725

26+
useEffect(() => {
27+
if (
28+
selectedVersionNum !== undefined &&
29+
selectedVersionNum !== null &&
30+
fileVersions !== undefined &&
31+
fileVersions !== null &&
32+
fileVersions.length > 0
33+
) {
34+
fileVersions.map((fileVersion: FileVersion) => {
35+
if (fileVersion.version_num == selectedVersionNum) {
36+
setSelectedFileVersionDetail(fileVersion);
37+
}
38+
});
39+
}
40+
}, [selectedVersionNum]);
5841

5942
const details = new Map<string, string>();
60-
if (currentSelectedFileVersion !== null && currentSelectedFileVersion !== undefined) {
61-
details.set("Size", prettyBytes(currentSelectedFileVersion.bytes));
62-
details.set("Content type", currentSelectedFileVersion.content_type);
63-
details.set("Updated on", parseDate(currentSelectedFileVersion.created));
64-
details.set("Uploaded as", name);
65-
details.set("Uploaded by", `${currentSelectedFileVersion.creator.first_name} ${currentSelectedFileVersion.creator.last_name}`);
66-
details.set("File id", id);
67-
details.set("Downloads", downloads);
43+
if (
44+
selectedFileVersionDetail !== null &&
45+
selectedFileVersionDetail !== undefined
46+
) {
47+
details.set(
48+
"Size",
49+
selectedFileVersionDetail.bytes
50+
? prettyBytes(selectedFileVersionDetail.bytes)
51+
: "NA"
52+
);
53+
details.set("Content type", contentType ?? "NA");
54+
details.set("Updated on", parseDate(selectedFileVersionDetail.created));
55+
details.set("Uploaded as", name ?? "NA");
56+
details.set(
57+
"Uploaded by",
58+
`${selectedFileVersionDetail.creator.first_name} ${selectedFileVersionDetail.creator.last_name}`
59+
);
60+
details.set("File id", selectedFileVersionDetail.file_id);
6861
}
6962

70-
7163
return (
72-
<Box sx={{ mt: 5 }}>
64+
<Box sx={{ mt: 5, mb: 2 }}>
7365
<Typography variant="h5" gutterBottom>
74-
History
66+
Details
7567
</Typography>
7668
<StackedList keyValues={details} />
7769
</Box>

frontend/src/components/files/FilesTableFileEntry.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,7 @@ export function FilesTableFileEntry(props: FilesTableFileEntryProps) {
5353
<Button onClick={() => selectFile(file.id)}>{file.name}</Button>
5454
</TableCell>
5555
<TableCell>
56-
<VersionChip
57-
selectedVersion={selectedVersion}
58-
setSelectedVersion={null}
59-
versionNumbers={null}
60-
isClickable={false}
61-
/>
56+
<VersionChip selectedVersion={selectedVersion} />
6257
</TableCell>
6358
<TableCell align="right">{parseDate(file.created)}</TableCell>
6459
<TableCell align="right">

0 commit comments

Comments
 (0)