From f8e642681f33f51ed76316d5ed9e1cabd1e31d46 Mon Sep 17 00:00:00 2001 From: regeter <2320305+regeter@users.noreply.github.com> Date: Fri, 26 Dec 2025 16:05:21 -0800 Subject: [PATCH] fix: dataset TTL sync, toast failures, and retention persistence --- src/App.js | 15 ++++++++++++++- src/DatasetLoading.js | 4 +--- src/localStorage.js | 7 ++++--- src/localStorage.test.js | 15 +++++++++++++++ 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/App.js b/src/App.js index c3b54d5..9535920 100644 --- a/src/App.js +++ b/src/App.js @@ -808,7 +808,20 @@ class App extends React.Component { try { const data = await getUploadedData(index); - if (!data || !data.retentionDate) return "Valid"; + if (!data) { + log(`Dataset ${index + 1} not found in storage. It may have expired or been deleted.`, "error"); + this.setState((prevState) => { + const newUploadedDatasets = [...prevState.uploadedDatasets]; + newUploadedDatasets[index] = null; + return { + uploadedDatasets: newUploadedDatasets, + activeDatasetIndex: prevState.activeDatasetIndex === index ? null : prevState.activeDatasetIndex, + }; + }); + return "Expired"; + } + + if (!data.retentionDate) return "Valid"; const retentionDate = new Date(data.retentionDate); const now = new Date(); diff --git a/src/DatasetLoading.js b/src/DatasetLoading.js index 984f662..7878efb 100644 --- a/src/DatasetLoading.js +++ b/src/DatasetLoading.js @@ -3,8 +3,7 @@ import { useState, useEffect } from "react"; import { GoogleOAuthProvider } from "@react-oauth/google"; import ExtraDataSource from "./ExtraDataSource"; import { log } from "./Utils"; -import { toast, ToastContainer } from "react-toastify"; -import "react-toastify/dist/ReactToastify.css"; +import { toast } from "react-toastify"; import { isTokenValid, fetchLogsWithToken, useCloudLoggingLogin, buildQueryFilter } from "./CloudLogging"; import { HAS_EXTRA_DATA_SOURCE } from "./constants"; @@ -206,7 +205,6 @@ export default function DatasetLoading(props) { return ( <> -
{renderSourceSelection()}
{isExtra ? ( diff --git a/src/localStorage.js b/src/localStorage.js index 6002c7e..2dae3c0 100644 --- a/src/localStorage.js +++ b/src/localStorage.js @@ -260,9 +260,10 @@ export function ensureCorrectFormat(data) { if (!Array.isArray(data)) { // If it's already in the correct format, return it as is, BUT RE-CALCULATE TTL for grace period. if (data && data.rawLogs && Array.isArray(data.rawLogs)) { + const calculatedTTL = calculateRetentionDate(data.rawLogs); return { ...data, - retentionDate: calculateRetentionDate(data.rawLogs), + retentionDate: data.retentionDate > calculatedTTL ? data.retentionDate : calculatedTTL, APIKEY: data.APIKEY || DEFAULT_API_KEY, }; } else { @@ -364,7 +365,7 @@ export function ensureCorrectFormat(data) { if (!hasPoints) log("Bounds Calculation Failed: Could not find vehicle location data in any row."); // Calculate retention date using the helper - const retentionDateIdentifier = calculateRetentionDate(logsArray); + const calculatedTTL = calculateRetentionDate(logsArray); return { APIKEY: DEFAULT_API_KEY, @@ -374,7 +375,7 @@ export function ensureCorrectFormat(data) { solutionType: solutionType, rawLogs: fullyNormalizedLogs, bounds: hasPoints ? bounds : null, - retentionDate: retentionDateIdentifier, + retentionDate: data.retentionDate > calculatedTTL ? data.retentionDate : calculatedTTL, }; } diff --git a/src/localStorage.test.js b/src/localStorage.test.js index c6c3fe3..014ccb1 100644 --- a/src/localStorage.test.js +++ b/src/localStorage.test.js @@ -274,4 +274,19 @@ describe("ensureCorrectFormat TTL Logic", () => { expect(result.retentionDate).not.toBe(staleDate); expect(retention).toBeGreaterThanOrEqual(expectedMin - 1000); }); + + it("should pick the 1h grace period if existing future TTL is less than 1h", () => { + const thirtyMinFuture = new Date(Date.now() + 30 * 60 * 1000).toISOString(); + const mockExportedFile = { + rawLogs: [{ timestamp: new Date(Date.now() - 100 * ONE_DAY_MS).toISOString(), jsonPayload: { test: 1 } }], + retentionDate: thirtyMinFuture, + }; + + const result = ensureCorrectFormat(mockExportedFile); + const retention = new Date(result.retentionDate).getTime(); + const expectedMin = Date.now() + ONE_HOUR_MS; + + expect(result.retentionDate).not.toBe(thirtyMinFuture); + expect(retention).toBeGreaterThanOrEqual(expectedMin - 1000); + }); });