Skip to content

Commit 1b154cd

Browse files
fix: split out sideloading from DatasetLoading to make it importable (#289) f6a683a
1 parent dc30b1a commit 1b154cd

File tree

4 files changed

+125
-96
lines changed

4 files changed

+125
-96
lines changed

src/App.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import ToggleBar from "./ToggleBar";
99
import TripLogs from "./TripLogs";
1010
import TaskLogs from "./TaskLogs";
1111
import DatasetLoading from "./DatasetLoading";
12+
import ExtraDataSource from "./ExtraDataSource";
1213
import {
1314
uploadFile,
1415
getUploadedData,
@@ -25,7 +26,8 @@ import Utils, { log } from "./Utils";
2526
import { toast, ToastContainer } from "react-toastify";
2627
import "react-toastify/dist/ReactToastify.css";
2728
import { ALL_TOGGLES, getVisibleToggles } from "./MapToggles";
28-
import { HAS_EXTRA_DATA_SOURCE } from "./constants";
29+
30+
const HAS_EXTRA_DATA_SOURCE = ExtraDataSource.isAvailable();
2931

3032
const MARKER_COLORS = [
3133
"#EA4335", // Red
@@ -807,6 +809,7 @@ class App extends React.Component {
807809
onLogsReceived: handleCloudLogsReceived,
808810
onExtraLogsReceived: handleExtraLogsReceived,
809811
onFileUpload: handleFileUpload,
812+
hasExtraDataSource: HAS_EXTRA_DATA_SOURCE,
810813
});
811814
dialogRoot.render(datasetLoadingComponent);
812815
});

src/DatasetLoading.js

Lines changed: 6 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,13 @@ import ExtraDataSource from "./ExtraDataSource";
55
import { log } from "./Utils";
66
import { toast } from "react-toastify";
77
import { isTokenValid, fetchLogsWithToken, useCloudLoggingLogin, buildQueryFilter } from "./CloudLogging";
8-
import { useSheetsLogin, isSheetsTokenValid, getSheetsToken, importFromGoogleSheet } from "./GoogleSheets";
9-
import { HAS_EXTRA_DATA_SOURCE, GOOGLE_CLIENT_ID } from "./constants";
8+
import DatasetSideLoading from "./DatasetSideLoading";
9+
import { GOOGLE_CLIENT_ID } from "./constants";
1010

1111
const CloudLoggingFormComponent = ({ onLogsReceived, onFileUpload }) => {
1212
const getStoredValue = (key, defaultValue = "") => localStorage.getItem(`datasetLoading_${key}`) || defaultValue;
1313

1414
const [fetching, setFetching] = useState(false);
15-
const [sheetFormVisible, setSheetFormVisible] = useState(false);
16-
const [sheetUrl, setSheetUrl] = useState(localStorage.getItem("datasetLoading_sheetUrl") || "");
17-
const [sheetLoading, setSheetLoading] = useState(false);
1815
const [queryParams, setQueryParams] = useState({
1916
projectId: getStoredValue("projectId"),
2017
vehicleId: getStoredValue("vehicleId"),
@@ -69,52 +66,6 @@ const CloudLoggingFormComponent = ({ onLogsReceived, onFileUpload }) => {
6966
}
7067
};
7168

72-
const handleSheetImport = (token) => {
73-
setSheetLoading(true);
74-
setLocalError(null);
75-
localStorage.setItem("datasetLoading_sheetUrl", sheetUrl);
76-
77-
importFromGoogleSheet(sheetUrl, token)
78-
.then((logs) => {
79-
log(`Received ${logs.length} logs from Google Sheet`);
80-
if (logs.length > 0) {
81-
onLogsReceived(logs);
82-
} else {
83-
toast.warning("No logs found in the spreadsheet.");
84-
}
85-
})
86-
.catch((err) => {
87-
setLocalError(`Sheet import error: ${err.message}`);
88-
toast.error(`Sheet import error: ${err.message}`);
89-
})
90-
.finally(() => setSheetLoading(false));
91-
};
92-
93-
const sheetsLogin = useSheetsLogin(
94-
(token) => {
95-
log("Sheets login successful, importing...");
96-
handleSheetImport(token);
97-
},
98-
(err) => {
99-
log("Sheets login failed.", err);
100-
setLocalError(`Auth Error: ${err.error || "Unknown"}`);
101-
setSheetLoading(false);
102-
}
103-
);
104-
105-
const handleSheetLoadClick = () => {
106-
if (!sheetUrl.trim()) {
107-
setLocalError("Please enter a spreadsheet URL or ID.");
108-
return;
109-
}
110-
setLocalError(null);
111-
if (isSheetsTokenValid()) {
112-
handleSheetImport(getSheetsToken());
113-
} else {
114-
sheetsLogin();
115-
}
116-
};
117-
11869
return (
11970
<div className="cloud-logging-form">
12071
<h3>Fleet Engine Logs Loading</h3>
@@ -211,56 +162,18 @@ const CloudLoggingFormComponent = ({ onLogsReceived, onFileUpload }) => {
211162
<progress className="progress-bar" />
212163
</div>
213164
)}
214-
<div className="cloud-logging-buttons">
165+
<DatasetSideLoading onLogsReceived={onLogsReceived} onFileUpload={onFileUpload} setLocalError={setLocalError}>
215166
<button type="button" onClick={handleFetch} disabled={fetching} className="fetch-logs-button">
216167
{fetching ? "Fetching..." : isTokenValid() ? "Fetch Logs" : "Sign in and Fetch Logs"}
217168
</button>
218-
<button type="button" onClick={() => setSheetFormVisible(!sheetFormVisible)} className="sideload-logs-button">
219-
Load Google Sheet
220-
</button>
221-
<label htmlFor="fileUploadInput" className="sideload-logs-button">
222-
Load JSON or ZIP
223-
</label>
224-
<input type="file" id="fileUploadInput" accept=".json,.zip" onChange={onFileUpload} className="file-input" />
225-
</div>
226-
{sheetFormVisible && (
227-
<div className="google-sheet-form">
228-
<div className="form-field">
229-
<label className="form-label">
230-
Spreadsheet URL or ID:
231-
<input
232-
type="text"
233-
value={sheetUrl}
234-
onChange={(e) => setSheetUrl(e.target.value)}
235-
placeholder="https://docs.google.com/spreadsheets/d/... or spreadsheet ID"
236-
className="form-input"
237-
/>
238-
</label>
239-
</div>
240-
<button
241-
type="button"
242-
onClick={handleSheetLoadClick}
243-
disabled={sheetLoading}
244-
className="fetch-logs-button"
245-
style={{ marginTop: "8px" }}
246-
>
247-
{sheetLoading ? "Loading..." : isSheetsTokenValid() ? "Load Sheet" : "Sign in and Load Sheet"}
248-
</button>
249-
{sheetLoading && (
250-
<div className="progress-indicator">
251-
<div>Loading from Google Sheet...</div>
252-
<progress className="progress-bar" />
253-
</div>
254-
)}
255-
</div>
256-
)}
169+
</DatasetSideLoading>
257170
</div>
258171
);
259172
};
260173

261174
export default function DatasetLoading(props) {
262175
const [activeDataSource, setActiveDataSource] = useState(
263-
localStorage.getItem("lastUsedDataSource") || (HAS_EXTRA_DATA_SOURCE ? "extra" : "cloudLogging")
176+
localStorage.getItem("lastUsedDataSource") || (props.hasExtraDataSource ? "extra" : "cloudLogging")
264177
);
265178

266179
useEffect(() => {
@@ -271,7 +184,7 @@ export default function DatasetLoading(props) {
271184
const ExtraFormComponent = isExtra ? ExtraDataSource.getFormComponent(props) : null;
272185

273186
const renderSourceSelection = () => {
274-
if (!HAS_EXTRA_DATA_SOURCE) {
187+
if (!props.hasExtraDataSource) {
275188
return <button className="active static">Cloud Logging</button>;
276189
}
277190

src/DatasetSideLoading.js

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// src/DatasetSideLoading.js
2+
import { useState } from "react";
3+
import { toast } from "react-toastify";
4+
import { useSheetsLogin, isSheetsTokenValid, getSheetsToken, importFromGoogleSheet } from "./GoogleSheets";
5+
import { log } from "./Utils";
6+
7+
/**
8+
* A shared section for sidebar/sideloading logs (Google Sheets and local files).
9+
* This handles the "Load Google Sheet" and "Load JSON or ZIP" buttons and forms.
10+
*
11+
* @param {Object} props
12+
* @param {Function} props.onLogsReceived Callback when logs are received (from Sheet).
13+
* @param {Function} props.onFileUpload Callback for file uploads.
14+
* @param {Function} props.setLocalError Callback to set error messages in the parent.
15+
* @param {React.ReactNode} props.children The primary fetch button(s) to show alongside sideload buttons.
16+
*/
17+
export const DatasetSideLoading = ({ onLogsReceived, onFileUpload, setLocalError, children }) => {
18+
const [sheetFormVisible, setSheetFormVisible] = useState(false);
19+
const [sheetUrl, setSheetUrl] = useState(localStorage.getItem("datasetLoading_sheetUrl") || "");
20+
const [sheetLoading, setSheetLoading] = useState(false);
21+
22+
const handleSheetImport = (token) => {
23+
setSheetLoading(true);
24+
if (setLocalError) setLocalError(null);
25+
localStorage.setItem("datasetLoading_sheetUrl", sheetUrl);
26+
27+
importFromGoogleSheet(sheetUrl, token)
28+
.then((logs) => {
29+
log(`Received ${logs.length} logs from Google Sheet`);
30+
if (logs.length > 0) {
31+
onLogsReceived(logs);
32+
} else {
33+
toast.warning("No logs found in the spreadsheet.");
34+
}
35+
})
36+
.catch((err) => {
37+
if (setLocalError) setLocalError(`Sheet import error: ${err.message}`);
38+
toast.error(`Sheet import error: ${err.message}`);
39+
})
40+
.finally(() => setSheetLoading(false));
41+
};
42+
43+
const sheetsLogin = useSheetsLogin(
44+
(token) => {
45+
log("Sheets login successful, importing...");
46+
handleSheetImport(token);
47+
},
48+
(err) => {
49+
log("Sheets login failed.", err);
50+
if (setLocalError) setLocalError(`Auth Error: ${err.error || "Unknown"}`);
51+
setSheetLoading(false);
52+
}
53+
);
54+
55+
const handleSheetLoadClick = () => {
56+
if (!sheetUrl.trim()) {
57+
if (setLocalError) setLocalError("Please enter a spreadsheet URL or ID.");
58+
return;
59+
}
60+
if (setLocalError) setLocalError(null);
61+
if (isSheetsTokenValid()) {
62+
handleSheetImport(getSheetsToken());
63+
} else {
64+
sheetsLogin();
65+
}
66+
};
67+
68+
return (
69+
<>
70+
<div className="cloud-logging-buttons">
71+
{children}
72+
<button type="button" onClick={() => setSheetFormVisible(!sheetFormVisible)} className="sideload-logs-button">
73+
Load Google Sheet
74+
</button>
75+
<label htmlFor="fileUploadInput" className="sideload-logs-button">
76+
Load JSON or ZIP
77+
</label>
78+
<input type="file" id="fileUploadInput" accept=".json,.zip" onChange={onFileUpload} className="file-input" />
79+
</div>
80+
{sheetFormVisible && (
81+
<div className="google-sheet-form">
82+
<div className="form-field">
83+
<label className="form-label">
84+
Spreadsheet URL or ID:
85+
<input
86+
type="text"
87+
value={sheetUrl}
88+
onChange={(e) => setSheetUrl(e.target.value)}
89+
placeholder="https://docs.google.com/spreadsheets/d/... or spreadsheet ID"
90+
className="form-input"
91+
/>
92+
</label>
93+
</div>
94+
<button
95+
type="button"
96+
onClick={handleSheetLoadClick}
97+
disabled={sheetLoading}
98+
className="fetch-logs-button"
99+
style={{ marginTop: "8px" }}
100+
>
101+
{sheetLoading ? "Loading..." : isSheetsTokenValid() ? "Load Sheet" : "Sign in and Load Sheet"}
102+
</button>
103+
{sheetLoading && (
104+
<div className="progress-indicator">
105+
<div>Loading from Google Sheet...</div>
106+
<progress className="progress-bar" />
107+
</div>
108+
)}
109+
</div>
110+
)}
111+
</>
112+
);
113+
};
114+
115+
export default DatasetSideLoading;

src/constants.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
// constants.js
2-
import ExtraDataSource from "./ExtraDataSource";
32

43
export const DEFAULT_API_KEY = "";
54
export const DEFAULT_MAP_ID = "e6ead35a6ace8599";
6-
export const HAS_EXTRA_DATA_SOURCE = ExtraDataSource.isAvailable();
75
export const GOOGLE_CLIENT_ID = "829183678942-eq2c9cd7pjdm39l2um5thgbrvgva07e7.apps.googleusercontent.com";

0 commit comments

Comments
 (0)