- alert level changes now display accurate color. - comm coor report no longer has dark loading screen in lt mode. login input text no longer white in dark mode
140 lines
5.0 KiB
React
140 lines
5.0 KiB
React
import {Flex, Button, Spinner, Text} from "@chakra-ui/react";
|
|
import useBuildUrl from "../../hooks/useBuildUrl.js";
|
|
import VdapApi from '../../hooks/useVdapApi.js';
|
|
import { useRef, useEffect } from 'react';
|
|
import {useDashboardStore} from "../../store/useDashboardStore.jsx";
|
|
|
|
export default function CommCoorReport({ settings, widgetID }) {
|
|
const reportRef = useRef(null);
|
|
|
|
const updateSettings = useDashboardStore(state => state.updateWidgetSettings);
|
|
|
|
// build url, defaults to 7 days past
|
|
const url = useBuildUrl('/api/v2/comm_coor_report', settings?.startDate, settings?.endDate);
|
|
console.log(url);
|
|
|
|
// VdapApi hook only calls api if the url changes and apiData remains stable since vdapApi uses state to track the data
|
|
const {data: apiData, isLoading, error} = VdapApi(url);
|
|
console.log(apiData);
|
|
|
|
const handleDownloadReport = () => {
|
|
if (apiData.length === 0) return;
|
|
const element = document.createElement('a');
|
|
element.style.display = 'none';
|
|
// Appends HTML right inside the element, after its last child
|
|
element.insertAdjacentHTML('afterbegin', apiData?.report_html);
|
|
|
|
// 1. Create a blob object with text content and text/plain mime type
|
|
const blob = new Blob([element.textContent || ""], { type: 'text/plain' });
|
|
|
|
// 2. Generate a temporary URL pointing to that blob
|
|
const fileUrl = URL.createObjectURL(blob);
|
|
|
|
// 3. Create a hidden anchor element
|
|
const linkElement = document.createElement('a');
|
|
linkElement.href = fileUrl;
|
|
linkElement.download = `comm_coor_report_${apiData?.start_date}_${apiData?.end_date}`; // Sets the target file name
|
|
linkElement.style.display = 'none';
|
|
|
|
// 4. Append to body, trigger click, and remove it immediately
|
|
document.body.appendChild(linkElement);
|
|
linkElement.click();
|
|
document.body.removeChild(linkElement);
|
|
document.body.removeChild(element);
|
|
|
|
// 5. Free up memory by revoking the blob URL
|
|
URL.revokeObjectURL(fileUrl);
|
|
}
|
|
|
|
const handleCopyReport = () => {
|
|
if (apiData.length === 0) return;
|
|
const element = document.createElement('a');
|
|
element.style.display = 'none';
|
|
// Appends HTML right inside the element, after its last child
|
|
element.insertAdjacentHTML('afterbegin', apiData?.report_html);
|
|
|
|
navigator.clipboard.writeText(element.textContent || "")
|
|
.then(() => {
|
|
alert('Copied to clipboard!');
|
|
})
|
|
.catch((err => {
|
|
console.error('Failed to copy: ', err);
|
|
}));
|
|
|
|
document.body.removeChild(element);
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (reportRef.current) {
|
|
reportRef.current.innerHTML = apiData?.report_html;
|
|
const p = reportRef.current.querySelectorAll('p');
|
|
const b = reportRef.current.querySelectorAll('b');
|
|
p[0].remove();
|
|
b[0].remove();
|
|
}
|
|
}, [apiData]);
|
|
|
|
// copy data to clipboard in formatted way when user clicks on copy btn in widget settings
|
|
useEffect(() => {
|
|
if (settings?.copyToClipboard === true && reportRef.current) {
|
|
navigator.clipboard.writeText(reportRef.current.innerText)
|
|
.then(() => {
|
|
alert('Copied to clipboard!');
|
|
})
|
|
.catch((err => {
|
|
console.error('Failed to copy: ', err);
|
|
}));
|
|
updateSettings(widgetID, {copyToClipboard: false});
|
|
}
|
|
}, [settings, widgetID, updateSettings]);
|
|
|
|
// download report
|
|
useEffect(() => {
|
|
if (settings?.downloadReport === true && reportRef.current) {
|
|
// 1. Create a blob object with text content and text/plain mime type
|
|
const blob = new Blob([reportRef.current.innerText || ""], { type: 'text/plain' });
|
|
|
|
// 2. Generate a temporary URL pointing to that blob
|
|
const fileUrl = URL.createObjectURL(blob);
|
|
|
|
// 3. Create a hidden anchor element
|
|
const linkElement = document.createElement('a');
|
|
linkElement.href = fileUrl;
|
|
linkElement.download = `comm_coor_report_${apiData?.start_date}_${apiData?.end_date}`; // Sets the target file name
|
|
linkElement.style.display = 'none';
|
|
|
|
// 4. Append to body, trigger click, and remove it immediately
|
|
document.body.appendChild(linkElement);
|
|
linkElement.click();
|
|
document.body.removeChild(linkElement);
|
|
|
|
// 5. Free up memory by revoking the blob URL
|
|
URL.revokeObjectURL(fileUrl);
|
|
updateSettings(widgetID, {downloadReport: false});
|
|
}
|
|
}, [settings, widgetID, updateSettings, apiData]);
|
|
|
|
if (isLoading) return (
|
|
<Flex w="100%" h="100%" align="center" justify="center" borderRadius="lg" bg="transparent">
|
|
<Spinner size="xl" color="blue.400" thickness="4px"/>
|
|
</Flex>
|
|
);
|
|
|
|
if (error) return (
|
|
<Flex w="100%" h="100%" align="center" justify="center" textAlign="center" borderRadius="lg" bg="transparent">
|
|
<Text color="red.400">{error}</Text>
|
|
</Flex>
|
|
);
|
|
|
|
if (!apiData) return (
|
|
<Flex w="100%" h="100%" align="center" justify="center" borderRadius="lg" bg="transparent">
|
|
<Text textAlign="center" color="gray.400">No data</Text>
|
|
</Flex>
|
|
);
|
|
|
|
return (
|
|
<Flex direction="row" w="100%" h="100%" p={1} overflowY="auto">
|
|
<Text ref={reportRef}></Text>
|
|
</Flex>
|
|
)
|
|
} |