From 8851ccf11c83536f1d98a00d1ddcac4e5482b04d Mon Sep 17 00:00:00 2001 From: Cannon Lock Date: Tue, 3 Dec 2024 15:53:18 -0600 Subject: [PATCH 1/6] Add a refresh interval to the origin exports - UI and UI backing updates to make sure its up to date --- .../frontend/components/DataExportTable.tsx | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/web_ui/frontend/components/DataExportTable.tsx b/web_ui/frontend/components/DataExportTable.tsx index a9a46748c..442f6b292 100644 --- a/web_ui/frontend/components/DataExportTable.tsx +++ b/web_ui/frontend/components/DataExportTable.tsx @@ -12,7 +12,7 @@ import { Pagination, Paper, Alert, - IconButton, + IconButton, LinearProgress, } from '@mui/material'; import React, { ReactElement, useEffect, useMemo, useState } from 'react'; import { Skeleton } from '@mui/material'; @@ -22,6 +22,7 @@ import useSWR from 'swr'; import { getErrorMessage } from '@/helpers/util'; import { Capabilities } from '@/types'; import { CapabilitiesDisplay } from '@/components'; +import CircularProgress from '@mui/material/CircularProgress'; type RegistrationStatus = | 'Not Supported' @@ -351,11 +352,19 @@ export const getExportData = async (): Promise => { }; export const DataExportTable = ({ boxProps }: { boxProps?: BoxProps }) => { - const [fromUrl, setFromUrl] = useState(undefined); - const { data, error } = useSWR('getDataExport', getExportData); + const [pending, setPending] = useState(false); + const [ fromUrl, setFromUrl ] = useState(undefined); + const { data, error, mutate } = useSWR('getDataExport', getExportData, { + refreshInterval: 10000 + }); useEffect(() => { setFromUrl(window.location.href); + setPending(true); + setTimeout(() => { + mutate() + setPending(false); + }, 5000); }, []); if (error) { @@ -396,6 +405,12 @@ export const DataExportTable = ({ boxProps }: { boxProps?: BoxProps }) => { return ( + {pending && + + + Checking Registry for Updates + + } Origin From 2cee6c3cca541f20e10112524f9fb3e0f6ad2038 Mon Sep 17 00:00:00 2001 From: Cannon Lock Date: Tue, 10 Dec 2024 14:41:23 -0600 Subject: [PATCH 2/6] Registration Refresh Only indicate loading if returning from registry --- .../frontend/components/DataExportTable.tsx | 91 ++++++++++--------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/web_ui/frontend/components/DataExportTable.tsx b/web_ui/frontend/components/DataExportTable.tsx index 442f6b292..b39acc5c3 100644 --- a/web_ui/frontend/components/DataExportTable.tsx +++ b/web_ui/frontend/components/DataExportTable.tsx @@ -23,6 +23,7 @@ import { getErrorMessage } from '@/helpers/util'; import { Capabilities } from '@/types'; import { CapabilitiesDisplay } from '@/components'; import CircularProgress from '@mui/material/CircularProgress'; +import { useSearchParams } from 'next/navigation'; type RegistrationStatus = | 'Not Supported' @@ -287,7 +288,7 @@ export const RecordTable = ({ data }: { data: ExportRes }): ReactElement => { const start = (page - 1) * 2; const end = start + 2; return Object.values(data.exports).slice(start, end); - }, [page]); + }, [page, data]); switch (data.type) { case 's3': @@ -351,10 +352,25 @@ export const getExportData = async (): Promise => { } }; +const generateEditUrl = (editUrl: string, fromUrl: string) => { + try { + let updatedFromUrl = new URL(fromUrl) + if(!('from_registry' in updatedFromUrl.searchParams)) { + updatedFromUrl.searchParams.append('from_registry', 'true') + } + const url = new URL(editUrl); + url.searchParams.append('fromUrl', updatedFromUrl.toString()); + return url.toString(); + } catch (e) { + console.error('Failed to generate editUrl', e); + return editUrl; + } +} + export const DataExportTable = ({ boxProps }: { boxProps?: BoxProps }) => { const [pending, setPending] = useState(false); const [ fromUrl, setFromUrl ] = useState(undefined); - const { data, error, mutate } = useSWR('getDataExport', getExportData, { + const { data, mutate } = useSWR('getDataExport', getExportData, { refreshInterval: 10000 }); @@ -367,45 +383,34 @@ export const DataExportTable = ({ boxProps }: { boxProps?: BoxProps }) => { }, 5000); }, []); - if (error) { - return ( - - - {error.toString()} - - - ); - } + const searchParams = useSearchParams() + const from_registry = searchParams.get('from_registry') == 'true' - const dataWFromUrl = data; - if (fromUrl) { - if (dataWFromUrl?.editUrl) { - try { - const editUrl = new URL(dataWFromUrl?.editUrl); - editUrl.searchParams.append('fromUrl', fromUrl); - dataWFromUrl.editUrl = editUrl.toString(); - } catch (error) { - console.log('editUrl is not a valid url: ', error); - } + const dataEnhanced = useMemo(() => { + + // If no from URL return current data + if (!fromUrl) { + return data; } - if (dataWFromUrl?.exports) { - dataWFromUrl.exports.map((val) => { - try { - const editUrl = new URL(val?.editUrl); - editUrl.searchParams.append('fromUrl', fromUrl); - val.editUrl = editUrl.toString(); - return val; - } catch (error) { - console.log('editUrl is not a valid url: ', error); - return val; - } - }); + + // If data is not available, return null + if (!data) { + return undefined; } - } + + let dataEnhanced = structuredClone(data) + dataEnhanced.editUrl = generateEditUrl(dataEnhanced.editUrl, fromUrl); + dataEnhanced.exports.map((val) => { + val.editUrl = generateEditUrl(val.editUrl, fromUrl); + }); + + return dataEnhanced; + + }, [data, fromUrl]) return ( - {pending && + {from_registry && pending && Checking Registry for Updates @@ -414,13 +419,13 @@ export const DataExportTable = ({ boxProps }: { boxProps?: BoxProps }) => { Origin - {dataWFromUrl && - dataWFromUrl.status && - dataWFromUrl.status != 'Completed' ? ( + {dataEnhanced && + dataEnhanced.status && + dataEnhanced.status != 'Completed' ? ( ) : ( Registration Completed @@ -429,8 +434,8 @@ export const DataExportTable = ({ boxProps }: { boxProps?: BoxProps }) => { Namespaces - {dataWFromUrl ? ( - + {dataEnhanced ? ( + ) : ( )} From 25d245b38d77b3d302c9a67d1423b0b38893a384 Mon Sep 17 00:00:00 2001 From: Cannon Lock Date: Tue, 10 Dec 2024 14:47:42 -0600 Subject: [PATCH 3/6] Registration Refresh Tweak language and header updates --- web_ui/frontend/components/DataExportTable.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web_ui/frontend/components/DataExportTable.tsx b/web_ui/frontend/components/DataExportTable.tsx index b39acc5c3..00a15f3c1 100644 --- a/web_ui/frontend/components/DataExportTable.tsx +++ b/web_ui/frontend/components/DataExportTable.tsx @@ -355,7 +355,7 @@ export const getExportData = async (): Promise => { const generateEditUrl = (editUrl: string, fromUrl: string) => { try { let updatedFromUrl = new URL(fromUrl) - if(!('from_registry' in updatedFromUrl.searchParams)) { + if(updatedFromUrl.searchParams.get('from_registry') === null) { updatedFromUrl.searchParams.append('from_registry', 'true') } const url = new URL(editUrl); @@ -413,7 +413,7 @@ export const DataExportTable = ({ boxProps }: { boxProps?: BoxProps }) => { {from_registry && pending && - Checking Registry for Updates + Starting Update Watcher; Will Poll Every 10 Seconds; } From f0f2cc91a0a24632305f003eb288f9f7360b5a1d Mon Sep 17 00:00:00 2001 From: Cannon Lock Date: Tue, 10 Dec 2024 15:18:21 -0600 Subject: [PATCH 4/6] Registration Refresh - Toss component in Suspense boundary --- web_ui/frontend/app/origin/page.tsx | 8 +++++--- web_ui/frontend/components/DataExportTable.tsx | 12 ++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/web_ui/frontend/app/origin/page.tsx b/web_ui/frontend/app/origin/page.tsx index 98e5fbcd6..0339bab11 100644 --- a/web_ui/frontend/app/origin/page.tsx +++ b/web_ui/frontend/app/origin/page.tsx @@ -18,8 +18,8 @@ 'use client'; -import { useState } from 'react'; -import { Box, IconButton, Grid, Tooltip, Typography } from '@mui/material'; +import { useState, Suspense } from 'react'; +import { Box, IconButton, Grid, Tooltip, Typography, Skeleton } from '@mui/material'; import { Key, CheckCircle } from '@mui/icons-material'; import RateGraph from '@/components/graphs/RateGraph'; @@ -85,7 +85,9 @@ export default function Home() { )} - + }> + + { } export const DataExportTable = ({ boxProps }: { boxProps?: BoxProps }) => { + + const searchParams = useSearchParams() + const from_registry = searchParams.get('from_registry') == 'true' + const [pending, setPending] = useState(false); const [ fromUrl, setFromUrl ] = useState(undefined); const { data, mutate } = useSWR('getDataExport', getExportData, { - refreshInterval: 10000 + refreshInterval: from_registry ? 10000 : 0, }); useEffect(() => { @@ -380,12 +383,9 @@ export const DataExportTable = ({ boxProps }: { boxProps?: BoxProps }) => { setTimeout(() => { mutate() setPending(false); - }, 5000); + }, 10000); }, []); - const searchParams = useSearchParams() - const from_registry = searchParams.get('from_registry') == 'true' - const dataEnhanced = useMemo(() => { // If no from URL return current data From 0c806b57cd5f6971c9d54e1b7b91db7291478959 Mon Sep 17 00:00:00 2001 From: Cannon Lock Date: Tue, 10 Dec 2024 15:19:31 -0600 Subject: [PATCH 5/6] Linter --- web_ui/frontend/app/origin/page.tsx | 11 +++++- .../frontend/components/DataExportTable.tsx | 38 +++++++++---------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/web_ui/frontend/app/origin/page.tsx b/web_ui/frontend/app/origin/page.tsx index 0339bab11..8c042eb1d 100644 --- a/web_ui/frontend/app/origin/page.tsx +++ b/web_ui/frontend/app/origin/page.tsx @@ -19,7 +19,14 @@ 'use client'; import { useState, Suspense } from 'react'; -import { Box, IconButton, Grid, Tooltip, Typography, Skeleton } from '@mui/material'; +import { + Box, + IconButton, + Grid, + Tooltip, + Typography, + Skeleton, +} from '@mui/material'; import { Key, CheckCircle } from '@mui/icons-material'; import RateGraph from '@/components/graphs/RateGraph'; @@ -85,7 +92,7 @@ export default function Home() { )} - }> + }> diff --git a/web_ui/frontend/components/DataExportTable.tsx b/web_ui/frontend/components/DataExportTable.tsx index 1275bab63..e50be19ee 100644 --- a/web_ui/frontend/components/DataExportTable.tsx +++ b/web_ui/frontend/components/DataExportTable.tsx @@ -12,7 +12,8 @@ import { Pagination, Paper, Alert, - IconButton, LinearProgress, + IconButton, + LinearProgress, } from '@mui/material'; import React, { ReactElement, useEffect, useMemo, useState } from 'react'; import { Skeleton } from '@mui/material'; @@ -353,9 +354,9 @@ export const getExportData = async (): Promise => { const generateEditUrl = (editUrl: string, fromUrl: string) => { try { - let updatedFromUrl = new URL(fromUrl) - if(updatedFromUrl.searchParams.get('from_registry') === null) { - updatedFromUrl.searchParams.append('from_registry', 'true') + let updatedFromUrl = new URL(fromUrl); + if (updatedFromUrl.searchParams.get('from_registry') === null) { + updatedFromUrl.searchParams.append('from_registry', 'true'); } const url = new URL(editUrl); url.searchParams.append('fromUrl', updatedFromUrl.toString()); @@ -364,15 +365,14 @@ const generateEditUrl = (editUrl: string, fromUrl: string) => { console.error('Failed to generate editUrl', e); return editUrl; } -} +}; export const DataExportTable = ({ boxProps }: { boxProps?: BoxProps }) => { - - const searchParams = useSearchParams() - const from_registry = searchParams.get('from_registry') == 'true' + const searchParams = useSearchParams(); + const from_registry = searchParams.get('from_registry') == 'true'; const [pending, setPending] = useState(false); - const [ fromUrl, setFromUrl ] = useState(undefined); + const [fromUrl, setFromUrl] = useState(undefined); const { data, mutate } = useSWR('getDataExport', getExportData, { refreshInterval: from_registry ? 10000 : 0, }); @@ -381,13 +381,12 @@ export const DataExportTable = ({ boxProps }: { boxProps?: BoxProps }) => { setFromUrl(window.location.href); setPending(true); setTimeout(() => { - mutate() + mutate(); setPending(false); }, 10000); }, []); const dataEnhanced = useMemo(() => { - // If no from URL return current data if (!fromUrl) { return data; @@ -398,24 +397,25 @@ export const DataExportTable = ({ boxProps }: { boxProps?: BoxProps }) => { return undefined; } - let dataEnhanced = structuredClone(data) + let dataEnhanced = structuredClone(data); dataEnhanced.editUrl = generateEditUrl(dataEnhanced.editUrl, fromUrl); dataEnhanced.exports.map((val) => { val.editUrl = generateEditUrl(val.editUrl, fromUrl); }); return dataEnhanced; - - }, [data, fromUrl]) + }, [data, fromUrl]); return ( - {from_registry && pending && - - - Starting Update Watcher; Will Poll Every 10 Seconds; + {from_registry && pending && ( + + + + Starting Update Watcher; Will Poll Every 10 Seconds; + - } + )} Origin From 1b9bda86c4f9317e993348cf599d013f0b2f1609 Mon Sep 17 00:00:00 2001 From: Cannon Lock <49032265+CannonLock@users.noreply.github.com> Date: Thu, 12 Dec 2024 09:14:00 -0600 Subject: [PATCH 6/6] Update web_ui/frontend/components/DataExportTable.tsx --- web_ui/frontend/components/DataExportTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_ui/frontend/components/DataExportTable.tsx b/web_ui/frontend/components/DataExportTable.tsx index e50be19ee..07d231da1 100644 --- a/web_ui/frontend/components/DataExportTable.tsx +++ b/web_ui/frontend/components/DataExportTable.tsx @@ -412,7 +412,7 @@ export const DataExportTable = ({ boxProps }: { boxProps?: BoxProps }) => { - Starting Update Watcher; Will Poll Every 10 Seconds; + Polling from Registry for Updates Every 10 Seconds )}