@@ -5,12 +5,16 @@ import ExtraDataSource from "./ExtraDataSource";
55import { log } from "./Utils" ;
66import { toast } from "react-toastify" ;
77import { isTokenValid , fetchLogsWithToken , useCloudLoggingLogin , buildQueryFilter } from "./CloudLogging" ;
8- import { HAS_EXTRA_DATA_SOURCE } from "./constants" ;
8+ import { useSheetsLogin , isSheetsTokenValid , getSheetsToken , importFromGoogleSheet } from "./GoogleSheets" ;
9+ import { HAS_EXTRA_DATA_SOURCE , GOOGLE_CLIENT_ID } from "./constants" ;
910
1011const CloudLoggingFormComponent = ( { onLogsReceived, onFileUpload } ) => {
1112 const getStoredValue = ( key , defaultValue = "" ) => localStorage . getItem ( `datasetLoading_${ key } ` ) || defaultValue ;
1213
1314 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 ) ;
1418 const [ queryParams , setQueryParams ] = useState ( {
1519 projectId : getStoredValue ( "projectId" ) ,
1620 vehicleId : getStoredValue ( "vehicleId" ) ,
@@ -65,6 +69,52 @@ const CloudLoggingFormComponent = ({ onLogsReceived, onFileUpload }) => {
6569 }
6670 } ;
6771
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+
68118 return (
69119 < div className = "cloud-logging-form" >
70120 < h3 > Fleet Engine Logs Loading</ h3 >
@@ -162,14 +212,48 @@ const CloudLoggingFormComponent = ({ onLogsReceived, onFileUpload }) => {
162212 </ div >
163213 ) }
164214 < div className = "cloud-logging-buttons" >
165- < button type = "button" onClick = { handleFetch } disabled = { fetching } className = "primary -button" >
215+ < button type = "button" onClick = { handleFetch } disabled = { fetching } className = "fetch-logs -button" >
166216 { fetching ? "Fetching..." : isTokenValid ( ) ? "Fetch Logs" : "Sign in and Fetch Logs" }
167217 </ button >
168- < label htmlFor = "fileUploadInput" className = "secondary-button" >
169- Load JSON or ZIP file instead
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
170223 </ label >
171224 < input type = "file" id = "fileUploadInput" accept = ".json,.zip" onChange = { onFileUpload } className = "file-input" />
172225 </ 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+ ) }
173257 </ div >
174258 ) ;
175259} ;
@@ -210,7 +294,7 @@ export default function DatasetLoading(props) {
210294 { isExtra ? (
211295 ExtraFormComponent
212296 ) : (
213- < GoogleOAuthProvider clientId = "829183678942-eq2c9cd7pjdm39l2um5thgbrvgva07e7.apps.googleusercontent.com" >
297+ < GoogleOAuthProvider clientId = { GOOGLE_CLIENT_ID } >
214298 < CloudLoggingFormComponent { ...props } />
215299 </ GoogleOAuthProvider >
216300 ) }
0 commit comments