Update viewing format of ivans summary and pdf

This commit is contained in:
2026-08-06 14:58:12 +00:00
parent 1dcee8c8c3
commit dccebbc21b
2 changed files with 67 additions and 92 deletions
+66 -90
View File
@@ -1,11 +1,10 @@
import VdapApi from '../../hooks/useVdapApi.js'; import {Button, Flex, Spinner, Text, Box, Collapsible} from "@chakra-ui/react";
import {Button, Dialog, Flex, Portal, Spinner, Text} from "@chakra-ui/react"; import {useEffect, useMemo } from 'react';
import {useEffect, useMemo, useState } from 'react';
import {useDashboardStore} from "@/store/useDashboardStore.jsx"; import {useDashboardStore} from "@/store/useDashboardStore.jsx";
import VdapApi from '../../hooks/useVdapApi.js';
export default function IvansAlerts({ settings, widgetID }) { export default function IvansAlerts({ settings, widgetID }) {
console.log("IvansAlerts widget ID: ", widgetID); console.log("IvansAlerts widget ID: ", widgetID);
const [activeSummaryItem, setActiveSummaryItem] = useState(false);
const updateSettings = useDashboardStore(state => state.updateWidgetSettings); const updateSettings = useDashboardStore(state => state.updateWidgetSettings);
const isCopy = settings?.copyToClipboard === true; // acts as a fail-safe if no default setting is set const isCopy = settings?.copyToClipboard === true; // acts as a fail-safe if no default setting is set
const sorts = settings?.activeSorts; const sorts = settings?.activeSorts;
@@ -122,13 +121,13 @@ export default function IvansAlerts({ settings, widgetID }) {
}, [isCopy, data, widgetID, updateSettings]); }, [isCopy, data, widgetID, updateSettings]);
if (isLoading) return ( if (isLoading) return (
<Flex w="100%" h="100%" bg="gray.800" borderRadius="md" align="center" justify="center"> <Flex w="100%" h="100%" align="center" justify="center" borderRadius="md" bg="gray.800">
<Spinner size="xl" color="blue.400" thickness="4px"/> <Spinner size="xl" color="blue.400" thickness="4px"/>
</Flex> </Flex>
); );
if (error) return ( if (error) return (
<Flex w="100%" h="100%" bg="gray.800" borderRadius="md" align="center" justify="center" p={4}> <Flex w="100%" h="100%" align="center" justify="center" p={4} borderRadius="md" bg="gray.800">
<Text color="red.400">{error}</Text> <Text color="red.400">{error}</Text>
</Flex> </Flex>
); );
@@ -140,98 +139,75 @@ export default function IvansAlerts({ settings, widgetID }) {
); );
return ( return (
<Flex pos="relative" w="100%" h="100%" direction="column" bg="gray.800" borderRadius="xl" align="center" justify="center" gap={2} p={2}> <Flex direction="column"
w="100%" h="100%"
pos="relative"
justify="top" align="center"
p={2} gap={2}
overflowY="auto"
borderRadius="xl"
bg="gray.800"
>
{data.map((item, index) => { {data.map((item, index) => {
return ( return (
/* IVANS ENTRIES */ <Collapsible.Root key={index} w="100%">
<Flex onClick={() => setActiveSummaryItem(item)} w="100%" h="100%" key={index} borderRadius="lg" bg="gray.700" justify="space-between" align="center"> <Collapsible.Context>
<Flex direction="column" w="60%" pl={3} color="gray.100"> {(collapsible) => (
<Text>{item.volcano_name}</Text> <>
<Text fontSize="xs" color="gray.300/90">{item.send_time}</Text> <Collapsible.Trigger w="100%">
</Flex> <Flex direction="row"
<Flex direction="row" w="40%" justify="right" pr={3}> w="100%" h="100%"
<Text color="gray.100" bg="gray.800/50" borderRadius="lg" pl={2} pr={2}>{item.report_num}</Text> justify="space-between" align="center"
</Flex> pb={1}
</Flex> borderTopRadius="lg"
borderBottomRadius={collapsible.open ? "0" : "lg"}
bg="gray.700"
>
<Flex direction="column" pl={3} textAlign="left" color="gray.100">
<Text>{item.volcano_name}</Text>
<Text fontSize="xs" color="gray.300/90">{item.send_time}</Text>
</Flex>
<Flex pr={3}>
<Text pl={2} pr={2} borderRadius="lg" bg="gray.800/50" color="gray.100">{item.report_num}</Text>
</Flex>
</Flex>
</Collapsible.Trigger>
<Collapsible.Content w="100%" h="100%">
<Box p={1} pl={2} borderBottomRadius="lg" bg="gray.700/45">
<Text textAlign="left" color="gray.100">{item?.summary}</Text>
<br />
{item?.files?.map((file, index) => {
return (
<>
<object key={index}
data={`${file?.url}#view=FitH&toolbar=1`}
type="application/pdf"
style={{ width: '100%', height: '100%', display: 'block' }}
>
<Flex w="100%" h="100%" p={4} color="gray.400">
<Text mb={2} color="fg.muted">
Your browser cannot display this PDF directly.
</Text>
<a href={file?.url} target="_blank">
Download PDF
</a>
</Flex>
</object>
<br />
</>
)})}
</Box>
</Collapsible.Content>
</>
)}
</Collapsible.Context>
</Collapsible.Root>
) )
})} })}
{/* SUMMARY/PDF VIEWER */}
<SummaryDialog
open={!!activeSummaryItem}
onOpenChange={() => setActiveSummaryItem(null)}
item={activeSummaryItem}
/>
</Flex> </Flex>
); );
} }
function SummaryDialog({ open, onOpenChange, item }) {
return (
<Dialog.Root lazyMount
open={open}
onOpenChange={onOpenChange}
trapFocus={false}
modal={false}
closeOnInteractOutside={false}
motionPreset="slide-in-bottom"
position="absolute"
>
<Dialog.Positioner w="100%" h="100%">
<Dialog.Content w="100%" h="100%" maxW="none" p={0} m={0} borderRadius="xl" boxShadow="none">
<Dialog.Header p={3}>
<Dialog.Title w="100%">
<Flex w="100%" direction="row" justify="space-between" align="center">
<Flex w="100%" direction="column">
<Text w="100%" fontSize="lg">
{item?.volcano_name}
</Text>
<Text w="100%" fontSize="sm" color="blue.400">
{item?.send_time}
</Text>
</Flex>
<Flex w="100%" justify="right" align="center">
<Text textAlign="center" bg="gray.600" fontSize="xs" borderRadius="xl" color="gray.400" pl={2} pr={2}>
prepared by: {item?.preparer}
</Text>
</Flex>
</Flex>
</Dialog.Title>
</Dialog.Header>
<Dialog.Body bg="gray.800" overflow="auto">
<Text textAlign="left" color="gray.100">{item?.summary}</Text>
<br />
{item?.files?.map((file, index) => {
return (
<>
<object data={`${file?.url}#view=FitH&toolbar=1`}
type="application/pdf"
style={{ width: '100%', height: '100%', display: 'block' }}
>
<Flex w="100%" h="100%" color="gray.400" p={4}>
<Text mb={2} color="fg.muted">
Your browser cannot display this PDF directly.
</Text>
<a href={file?.url} target="_blank">
Download PDF
</a>
</Flex>
</object>
<br />
</>
)})}
</Dialog.Body>
<Dialog.Footer p={2} pr={3}>
<Button size="xs" variant="subtle" onClick={() => onOpenChange({ open: false })}>
Close
</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Positioner>
</Dialog.Root>
)
}
function ascTimeVolcanoSort(a, b) { function ascTimeVolcanoSort(a, b) {
if (a.volcano_name < b.volcano_name) return -1 if (a.volcano_name < b.volcano_name) return -1
+1 -2
View File
@@ -53,8 +53,7 @@ export const WIDGET_REGISTRY = {
allowedSizes: { allowedSizes: {
small: { w: 3, h: 6 }, small: { w: 3, h: 6 },
medium: { w: 3, h: 9 }, medium: { w: 3, h: 9 },
large: { w: 3, h: 12 }, large: { w: 6, h: 9 },
gargantuan: { w: 6, h: 12 },
} }
}, },