Skip to content

Commit 845b0ee

Browse files
committed
add remote file selection
1 parent 1ec90a8 commit 845b0ee

File tree

8 files changed

+200
-53
lines changed

8 files changed

+200
-53
lines changed

web-server/components/RemoteFileBrowser.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export interface RemoteFileBrowserProps {
2222
hostname: string;
2323
persistenceId?: string;
2424
onSelectFileCallBack: Function;
25-
onSelectParserCallBack: Function;
25+
onSelectParserCallBack?: Function | undefined;
2626
onReauthCallBack: Function;
2727
selectedOption?: string;
2828
showSelector?: boolean;
@@ -367,7 +367,7 @@ export default function RemoteFileBrowser(props: RemoteFileBrowserProps) {
367367
Loading...
368368
</button>
369369
)}
370-
{props.showSelector !== false && props.selectedOption && (
370+
{props.showSelector !== false && props.onSelectParserCallBack && props.selectedOption && (
371371
<SlycatSelector
372372
onSelectCallBack={props.onSelectParserCallBack}
373373
label={"Filetype"}

web-server/js/slycat-dialog.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ export function ajax_error(message)
112112
{
113113
dialog(
114114
{
115-
message: message + " " + reason_phrase
115+
message: message + " " + (reason_phrase ?? '')
116116
});
117117
}
118118
}

web-server/js/slycat-file-uploader-factory.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ function finishUpload(pid, mid, uid, file, numberOfUploadedSlices, fileObject, u
550550
*/
551551
function deleteUpload(pid, mid, uid, fileObject, progress_increment_applied) {
552552
if (fileObject.progress_status) {
553+
fileObject.progress(80);
553554
fileObject.progress_status("Parsing...");
554555
}
555556
client.delete_upload({

web-server/plugins/slycat-cca/js/components/CCAWizardUtils.tsx

Lines changed: 111 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ import {
1717
selectMarking,
1818
selectMid,
1919
selectName,
20+
selectParser,
2021
selectPid,
22+
selectProgress,
23+
selectProgressStatus,
24+
selectRemotePath,
2125
selectScaleInputs,
2226
selectTab,
2327
setAttributes,
@@ -26,6 +30,8 @@ import {
2630
setLoading,
2731
setMid,
2832
setPid,
33+
setProgress,
34+
setProgressStatus,
2935
setTabName,
3036
TabNames,
3137
} from "./wizard-store/reducers/cCAWizardSlice";
@@ -46,6 +52,7 @@ export const useCCAWizardFooter = () => {
4652
const authInfo = useAppSelector(selectAuthInfo);
4753
const dispatch = useAppDispatch();
4854
const uploadSelection = useUploadSelection();
55+
const uploadHandleRemoteFileSubmit = useHandleRemoteFileSubmit();
4956
const handleAuthentication = useHandleAuthentication();
5057
const finishModel = useFinishModel();
5158

@@ -54,11 +61,9 @@ export const useCCAWizardFooter = () => {
5461
*/
5562
const handleContinue = React.useCallback(() => {
5663
if (tabName === TabNames.CCA_DATA_WIZARD_SELECTION_TAB && dataLocation === "local") {
57-
console.log(dataLocation);
5864
dispatch(setTabName(TabNames.CCA_LOCAL_BROWSER_TAB));
5965
}
6066
if (tabName === TabNames.CCA_DATA_WIZARD_SELECTION_TAB && dataLocation === "remote") {
61-
console.log(dataLocation);
6267
dispatch(setTabName(TabNames.CCA_AUTHENTICATION_TAB));
6368
}
6469
if (tabName === TabNames.CCA_AUTHENTICATION_TAB) {
@@ -68,6 +73,9 @@ export const useCCAWizardFooter = () => {
6873
handleAuthentication();
6974
}
7075
}
76+
if (tabName === TabNames.CCA_REMOTE_BROWSER_TAB) {
77+
uploadHandleRemoteFileSubmit();
78+
}
7179
if (tabName === TabNames.CCA_LOCAL_BROWSER_TAB && fileUploaded) {
7280
dispatch(setTabName(TabNames.CCA_TABLE_INGESTION));
7381
}
@@ -81,6 +89,7 @@ export const useCCAWizardFooter = () => {
8189
dispatch,
8290
uploadSelection,
8391
handleAuthentication,
92+
uploadHandleRemoteFileSubmit,
8493
fileUploaded,
8594
setTabName,
8695
tabName,
@@ -100,9 +109,12 @@ export const useCCAWizardFooter = () => {
100109
if (tabName === TabNames.CCA_REMOTE_BROWSER_TAB) {
101110
dispatch(setTabName(TabNames.CCA_AUTHENTICATION_TAB));
102111
}
103-
if (tabName === TabNames.CCA_TABLE_INGESTION) {
112+
if (tabName === TabNames.CCA_TABLE_INGESTION && dataLocation === "local") {
104113
dispatch(setTabName(TabNames.CCA_LOCAL_BROWSER_TAB));
105114
}
115+
if (tabName === TabNames.CCA_TABLE_INGESTION && dataLocation === "remote") {
116+
dispatch(setTabName(TabNames.CCA_REMOTE_BROWSER_TAB));
117+
}
106118
if (tabName === TabNames.CCA_FINISH_MODEL) {
107119
dispatch(setTabName(TabNames.CCA_TABLE_INGESTION));
108120
}
@@ -132,7 +144,7 @@ export const useCCAWizardFooter = () => {
132144
Continue
133145
</button>
134146
) : (
135-
<button className="btn btn-primary" type="button" disabled>
147+
<button className="btn btn-primary" type="button" key="loading" disabled>
136148
<span className="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
137149
Loading...
138150
</button>
@@ -249,6 +261,7 @@ const useFileUploadSuccess = () => {
249261
},
250262
);
251263
dispatch(setAttributes(attributes ?? []));
264+
dispatch(setLoading(false));
252265
setUploadStatus(true);
253266
dispatch(setTabName(TabNames.CCA_TABLE_INGESTION));
254267
},
@@ -258,33 +271,116 @@ const useFileUploadSuccess = () => {
258271
);
259272
};
260273

274+
/**
275+
* Sets up a stable function for handling remote file uploads, including setting loading status, progress bar, and switching to the next tab.
276+
* @returns a stable function for handling remote file upload
277+
*/
278+
export const useHandleRemoteFileSubmit = () => {
279+
const mid = useAppSelector(selectMid);
280+
const pid = useAppSelector(selectPid);
281+
const fileDescriptor = useAppSelector(selectRemotePath);
282+
const parser = useAppSelector(selectParser);
283+
const { hostname } = useAppSelector(selectAuthInfo);
284+
const dispatch = useAppDispatch();
285+
const progress = useAppSelector(selectProgress);
286+
const progressStatus = useAppSelector(selectProgressStatus);
287+
const fileUploadSuccess = useFileUploadSuccess();
288+
return React.useCallback(() => {
289+
dispatch(setLoading(true));
290+
console.log(fileDescriptor);
291+
if (!fileDescriptor?.path) {
292+
dialog.ajax_error(`no file selected`)();
293+
dispatch(setLoading(false));
294+
return;
295+
}
296+
if (fileDescriptor.type !== "f") {
297+
dialog.ajax_error(
298+
`Did you choose the correct file and filetype? selected file: ${fileDescriptor?.path} is not a file `,
299+
)();
300+
dispatch(setLoading(false));
301+
return;
302+
}
303+
client
304+
.get_remote_file_fetch({ hostname: hostname, path: fileDescriptor?.path })
305+
.then((response: any) => {
306+
return response.text();
307+
})
308+
.then((file) => {
309+
const progressCallback = (input?: number) => {
310+
if (!input) {
311+
return progress;
312+
}
313+
dispatch(setProgress(input));
314+
};
315+
const progressStatusCallback = (input?: string) => {
316+
if (!input) {
317+
return progressStatus;
318+
}
319+
dispatch(setProgressStatus(input));
320+
};
321+
const fileObject = {
322+
pid,
323+
mid,
324+
file,
325+
parser,
326+
hostname,
327+
paths: fileDescriptor.path,
328+
aids: [["data-table"], fileDescriptor.path.split("/").at(-1)],
329+
progress: progressCallback,
330+
progress_status: progressStatusCallback,
331+
progress_final: 90,
332+
success: function () {
333+
setProgress(100);
334+
setProgressStatus("File upload complete");
335+
dispatch(setLoading(false));
336+
dispatch(setTabName(TabNames.CCA_TABLE_INGESTION));
337+
// setUploadStatus(true);
338+
fileUploadSuccess(setProgress, setProgressStatus, (status) => console.log(status));
339+
},
340+
error: function () {
341+
// setUploadStatus(false);
342+
dispatch(setLoading(false));
343+
dialog.ajax_error(
344+
"Did you choose the correct file and filetype? There was a problem parsing the file: ",
345+
)();
346+
dispatch(setProgress(0));
347+
dispatch(setProgressStatus(""));
348+
},
349+
};
350+
fileUploader.uploadFile(fileObject);
351+
});
352+
}, [mid, pid, hostname, fileDescriptor, fileUploadSuccess, parser, dispatch]);
353+
};
354+
261355
/**
262356
* handle local file submission
263357
*/
264358
export const useHandleLocalFileSubmit = (): [
265359
(file: File, parser: string | undefined, setUploadStatus: (status: boolean) => void) => void,
266360
number,
267-
string,
361+
string | undefined,
268362
] => {
269363
const mid = useAppSelector(selectMid);
270364
const pid = useAppSelector(selectPid);
365+
const progress = useAppSelector(selectProgress);
366+
const progressStatus = useAppSelector(selectProgressStatus);
367+
const dispatch = useAppDispatch();
271368
const fileUploadSuccess = useFileUploadSuccess();
272-
const [progress, setProgress] = React.useState<number>(0);
273-
const [progressStatus, setProgressStatus] = React.useState("");
274369
const handleSubmit = React.useCallback(
275370
(file: File, parser: string | undefined, setUploadStatus: (status: boolean) => void) => {
276371
const progressCallback = (input?: number) => {
277372
if (!input) {
278373
return progress;
279374
}
280-
setProgress(input);
375+
dispatch(setProgress(input));
281376
};
282377
const progressStatusCallback = (input?: string) => {
283378
if (!input) {
284379
return progressStatus;
285380
}
286-
setProgressStatus(input);
381+
dispatch(setProgressStatus(input));
287382
};
383+
dispatch(setLoading(true));
288384
const fileObject = {
289385
pid,
290386
mid,
@@ -296,19 +392,19 @@ export const useHandleLocalFileSubmit = (): [
296392
progress_status: progressStatusCallback,
297393
progress_final: 90,
298394
success: function () {
299-
setProgress(100);
300-
setProgressStatus("File upload complete");
395+
dispatch(setProgress(100));
396+
dispatch(setProgressStatus("File upload complete"));
301397
setUploadStatus(true);
302398
fileUploadSuccess(setProgress, setProgressStatus, setUploadStatus);
303399
},
304400
error: function () {
305401
setUploadStatus(false);
402+
dispatch(setLoading(false));
306403
dialog.ajax_error(
307404
"Did you choose the correct file and filetype? There was a problem parsing the file: ",
308405
)();
309-
// TODO: toggle disabled for continue
310-
setProgress(0);
311-
setProgressStatus("");
406+
dispatch(setProgress(0));
407+
dispatch(setProgressStatus(""));
312408
},
313409
};
314410
fileUploader.uploadFile(fileObject);
@@ -323,7 +419,7 @@ export const useHandleLocalFileSubmit = (): [
323419
* Returns a function that sets the callback "setParser" value to the selected parser
324420
*/
325421
export const handleParserChange = (
326-
setParser: React.Dispatch<React.SetStateAction<string | undefined>>,
422+
setParser: (parser: string) => void | React.Dispatch<React.SetStateAction<string | undefined>>,
327423
) =>
328424
React.useCallback(
329425
(e: React.ChangeEvent<HTMLSelectElement>) => {

web-server/plugins/slycat-cca/js/components/slycat-local-browser/SlycatLocalBrowser.tsx

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,19 @@
44
import * as React from "react";
55
import { useHandleLocalFileSubmit } from "../CCAWizardUtils";
66
import { SlycatParserControls } from "../slycat-parser-controls/SlycatParserControls";
7+
import { useAppDispatch, useAppSelector } from "../wizard-store/hooks";
8+
import { selectParser, setParser } from "../wizard-store/reducers/cCAWizardSlice";
79

810
export const SlycatLocalBrowser = (props: { setUploadStatus: (status: boolean) => void }) => {
911
const { setUploadStatus } = props;
10-
const [fileSelected, setFileSelected] = React.useState<boolean>(false);
11-
const [file, setFile] = React.useState<File | undefined>(undefined);
12-
const [parser, setParser] = React.useState<string | undefined>(undefined);
12+
const dispatch = useAppDispatch();
13+
const parser = useAppSelector(selectParser);
1314
const [handleSubmit, progress, progressStatus] = useHandleLocalFileSubmit();
1415
const handleFileSelected = (e: React.ChangeEvent<HTMLInputElement>): void => {
1516
if (e.target.files !== null && e.target.files.length >= 1) {
16-
setFileSelected(true);
17-
setFile(e.target.files[0]);
17+
if (e.target.files[0]) {
18+
handleSubmit(e.target.files[0], parser, setUploadStatus);
19+
}
1820
}
1921
};
2022
return (
@@ -28,23 +30,14 @@ export const SlycatLocalBrowser = (props: { setUploadStatus: (status: boolean) =
2830
id="slycat-local-browser-file"
2931
placeholder="file"
3032
></input>
31-
<SlycatParserControls setParser={setParser} />
32-
<button
33-
key="Upload File To Server"
34-
disabled={!fileSelected}
35-
style={{ visibility: progress <= 0 ? "visible" : "hidden" }}
36-
className="btn btn-primary"
37-
data-toggle="tooltip"
38-
data-placement="top"
39-
title="You must selected a file before continuing."
40-
onClick={React.useCallback(() => {
41-
if (file) {
42-
handleSubmit(file, parser, setUploadStatus);
43-
}
44-
}, [file, handleSubmit])}
45-
>
46-
{fileSelected ? `Upload File: ${file?.name}` : "Select A File"}
47-
</button>
33+
<SlycatParserControls
34+
setParser={React.useCallback(
35+
(parser: string) => {
36+
dispatch(setParser(parser));
37+
},
38+
[dispatch],
39+
)}
40+
/>
4841
<div className="progress" style={{ visibility: progress > 0 ? undefined : "hidden" }}>
4942
<div
5043
className="progress-bar progress-bar-striped progress-bar-animated"

web-server/plugins/slycat-cca/js/components/slycat-parser-controls/SlycatParserControls.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { includes } from "lodash";
77
import { handleParserChange } from "../CCAWizardUtils";
88

99
export const SlycatParserControls = (props: {
10-
setParser: React.Dispatch<React.SetStateAction<string | undefined>>;
10+
setParser: (parser: string) => void | React.Dispatch<React.SetStateAction<string | undefined>>;
1111
}) => {
1212
const { setParser } = props;
1313
const filteredParsers: [{ type: () => string; label: () => string }] = parsers

0 commit comments

Comments
 (0)