diff --git a/src/App.js b/src/App.js index 04b4be3..1f3e394 100644 --- a/src/App.js +++ b/src/App.js @@ -9,6 +9,7 @@ import ToggleBar from "./ToggleBar"; import TripLogs from "./TripLogs"; import TaskLogs from "./TaskLogs"; import DatasetLoading from "./DatasetLoading"; +import ExtraDataSource from "./ExtraDataSource"; import { uploadFile, getUploadedData, @@ -25,7 +26,8 @@ import Utils, { log } from "./Utils"; import { toast, ToastContainer } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import { ALL_TOGGLES, getVisibleToggles } from "./MapToggles"; -import { HAS_EXTRA_DATA_SOURCE } from "./constants"; + +const HAS_EXTRA_DATA_SOURCE = ExtraDataSource.isAvailable(); const MARKER_COLORS = [ "#EA4335", // Red @@ -807,6 +809,7 @@ class App extends React.Component { onLogsReceived: handleCloudLogsReceived, onExtraLogsReceived: handleExtraLogsReceived, onFileUpload: handleFileUpload, + hasExtraDataSource: HAS_EXTRA_DATA_SOURCE, }); dialogRoot.render(datasetLoadingComponent); }); diff --git a/src/DatasetLoading.js b/src/DatasetLoading.js index 7f8e3aa..8504811 100644 --- a/src/DatasetLoading.js +++ b/src/DatasetLoading.js @@ -5,16 +5,13 @@ import ExtraDataSource from "./ExtraDataSource"; import { log } from "./Utils"; import { toast } from "react-toastify"; import { isTokenValid, fetchLogsWithToken, useCloudLoggingLogin, buildQueryFilter } from "./CloudLogging"; -import { useSheetsLogin, isSheetsTokenValid, getSheetsToken, importFromGoogleSheet } from "./GoogleSheets"; -import { HAS_EXTRA_DATA_SOURCE, GOOGLE_CLIENT_ID } from "./constants"; +import DatasetSideLoading from "./DatasetSideLoading"; +import { GOOGLE_CLIENT_ID } from "./constants"; const CloudLoggingFormComponent = ({ onLogsReceived, onFileUpload }) => { const getStoredValue = (key, defaultValue = "") => localStorage.getItem(`datasetLoading_${key}`) || defaultValue; const [fetching, setFetching] = useState(false); - const [sheetFormVisible, setSheetFormVisible] = useState(false); - const [sheetUrl, setSheetUrl] = useState(localStorage.getItem("datasetLoading_sheetUrl") || ""); - const [sheetLoading, setSheetLoading] = useState(false); const [queryParams, setQueryParams] = useState({ projectId: getStoredValue("projectId"), vehicleId: getStoredValue("vehicleId"), @@ -69,52 +66,6 @@ const CloudLoggingFormComponent = ({ onLogsReceived, onFileUpload }) => { } }; - const handleSheetImport = (token) => { - setSheetLoading(true); - setLocalError(null); - localStorage.setItem("datasetLoading_sheetUrl", sheetUrl); - - importFromGoogleSheet(sheetUrl, token) - .then((logs) => { - log(`Received ${logs.length} logs from Google Sheet`); - if (logs.length > 0) { - onLogsReceived(logs); - } else { - toast.warning("No logs found in the spreadsheet."); - } - }) - .catch((err) => { - setLocalError(`Sheet import error: ${err.message}`); - toast.error(`Sheet import error: ${err.message}`); - }) - .finally(() => setSheetLoading(false)); - }; - - const sheetsLogin = useSheetsLogin( - (token) => { - log("Sheets login successful, importing..."); - handleSheetImport(token); - }, - (err) => { - log("Sheets login failed.", err); - setLocalError(`Auth Error: ${err.error || "Unknown"}`); - setSheetLoading(false); - } - ); - - const handleSheetLoadClick = () => { - if (!sheetUrl.trim()) { - setLocalError("Please enter a spreadsheet URL or ID."); - return; - } - setLocalError(null); - if (isSheetsTokenValid()) { - handleSheetImport(getSheetsToken()); - } else { - sheetsLogin(); - } - }; - return (

Fleet Engine Logs Loading

@@ -211,56 +162,18 @@ const CloudLoggingFormComponent = ({ onLogsReceived, onFileUpload }) => {
)} -
+ - - - -
- {sheetFormVisible && ( -
-
- -
- - {sheetLoading && ( -
-
Loading from Google Sheet...
- -
- )} -
- )} + ); }; export default function DatasetLoading(props) { const [activeDataSource, setActiveDataSource] = useState( - localStorage.getItem("lastUsedDataSource") || (HAS_EXTRA_DATA_SOURCE ? "extra" : "cloudLogging") + localStorage.getItem("lastUsedDataSource") || (props.hasExtraDataSource ? "extra" : "cloudLogging") ); useEffect(() => { @@ -271,7 +184,7 @@ export default function DatasetLoading(props) { const ExtraFormComponent = isExtra ? ExtraDataSource.getFormComponent(props) : null; const renderSourceSelection = () => { - if (!HAS_EXTRA_DATA_SOURCE) { + if (!props.hasExtraDataSource) { return ; } diff --git a/src/DatasetSideLoading.js b/src/DatasetSideLoading.js new file mode 100644 index 0000000..e8dafed --- /dev/null +++ b/src/DatasetSideLoading.js @@ -0,0 +1,115 @@ +// src/DatasetSideLoading.js +import { useState } from "react"; +import { toast } from "react-toastify"; +import { useSheetsLogin, isSheetsTokenValid, getSheetsToken, importFromGoogleSheet } from "./GoogleSheets"; +import { log } from "./Utils"; + +/** + * A shared section for sidebar/sideloading logs (Google Sheets and local files). + * This handles the "Load Google Sheet" and "Load JSON or ZIP" buttons and forms. + * + * @param {Object} props + * @param {Function} props.onLogsReceived Callback when logs are received (from Sheet). + * @param {Function} props.onFileUpload Callback for file uploads. + * @param {Function} props.setLocalError Callback to set error messages in the parent. + * @param {React.ReactNode} props.children The primary fetch button(s) to show alongside sideload buttons. + */ +export const DatasetSideLoading = ({ onLogsReceived, onFileUpload, setLocalError, children }) => { + const [sheetFormVisible, setSheetFormVisible] = useState(false); + const [sheetUrl, setSheetUrl] = useState(localStorage.getItem("datasetLoading_sheetUrl") || ""); + const [sheetLoading, setSheetLoading] = useState(false); + + const handleSheetImport = (token) => { + setSheetLoading(true); + if (setLocalError) setLocalError(null); + localStorage.setItem("datasetLoading_sheetUrl", sheetUrl); + + importFromGoogleSheet(sheetUrl, token) + .then((logs) => { + log(`Received ${logs.length} logs from Google Sheet`); + if (logs.length > 0) { + onLogsReceived(logs); + } else { + toast.warning("No logs found in the spreadsheet."); + } + }) + .catch((err) => { + if (setLocalError) setLocalError(`Sheet import error: ${err.message}`); + toast.error(`Sheet import error: ${err.message}`); + }) + .finally(() => setSheetLoading(false)); + }; + + const sheetsLogin = useSheetsLogin( + (token) => { + log("Sheets login successful, importing..."); + handleSheetImport(token); + }, + (err) => { + log("Sheets login failed.", err); + if (setLocalError) setLocalError(`Auth Error: ${err.error || "Unknown"}`); + setSheetLoading(false); + } + ); + + const handleSheetLoadClick = () => { + if (!sheetUrl.trim()) { + if (setLocalError) setLocalError("Please enter a spreadsheet URL or ID."); + return; + } + if (setLocalError) setLocalError(null); + if (isSheetsTokenValid()) { + handleSheetImport(getSheetsToken()); + } else { + sheetsLogin(); + } + }; + + return ( + <> +
+ {children} + + + +
+ {sheetFormVisible && ( +
+
+ +
+ + {sheetLoading && ( +
+
Loading from Google Sheet...
+ +
+ )} +
+ )} + + ); +}; + +export default DatasetSideLoading; diff --git a/src/constants.js b/src/constants.js index 08d81ad..afd0741 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,7 +1,5 @@ // constants.js -import ExtraDataSource from "./ExtraDataSource"; export const DEFAULT_API_KEY = ""; export const DEFAULT_MAP_ID = "e6ead35a6ace8599"; -export const HAS_EXTRA_DATA_SOURCE = ExtraDataSource.isAvailable(); export const GOOGLE_CLIENT_ID = "829183678942-eq2c9cd7pjdm39l2um5thgbrvgva07e7.apps.googleusercontent.com";