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
+46 -70
View File
@@ -1,11 +1,10 @@
import VdapApi from '../../hooks/useVdapApi.js';
import {Button, Dialog, Flex, Portal, Spinner, Text} from "@chakra-ui/react";
import {useEffect, useMemo, useState } from 'react';
import {Button, Flex, Spinner, Text, Box, Collapsible} from "@chakra-ui/react";
import {useEffect, useMemo } from 'react';
import {useDashboardStore} from "@/store/useDashboardStore.jsx";
import VdapApi from '../../hooks/useVdapApi.js';
export default function IvansAlerts({ settings, widgetID }) {
console.log("IvansAlerts widget ID: ", widgetID);
const [activeSummaryItem, setActiveSummaryItem] = useState(false);
const updateSettings = useDashboardStore(state => state.updateWidgetSettings);
const isCopy = settings?.copyToClipboard === true; // acts as a fail-safe if no default setting is set
const sorts = settings?.activeSorts;
@@ -122,13 +121,13 @@ export default function IvansAlerts({ settings, widgetID }) {
}, [isCopy, data, widgetID, updateSettings]);
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"/>
</Flex>
);
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>
</Flex>
);
@@ -140,75 +139,52 @@ export default function IvansAlerts({ settings, widgetID }) {
);
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) => {
return (
/* IVANS ENTRIES */
<Flex onClick={() => setActiveSummaryItem(item)} w="100%" h="100%" key={index} borderRadius="lg" bg="gray.700" justify="space-between" align="center">
<Flex direction="column" w="60%" pl={3} color="gray.100">
<Collapsible.Root key={index} w="100%">
<Collapsible.Context>
{(collapsible) => (
<>
<Collapsible.Trigger w="100%">
<Flex direction="row"
w="100%" h="100%"
justify="space-between" align="center"
pb={1}
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 direction="row" w="40%" justify="right" pr={3}>
<Text color="gray.100" bg="gray.800/50" borderRadius="lg" pl={2} pr={2}>{item.report_num}</Text>
<Flex pr={3}>
<Text pl={2} pr={2} borderRadius="lg" bg="gray.800/50" color="gray.100">{item.report_num}</Text>
</Flex>
</Flex>
)
})}
{/* SUMMARY/PDF VIEWER */}
<SummaryDialog
open={!!activeSummaryItem}
onOpenChange={() => setActiveSummaryItem(null)}
item={activeSummaryItem}
/>
</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">
</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 data={`${file?.url}#view=FitH&toolbar=1`}
<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%" color="gray.400" p={4}>
<Flex w="100%" h="100%" p={4} color="gray.400">
<Text mb={2} color="fg.muted">
Your browser cannot display this PDF directly.
</Text>
@@ -220,19 +196,19 @@ function SummaryDialog({ open, onOpenChange, item }) {
<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>
</Box>
</Collapsible.Content>
</>
)}
</Collapsible.Context>
</Collapsible.Root>
)
})}
</Flex>
);
}
function ascTimeVolcanoSort(a, b) {
if (a.volcano_name < b.volcano_name) return -1
else if (a.volcano_name > b.volcano_name) return 1
+1 -2
View File
@@ -53,8 +53,7 @@ export const WIDGET_REGISTRY = {
allowedSizes: {
small: { w: 3, h: 6 },
medium: { w: 3, h: 9 },
large: { w: 3, h: 12 },
gargantuan: { w: 6, h: 12 },
large: { w: 6, h: 9 },
}
},