diff --git a/src/App.js b/src/App.js
index dac0888..0605288 100644
--- a/src/App.js
+++ b/src/App.js
@@ -24,6 +24,7 @@ import { 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 MARKER_COLORS = [
"#EA4335", // Red
@@ -414,6 +415,22 @@ class App extends React.Component {
const data = await getUploadedData(index);
log(`Dataset ${index}:`, data);
if (data && data.rawLogs && Array.isArray(data.rawLogs) && data.rawLogs.length > 0) {
+ if (HAS_EXTRA_DATA_SOURCE && data.retentionDate) {
+ const retentionDate = new Date(data.retentionDate);
+ if (retentionDate <= new Date()) {
+ log(`Startup: Dataset ${index} expired. Deleting...`);
+ await deleteUploadedData(index);
+ log(`Dataset ${index + 1} has expired and was deleted.`, "error");
+ return { status: null, index };
+ } else {
+ const now = new Date();
+ const timeLeftMs = retentionDate - now;
+ const daysLeft = timeLeftMs / (1000 * 60 * 60 * 24);
+ if (daysLeft <= 10) {
+ log(`Dataset ${index + 1} will expire in ${Math.ceil(daysLeft)} days.`, "warn");
+ }
+ }
+ }
return { status: "Uploaded", index };
}
return { status: null, index };
@@ -786,8 +803,48 @@ class App extends React.Component {
}
};
+ checkAndEnforceTTL = async (index) => {
+ if (!HAS_EXTRA_DATA_SOURCE) return "Valid";
+
+ try {
+ const data = await getUploadedData(index);
+ if (!data || !data.retentionDate) return "Valid";
+
+ const retentionDate = new Date(data.retentionDate);
+ const now = new Date();
+ const timeLeftMs = retentionDate - now;
+ const daysLeft = timeLeftMs / (1000 * 60 * 60 * 24);
+
+ if (timeLeftMs <= 0) {
+ log(`Dataset ${index} expired. Deleting...`);
+ await deleteUploadedData(index);
+ this.setState((prevState) => {
+ const newUploadedDatasets = [...prevState.uploadedDatasets];
+ newUploadedDatasets[index] = null;
+ return {
+ uploadedDatasets: newUploadedDatasets,
+ activeDatasetIndex: prevState.activeDatasetIndex === index ? null : prevState.activeDatasetIndex,
+ };
+ });
+ log(`Dataset ${index + 1} has expired and was deleted (Retention limit reached).`, "error");
+ return "Expired";
+ } else if (daysLeft <= 10) {
+ log(`Dataset ${index + 1} will expire in ${Math.ceil(daysLeft)} days.`, "warn");
+ return "Warning";
+ }
+ return "Valid";
+ } catch (e) {
+ console.error("Error verifying TTL:", e);
+ return "Error";
+ }
+ };
+
switchDataset = async (index) => {
log(`Attempting to switch to dataset ${index}`);
+
+ const ttlStatus = await this.checkAndEnforceTTL(index);
+ if (ttlStatus === "Expired") return;
+
if (this.state.uploadedDatasets[index] !== "Uploaded") {
console.error(`Attempted to switch to dataset ${index}, but it's not uploaded or is empty`);
return;
diff --git a/src/DatasetLoading.js b/src/DatasetLoading.js
index 3714348..984f662 100644
--- a/src/DatasetLoading.js
+++ b/src/DatasetLoading.js
@@ -6,11 +6,7 @@ import { log } from "./Utils";
import { toast, ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { isTokenValid, fetchLogsWithToken, useCloudLoggingLogin, buildQueryFilter } from "./CloudLogging";
-
-const DATA_SOURCES = {
- CLOUD_LOGGING: "cloudLogging",
- EXTRA: "extra",
-};
+import { HAS_EXTRA_DATA_SOURCE } from "./constants";
const CloudLoggingFormComponent = ({ onLogsReceived, onFileUpload }) => {
const getStoredValue = (key, defaultValue = "") => localStorage.getItem(`datasetLoading_${key}`) || defaultValue;
@@ -181,38 +177,37 @@ const CloudLoggingFormComponent = ({ onLogsReceived, onFileUpload }) => {
export default function DatasetLoading(props) {
const [activeDataSource, setActiveDataSource] = useState(
- localStorage.getItem("datasetLoading_dataSource") ||
- (ExtraDataSource.isAvailable() ? DATA_SOURCES.EXTRA : DATA_SOURCES.CLOUD_LOGGING)
+ localStorage.getItem("lastUsedDataSource") || (HAS_EXTRA_DATA_SOURCE ? "extra" : "cloudLogging")
);
useEffect(() => {
- localStorage.setItem("datasetLoading_dataSource", activeDataSource);
+ localStorage.setItem("lastUsedDataSource", activeDataSource);
}, [activeDataSource]);
- const isExtra = activeDataSource === DATA_SOURCES.EXTRA;
+ const isExtra = activeDataSource === "extra";
const ExtraFormComponent = isExtra ? ExtraDataSource.getFormComponent(props) : null;
- const isExtraAvailable = ExtraDataSource.isAvailable();
+
+ const renderSourceSelection = () => {
+ if (!HAS_EXTRA_DATA_SOURCE) {
+ return ;
+ }
+
+ return (
+ <>
+
+
+ >
+ );
+ };
return (
<>