Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9,920 changes: 3,990 additions & 5,930 deletions package-lock.json

Large diffs are not rendered by default.

44 changes: 22 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,47 +15,47 @@
},
"homepage": ".",
"dependencies": {
"@google-cloud/bigquery": "^6.0.0",
"@google-cloud/bigquery": "^7.8.0",
"@react-oauth/google": "^0.12.1",
"@testing-library/jest-dom": "^5.14.1",
"@turf/turf": "^7.2.0",
"@testing-library/jest-dom": "^6.4.6",
"@turf/turf": "^6.5.0",
"@vis.gl/react-google-maps": "^1.5.2",
"axios": "^1.7.4",
"axios": "^1.7.2",
"express": "^4.19.2",
"googleapis": "^89.0.0",
"googleapis": "^140.0.1",
"jszip": "^3.10.1",
"lodash": "^4.17.21",
"open": "^8.3.0",
"query-string": "^7.1.0",
"rc-slider": "^9.7.4",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"open": "^10.1.0",
"query-string": "^9.0.0",
"rc-slider": "^11.1.8",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-json-view": "^1.21.3",
"react-scripts": "5.0.1",
"react-table": "^7.7.0",
"react-toastify": "^9.0.3",
"react-table": "^7.8.0",
"react-toastify": "^10.0.5",
"react-virtualized-auto-sizer": "^1.0.24",
"react-window": "^1.8.10",
"s2polyline-ts": "^1.0.0",
"webpack": "5.94.0",
"yargs": "^17.2.1"
"yargs": "^17.7.2"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.25.1",
"@babel/plugin-transform-class-properties": "^7.24.7",
"@babel/preset-react": "^7.24.7",
"@typescript-eslint/eslint-plugin": "^4.29.3",
"@typescript-eslint/parser": "^4.29.3",
"@typescript-eslint/eslint-plugin": "^7.16.0",
"@typescript-eslint/parser": "^7.16.0",
"cross-env": "^7.0.3",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.10.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-jest": "^25.2.2",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-jest": "^28.6.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.35.0",
"prettier": "^2.8.8",
"typescript": "^4.4.4"
"prettier": "^3.3.3",
"typescript": "^5.5.3"
},
"scripts": {
"start": "react-scripts start",
Expand Down Expand Up @@ -97,4 +97,4 @@
"last 1 safari version"
]
}
}
}
54 changes: 31 additions & 23 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// src/App.js
import ReactDOM from "react-dom";
import React from "react";
import { createRoot } from "react-dom/client";
import Map from "./Map";
import Dataframe from "./Dataframe";
import TimeSlider from "./TimeSlider";
Expand Down Expand Up @@ -410,7 +410,9 @@ class App extends React.Component {
checkForDemoFile = async () => {
try {
const response = await fetch("./data.json");
if (!response.ok) {
const contentType = response.headers.get("content-type");

if (!response.ok || !contentType || !contentType.includes("application/json")) {
return;
}
console.log("data.json demo file found on the server root, saving it to Dataset 1");
Expand Down Expand Up @@ -455,15 +457,19 @@ class App extends React.Component {
return { status: null, index };
})
);
this.setState({
uploadedDatasets: newUploadedDatasets.map((d) => d.status),
});
if (this.state.activeDatasetIndex === null) {
const firstAvailableIndex = newUploadedDatasets.find((dataset) => dataset.status === "Uploaded")?.index;
if (firstAvailableIndex !== undefined) {
this.switchDataset(firstAvailableIndex);
this.setState(
{
uploadedDatasets: newUploadedDatasets.map((d) => d.status),
},
() => {
if (this.state.activeDatasetIndex === null) {
const firstAvailableIndex = newUploadedDatasets.find((dataset) => dataset.status === "Uploaded")?.index;
if (firstAvailableIndex !== undefined) {
this.switchDataset(firstAvailableIndex);
}
}
}
}
);
};

handleLongPress = async (index) => {
Expand Down Expand Up @@ -723,43 +729,45 @@ class App extends React.Component {
dialog.className = "cloud-logging-dialog";

document.body.appendChild(dialog);
const dialogRootElement = document.createElement("div");
dialog.appendChild(dialogRootElement);
const dialogRoot = createRoot(dialogRootElement);
dialog.showModal();
return new Promise((resolve) => {
const cleanupAndResolve = (result) => {
dialogRoot.unmount();
dialog.remove();
resolve(result);
};
const handleError = (error) => {
console.error("Cloud Logging Error:", error);
toast.error(error.message || "Failed to fetch logs. Please try again.");
dialog.remove();
resolve(null);
cleanupAndResolve(null);
};

const handleFileUpload = (event) => {
log("File upload selected from Cloud Logging dialog");
console.log("File upload selected from Cloud Logging dialog");
const file = event?.target?.files?.[0];
if (file) {
dialog.remove();
resolve({ file });
cleanupAndResolve({ file });
}
};

// Using direct DOM manipulation instead of ReactDOM.render to avoid React 17 issues
const root = document.createElement("div");
dialog.appendChild(root);

const cloudLogging = React.createElement(CloudLogging, {
const cloudLoggingComponent = React.createElement(CloudLogging, {
onLogsReceived: (logs) => {
log(`Received ${logs.length} logs from Cloud Logging`);
dialog.remove();
if (logs.length === 0) {
toast.warning("No logs found matching your criteria.");
resolve(null);
cleanupAndResolve(null);
} else {
resolve({ logs });
cleanupAndResolve({ logs });
}
},
onFileUpload: handleFileUpload,
setError: handleError,
});
ReactDOM.render(cloudLogging, root);
dialogRoot.render(cloudLoggingComponent);
});
}

Expand Down
9 changes: 6 additions & 3 deletions src/CloudLogging.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,12 @@ const CloudLoggingForm = ({ onLogsReceived, onFileUpload }) => {
if (error.message.includes("Failed to fetch") && retryCount < 2) {
log(`Network error, retrying (attempt ${retryCount + 1})...`);
return new Promise((resolve) => {
setTimeout(() => {
resolve(fetchLogBatch(token, filter, pageToken, retryCount + 1));
}, 1000 * (retryCount + 1)); // Exponential backoff
setTimeout(
() => {
resolve(fetchLogBatch(token, filter, pageToken, retryCount + 1));
},
1000 * (retryCount + 1) // Exponential backoff
);
});
}
throw error;
Expand Down
73 changes: 43 additions & 30 deletions src/LogTable.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// src/LogTable.js

import React, { useState } from "react";
import { useSortBy, useTable } from "react-table";
import { FixedSizeList as List } from "react-window";
Expand Down Expand Up @@ -59,15 +58,18 @@ function Table({ columns, data, onSelectionChange, listRef, selectedRow, centerO
}
};

const { key, ...restRowProps } = row.getRowProps({
style: {
...style,
pointerEvents: "auto",
color: hasError ? "darkred" : "inherit",
},
});

return (
<div
{...row.getRowProps({
style: {
...style,
pointerEvents: "auto",
color: hasError ? "darkred" : "inherit",
},
})}
key={key}
{...restRowProps}
className={`logtable-row ${selectedRow === index ? "selected" : ""}`}
onMouseDown={startPressTimer}
onMouseUp={() => {
Expand All @@ -85,15 +87,19 @@ function Table({ columns, data, onSelectionChange, listRef, selectedRow, centerO
}
}}
>
{row.cells.map((cell) => (
<div
{...cell.getCellProps()}
className={`logtable-cell ${cell.column.className || ""}`}
style={{ width: cell.column.width }}
>
{cell.render("Cell")}
</div>
))}
{row.cells.map((cell) => {
const { key, ...restCellProps } = cell.getCellProps();
return (
<div
key={key}
{...restCellProps}
className={`logtable-cell ${cell.column.className || ""}`}
style={{ width: cell.column.width }}
>
{cell.render("Cell")}
</div>
);
})}
</div>
);
},
Expand All @@ -113,19 +119,26 @@ function Table({ columns, data, onSelectionChange, listRef, selectedRow, centerO
<div>
<div {...getTableProps()}>
<div>
{headerGroups.map((headerGroup) => (
<div {...headerGroup.getHeaderGroupProps()} className="logtable-header-row">
{headerGroup.headers.map((column) => (
<div
{...column.getHeaderProps()}
className={`logtable-header-cell ${column.className || ""}`}
style={{ width: column.width }}
>
{column.render("Header")}
</div>
))}
</div>
))}
{headerGroups.map((headerGroup) => {
const { key, ...restHeaderGroupProps } = headerGroup.getHeaderGroupProps();
return (
<div key={key} {...restHeaderGroupProps} className="logtable-header-row">
{headerGroup.headers.map((column) => {
const { key, ...restColumnProps } = column.getHeaderProps();
return (
<div
key={key}
{...restColumnProps}
className={`logtable-header-cell ${column.className || ""}`}
style={{ width: column.width }}
>
{column.render("Header")}
</div>
);
})}
</div>
);
})}
</div>
<div {...getTableBodyProps()}>
<List
Expand Down
8 changes: 6 additions & 2 deletions src/Map.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function initializeMapObject(element) {
});
const jsMapView = new window.google.maps.journeySharing.JourneySharingMapView({
element: element,
locationProvider,
locationProviders: [locationProvider],
mapOptions: {
mapId: mapId,
mapTypeControl: true,
Expand Down Expand Up @@ -142,7 +142,11 @@ function MyMapComponent(props) {
map.addListener(
"center_changed",
_.debounce(() => {
setQueryStringValue("center", JSON.stringify(map.getCenter().toJSON()));
const center = map.getCenter();
if (center) {
console.log("center_changed event fired, updating query string.");
setQueryStringValue("center", JSON.stringify(center.toJSON()));
}
}, 100)
);

Expand Down
9 changes: 4 additions & 5 deletions src/TimeSlider.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@
* Provides a time-based visualization of key events (vehicle status changes) as well
* as filtering control for the log viewer & map view.
*/
import Slider from "rc-slider";
const Slider = require("rc-slider").default;
import { useMemo, useRef, useEffect, useState } from "react";
import "rc-slider/assets/index.css";
import _ from "lodash";
import { log } from "./Utils";

const { createSliderWithTooltip } = Slider;
const Range = createSliderWithTooltip(Slider.Range);

const style = { width: "100%" };

function TimeSlider(props) {
Expand Down Expand Up @@ -127,6 +124,7 @@ function TimeSlider(props) {
container.appendChild(overlay);

const handleOverlayClick = (e) => {
if (isDragging) return;
const rect = container.getBoundingClientRect();
const totalWidth = rect.width;
const clickPosition = e.clientX - rect.left;
Expand Down Expand Up @@ -188,7 +186,8 @@ function TimeSlider(props) {

return (
<div style={style} ref={sliderContainerRef}>
<Range
<Slider
range
min={minVal}
max={maxVal}
marks={marks}
Expand Down
Loading
Loading