Skip to content

Commit cd46219

Browse files
committed
add upload status and completion to local browser
1 parent 03e5667 commit cd46219

File tree

9 files changed

+116
-59
lines changed

9 files changed

+116
-59
lines changed

docker/compose/slycat-compose/slycat-web-server/DockerFile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ RUN pip install --trusted-host files.pythonhosted.org --trusted-host pypi.org --
1010
RUN pip install --trusted-host files.pythonhosted.org --trusted-host pypi.org --trusted-host pypi.python.org --no-cache-dir -r requirements.txt
1111

1212
RUN git config --global http.sslVerify false
13+
RUN git config --global http.postBuffer 524288000
1314
RUN git clone --depth 1 https://github.com/sandialabs/slycat.git
1415
RUN mkdir -p /var/lib/slycat/data-store
1516
WORKDIR /usr/src/slycat/slycat

docker/compose/slycat-compose/sshd/DockerFile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ LABEL maintainer="Matthew Letter <mletter@sandia.gov>"
44

55
ENV DEBIAN_FRONTEND noninteractive
66

7-
RUN apt-get update && \
8-
apt-get --yes install openssh-server rsync git && \
7+
RUN apt-get update
8+
RUN apt-get --yes install openssh-server rsync git && \
99
apt-get clean && \
1010
rm -rf /var/lib/apt/lists/* && \
1111
mkdir -vp /var/run/sshd && \

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,16 @@ export const CCAWizard = (params: CCAWizardParams) => {
2121
const { pid, marking } = params;
2222
const [modalOpen, setModalOpen] = React.useState(true);
2323
const cCAWizardFooter = useCCAWizardFooter();
24-
const dispatch = useAppDispatch();
2524
const statePid = useAppSelector(selectPid);
2625
const stateMid = useAppSelector(selectMid);
2726
const handleClosingCallback = useHandleClosingCallback(setModalOpen, stateMid);
2827
const handleWizardSetup = useHandleWizardSetup(pid, statePid, stateMid, marking);
2928

3029
React.useEffect(() => {
31-
console.log("statePid, pid, selectMid", statePid, pid, stateMid);
3230
if (modalOpen) {
3331
handleWizardSetup()
3432
}
35-
}, [dispatch, pid, statePid, stateMid]);
33+
}, [pid, statePid, stateMid]);
3634

3735
return (
3836
<CCAModalContent

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

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,6 @@ export const CCAWizardSteps = () => {
1717
<div className="tab-content">
1818
<CCAWizardDataSelectionTab hidden={!(tabName === TabNames.CCA_DATA_WIZARD_SELECTION_TAB)}/>
1919
<CCALocalBrowserTab hidden={!(tabName === TabNames.CCA_LOCAL_BROWSER_TAB)}/>
20-
<div hidden={true}>
21-
<div
22-
className="alert alert-danger"
23-
role="alert"
24-
data-bind="visible:show_local_browser_error()"
25-
>
26-
You must selected a file before continuing.
27-
</div>
28-
{/* <slycat-local-browser
29-
params="
30-
selection:browser.selection,
31-
progress:browser.progress,
32-
progress_status:browser.progress_status"
33-
></slycat-local-browser>
34-
<slycat-parser-controls params="parser:parser,category:'table'"></slycat-parser-controls> */}
35-
</div>
36-
3720
<div hidden={true}>
3821
<form role="form">
3922
{/* <slycat-remote-controls

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

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,28 @@ import { useAppDispatch, useAppSelector } from "./wizard-store/hooks";
66
import {
77
resetCCAWizard,
88
selectDataLocation,
9+
selectFileUploaded,
910
selectMid,
1011
selectPid,
1112
selectTab,
13+
setFileUploaded,
1214
setMid,
1315
setPid,
1416
setTabName,
1517
TabNames,
16-
uploadFile,
1718
} from "./wizard-store/reducers/cCAWizardSlice";
1819
import client from "js/slycat-web-client";
1920
import fileUploader from "js/slycat-file-uploader-factory";
2021
import * as dialog from "js/slycat-dialog";
2122

23+
/**
24+
* A hook for controlling how the back and continue buttons work based on the current redux state
25+
* @returns the back button and continue button jsx
26+
*/
2227
export const useCCAWizardFooter = () => {
2328
const tabName = useAppSelector(selectTab);
2429
const dataLocation = useAppSelector(selectDataLocation);
30+
const fileUploaded = useAppSelector(selectFileUploaded);
2531
const dispatch = useAppDispatch();
2632

2733
/**
@@ -31,8 +37,8 @@ export const useCCAWizardFooter = () => {
3137
if (tabName === TabNames.CCA_DATA_WIZARD_SELECTION_TAB && dataLocation) {
3238
dispatch(setTabName(TabNames.CCA_LOCAL_BROWSER_TAB));
3339
}
34-
if (tabName === TabNames.CCA_LOCAL_BROWSER_TAB) {
35-
dispatch(uploadFile());
40+
if (tabName === TabNames.CCA_LOCAL_BROWSER_TAB && fileUploaded) {
41+
dispatch(setTabName(TabNames.CCA_LOCAL_BROWSER_TAB));
3642
}
3743
}, [dispatch, setTabName, tabName]);
3844

@@ -55,11 +61,16 @@ export const useCCAWizardFooter = () => {
5561
);
5662

5763
const nextButton = (
58-
<button key="continue" className="btn btn-primary" onClick={handleContinue}>
59-
Continue
64+
<button
65+
key="continue"
66+
className="btn btn-primary"
67+
onClick={handleContinue}
68+
disabled={tabName === TabNames.CCA_LOCAL_BROWSER_TAB && !fileUploaded}
69+
>
70+
Continue {fileUploaded.toString()}
6071
</button>
6172
);
62-
return React.useMemo(() => [backButton, nextButton], [tabName, dataLocation, dispatch]);
73+
return React.useMemo(() => [backButton, nextButton], [fileUploaded, tabName, dataLocation, dispatch]);
6374
};
6475

6576
/**
@@ -122,32 +133,47 @@ export const useHandleClosingCallback = (
122133
/**
123134
* handle file submission
124135
*/
125-
export const useHandleSubmit = ():[(file: File) => void, number, string] => {
136+
export const useHandleLocalFileSubmit = (): [
137+
(file: File, parser: string | undefined, setUploadStatus: (status: boolean) => void) => void,
138+
number,
139+
string,
140+
] => {
126141
const mid = useAppSelector(selectMid);
127142
const pid = useAppSelector(selectPid);
128143
const [progress, setProgress] = React.useState<number>(0);
129144
const [progressStatus, setProgressStatus] = React.useState("");
130145
const handleSubmit = React.useCallback(
131-
(file: File) => {
146+
(file: File, parser: string | undefined, setUploadStatus: (status: boolean) => void) => {
132147
const progressCallback = (input?: number) => {
133148
if (!input) {
134149
return progress;
135150
}
136151
setProgress(input);
137152
};
153+
const progressStatusCallback = (input?: string) => {
154+
if (!input) {
155+
return progressStatus;
156+
}
157+
setProgressStatus(input);
158+
};
138159
const fileObject = {
139160
pid,
140161
mid,
141162
file: file,
163+
parser: parser,
142164
aids: [["data-table"], file?.name],
143165
// parser: component.parser(),
144-
progress: progress,
145-
progress_status: progressCallback,
166+
progress: progressCallback,
167+
progress_status: progressStatusCallback,
146168
progress_final: 90,
147169
success: function () {
148-
// set browser tab
170+
console.log("uploaded");
171+
setProgress(100);
172+
setProgressStatus("File upload complete");
173+
setUploadStatus(true);
149174
},
150175
error: function () {
176+
setUploadStatus(false);
151177
dialog.ajax_error(
152178
"Did you choose the correct file and filetype? There was a problem parsing the file: ",
153179
)();
@@ -163,3 +189,27 @@ export const useHandleSubmit = ():[(file: File) => void, number, string] => {
163189

164190
return [handleSubmit, progress, progressStatus];
165191
};
192+
193+
/**
194+
* Returns a function that sets the callback "setParser" value to the selected parser
195+
*/
196+
export const handleParserChange = (
197+
setParser: React.Dispatch<React.SetStateAction<string | undefined>>,
198+
) =>
199+
React.useCallback(
200+
(e: React.ChangeEvent<HTMLSelectElement>) => {
201+
setParser(e?.target?.value ?? undefined);
202+
},
203+
[setParser],
204+
);
205+
206+
export const useSetUploadStatus = () => {
207+
const dispatch = useAppDispatch();
208+
return React.useCallback(
209+
(status: boolean) => {
210+
console.log("dispatching", status);
211+
dispatch(setFileUploaded(status));
212+
},
213+
[dispatch],
214+
);
215+
};

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

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
DE-NA0003525 with National Technology and Engineering Solutions of Sandia, LLC, the U.S. Government
33
retains certain rights in this software. */
44
import * as React from "react";
5-
import { useHandleSubmit } from "../CCAWizardUtils";
5+
import { useHandleLocalFileSubmit } from "../CCAWizardUtils";
66
import { SlycatParserControls } from "../slycat-parser-controls/SlycatParserControls";
77

8-
export const SlycatLocalBrowser = () => {
8+
export const SlycatLocalBrowser = (props: { setUploadStatus: (status: boolean) => void, disabled?: boolean }) => {
9+
const { setUploadStatus, disabled } = props;
910
const [file, setFile] = React.useState<File | undefined>(undefined);
10-
const [handleSubmit, progress, progressStatus] = useHandleSubmit();
11+
const [parser, setParser] = React.useState<string | undefined>(undefined);
12+
const [handleSubmit, progress, progressStatus] = useHandleLocalFileSubmit();
1113
const handleFileSelected = (e: React.ChangeEvent<HTMLInputElement>): void => {
1214
if (e.target.files !== null && e.target.files.length >= 1) {
1315
setFile(e.target.files[0]);
@@ -24,6 +26,23 @@ export const SlycatLocalBrowser = () => {
2426
id="slycat-local-browser-file"
2527
placeholder="file"
2628
></input>
29+
<SlycatParserControls setParser={setParser} />
30+
<button
31+
key="Upload File To Server"
32+
disabled={disabled ?? false }
33+
style={{visibility: progress<=0? 'visible': 'hidden'}}
34+
className="btn btn-primary"
35+
data-toggle="tooltip"
36+
data-placement="top"
37+
title="You must selected a file before continuing."
38+
onClick={React.useCallback(() => {
39+
if (file) {
40+
handleSubmit(file, parser, setUploadStatus);
41+
}
42+
}, [file, handleSubmit])}
43+
>
44+
Upload File parser
45+
</button>
2746
<div className="progress" style={{ visibility: progress > 0 ? undefined : "hidden" }}>
2847
<div
2948
className="progress-bar progress-bar-striped progress-bar-animated"
@@ -36,18 +55,6 @@ export const SlycatLocalBrowser = () => {
3655
{progressStatus}
3756
</div>
3857
</div>
39-
<SlycatParserControls/>
40-
<button
41-
key="Upload File To Server"
42-
className="btn btn-primary"
43-
onClick={React.useCallback(() => {
44-
if (file) {
45-
handleSubmit(file);
46-
}
47-
}, [file, handleSubmit])}
48-
>
49-
Upload File
50-
</button>
5158
</div>
5259
</div>
5360
);

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,28 @@
44
import * as React from "react";
55
import parsers from "js/slycat-parsers";
66
import _ from "lodash";
7+
import { handleParserChange } from "../CCAWizardUtils";
78

8-
export const SlycatParserControls = () => {
9-
const filteredParsers = parsers
9+
export const SlycatParserControls = (props: {
10+
setParser: React.Dispatch<React.SetStateAction<string | undefined>>;
11+
}) => {
12+
const { setParser } = props;
13+
const filteredParsers: [{ type: () => string }] = parsers
1014
.available()
1115
?.filter((parser: { categories: () => string }) => _.includes(parser.categories(), "table"));
16+
React.useEffect(() => {
17+
if (filteredParsers !== undefined && filteredParsers.length > 0) {
18+
console.log('reset', filteredParsers[0].type());
19+
setParser(filteredParsers[0].type());
20+
}
21+
}, [filteredParsers.length]);
1222
return (
1323
<div className="form-group row">
1424
<label className="col-sm-2 col-form-label">Filetype</label>
1525
<div className="col-sm-10">
16-
<select id="slycat-model-parser" className="form-control" >
26+
<select id="slycat-model-parser" className="form-control" onChange={handleParserChange(setParser)}>
1727
{filteredParsers.map((parser: { type: () => string }) => {
18-
return <option>{parser.type()}</option>;
28+
return <option key={parser.type()}>{parser.type()}</option>;
1929
})}
2030
</select>
2131
</div>

web-server/plugins/slycat-cca/js/components/wizard-store/reducers/cCAWizardSlice.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ export interface CCAWizardState {
1414
dataLocation: dataLocationType;
1515
mid: string | undefined;
1616
pid: string | undefined;
17+
fileUploaded: boolean;
1718
}
1819
const initialState: CCAWizardState = {
1920
tab: TabNames.CCA_DATA_WIZARD_SELECTION_TAB,
2021
dataLocation: dataLocationType.LOCAL,
2122
mid: undefined,
22-
pid: undefined
23+
pid: undefined,
24+
fileUploaded: false
2325
};
2426
export const cCAWizardSlice = createSlice({
2527
name: "cCAWizard",
@@ -35,12 +37,12 @@ export const cCAWizardSlice = createSlice({
3537
state.mid = action.payload;
3638
},
3739
setPid: (state, action: PayloadAction<string>) => {
38-
// TODO: dispatch model creation if no MID present aka undefined
3940
state.pid = action.payload;
4041
},
41-
uploadFile: (state) => {
42-
console.log(`upload`);
43-
},
42+
setFileUploaded:(state, action: PayloadAction<boolean>) => {
43+
console.log("dispatching action.payload", action.payload)
44+
state.fileUploaded = action.payload;
45+
},
4446
resetCCAWizard: () => initialState,
4547
},
4648
});
@@ -51,12 +53,13 @@ export const {
5153
setDataLocation,
5254
setMid,
5355
setPid,
54-
uploadFile,
5556
resetCCAWizard: resetCCAWizard,
57+
setFileUploaded
5658
} = cCAWizardSlice.actions;
5759
// Other code such as selectors can use the imported `RootState` type
5860
export const selectTab = (state: RootState) => state.cCAWizard.tab;
5961
export const selectDataLocation = (state: RootState) => state.cCAWizard.dataLocation;
62+
export const selectFileUploaded= (state: RootState) => state.cCAWizard.fileUploaded;
6063
export const selectPid = (state: RootState) => state.cCAWizard.pid;
6164
export const selectMid = (state: RootState) => state.cCAWizard.mid;
6265

web-server/plugins/slycat-cca/js/components/wizard-tabs/CCSLocalBrowserTab.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@
33
retains certain rights in this software. */
44
import * as React from "react";
55
import { SlycatLocalBrowser } from "../slycat-local-browser/SlycatLocalBrowser";
6+
import { useSetUploadStatus } from "../CCAWizardUtils";
7+
import { useAppSelector } from "../wizard-store/hooks";
8+
import { selectFileUploaded } from "../wizard-store/reducers/cCAWizardSlice";
69

710
export const CCALocalBrowserTab = (props: { hidden?: boolean }) => {
811
const { hidden = false } = props;
12+
const fileUploaded = useAppSelector(selectFileUploaded);
13+
const setUploadStatus = useSetUploadStatus();
914
return (
1015
<div hidden={hidden}>
11-
<SlycatLocalBrowser />
16+
<SlycatLocalBrowser disabled={fileUploaded} setUploadStatus={setUploadStatus}/>
1217
</div>
1318
);
1419
};

0 commit comments

Comments
 (0)