Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docx Export #241

Merged
merged 2 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"bootstrap": "^4.6.0",
"date-fns": "^2.30.0",
"dayzed": "^3.2.3",
"docx": "8.0.0",
"framer-motion": "^4.1.17",
"graphql": "^15.5.0",
"humps": "^2.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,21 @@ import {
ModalCloseButton,
Spinner,
FormLabel,
Flex,
} from "@chakra-ui/react";
import { ArrowDownIcon, ArrowUpIcon } from "@chakra-ui/icons";
import { TiExport } from "react-icons/ti";
import LogRecordAPIClient from "../../APIClients/LogRecordAPIClient";
import { singleDatePickerStyle } from "../../theme/forms/datePickerStyles";
import convertLogsToCSV from "../../helper/csvHelpers";
import {
convertLogsToDOCX,
convertLogsToCSV,
} from "../../helper/exportHelpers";
import CreateToast from "../common/Toasts";
import { getFormattedDateAndTime } from "../../helper/dateHelpers";
import { SingleDatepicker } from "../common/Datepicker";

const ExportToCSV = (): React.ReactElement => {
const ExportLogs = (): React.ReactElement => {
const [startDate, setStartDate] = useState<Date | undefined>();
const [isStartDateEmpty, setIsStartDateEmpty] = useState<boolean>(true);
const [endDate, setEndDate] = useState<Date | undefined>();
Expand All @@ -39,6 +44,8 @@ const ExportToCSV = (): React.ReactElement => {
const [endDateError, setEndDateError] = useState<boolean>(false);
const [dateError, setDateError] = useState<boolean>(false);

const [sortDirection, setSortDirection] = useState("desc");

const [isOpen, setOpen] = useState(false);

const [loading, setLoading] = useState(false);
Expand All @@ -47,6 +54,7 @@ const ExportToCSV = (): React.ReactElement => {
const handleClear = () => {
setStartDate(undefined);
setEndDate(undefined);
setSortDirection("desc");
setDateError(false);
setStartDateError(false);
setEndDateError(false);
Expand Down Expand Up @@ -93,20 +101,23 @@ const ExportToCSV = (): React.ReactElement => {
setOpen(false);
};

const handleSubmit = async () => {
const validateDates = (): boolean => {
if (!startDate && !isStartDateEmpty) {
setStartDateError(true);
return;
return false;
}
if (!endDate && !isEndDateEmpty) {
setEndDateError(true);
return;
return false;
}
if (startDate && endDate && startDate > endDate) {
setDateError(true);
return;
return false;
}
return true;
};

const constructDateRange = (): (string | null)[] | undefined => {
let dateRange;
if (startDate || endDate) {
startDate?.setHours(0, 0, 0, 0);
Expand All @@ -117,10 +128,57 @@ const ExportToCSV = (): React.ReactElement => {
endDate ? endDate.toISOString() : null,
];
}

return dateRange;
};

const handleDocxExport = async () => {
if (!validateDates()) {
return;
}

setLoading(true);
const data = await LogRecordAPIClient.filterLogRecords({
dateRange,
returnAll: true, // return all data
dateRange: constructDateRange(),
sortDirection,
returnAll: true,
});

if (!data || data.logRecords.length === 0) {
newToast(
"Error downloading DOCX",
"No records found in the provided date range.",
"error",
);
} else {
const formattedLogRecords = data.logRecords.map((logRecord) => {
const { date, time } = getFormattedDateAndTime(
new Date(logRecord.datetime),
true,
);
return { ...logRecord, datetime: `${date}, ${time}` };
});
const success = await convertLogsToDOCX(formattedLogRecords);
if (success) {
newToast("DOCX downloaded", "Successfully downloaded DOCX.", "success");
handleClose();
} else {
newToast("Error downloading DOCX", "Unable to download DOCX.", "error");
}
}
setLoading(false);
};

const handleCsvExport = async () => {
if (!validateDates()) {
return;
}

setLoading(true);
const data = await LogRecordAPIClient.filterLogRecords({
dateRange: constructDateRange(),
sortDirection,
returnAll: true,
});

if (!data || data.logRecords.length === 0) {
Expand Down Expand Up @@ -150,9 +208,9 @@ const ExportToCSV = (): React.ReactElement => {

return (
<>
<Tooltip label="Export to CSV">
<Tooltip label="Export Logs">
<IconButton
aria-label="Export to CSV"
aria-label="Export Logs"
icon={<Icon boxSize="36px" as={TiExport} />}
variant="tertiary"
onClick={handleOpen}
Expand All @@ -163,7 +221,7 @@ const ExportToCSV = (): React.ReactElement => {
<Modal isOpen={isOpen} onClose={handleClose} size="xl">
<ModalOverlay />
<ModalContent>
<ModalHeader>Export to CSV File</ModalHeader>
<ModalHeader>Export Logs</ModalHeader>
<ModalCloseButton size="lg" />
<ModalBody>
<FormControl isInvalid={dateError}>
Expand Down Expand Up @@ -225,6 +283,32 @@ const ExportToCSV = (): React.ReactElement => {
Note: If a range is not selected, all records will be printed.
</FormHelperText>
</FormControl>
<FormControl>
<FormLabel mt={4}>Sort Direction</FormLabel>
<Flex alignItems="center" gap="10px">
<IconButton
aria-label="calendar"
size="sm"
variant="secondary"
fontSize="20px"
icon={
sortDirection === "desc" ? (
<ArrowDownIcon />
) : (
<ArrowUpIcon />
)
}
onClick={() =>
setSortDirection(
sortDirection === "desc" ? "asc" : "desc",
)
}
/>
<Text>
{sortDirection === "desc" ? "Descending" : "Ascending"}
</Text>
</Flex>
</FormControl>
</ModalBody>

<ModalFooter>
Expand All @@ -237,8 +321,16 @@ const ExportToCSV = (): React.ReactElement => {
marginRight="10px"
/>
)}
<Button onClick={handleSubmit} variant="primary" type="submit">
Export
<Button
onClick={handleDocxExport}
variant="primary"
type="submit"
marginRight="10px"
>
Export As DOCX
</Button>
<Button onClick={handleCsvExport} variant="primary" type="submit">
Export As CSV
</Button>
</ModalFooter>
</ModalContent>
Expand All @@ -248,4 +340,4 @@ const ExportToCSV = (): React.ReactElement => {
);
};

export default ExportToCSV;
export default ExportLogs;
4 changes: 2 additions & 2 deletions frontend/src/components/pages/HomePage/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import CreateLog from "../../forms/CreateLog";
import { LogRecord } from "../../../types/LogRecordTypes";
import LogRecordsTable from "./LogRecordsTable";
import HomePageFilters from "./HomePageFilters";
import ExportToCSV from "../../forms/ExportToCSV";
import ExportLogs from "../../forms/ExportLogs";
import LogRecordAPIClient from "../../../APIClients/LogRecordAPIClient";
import { SelectLabel } from "../../../types/SharedTypes";

Expand Down Expand Up @@ -219,7 +219,7 @@ const HomePage = (): React.ReactElement => {
countRecords={countLogRecords}
setUserPageNum={setUserPageNum}
/>
<ExportToCSV />
<ExportLogs />
</Flex>
</Flex>

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/pages/HomePage/LogRecordsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ const LogRecordsTable = ({
<Th>Tenants</Th>
<Th>Note</Th>
<Th>Employee</Th>
<Th>Attn To</Th>
<Th>Attn Tos</Th>
<Th>Tags</Th>
<Th> </Th>
</Tr>
Expand Down
68 changes: 0 additions & 68 deletions frontend/src/helper/csvHelpers.ts

This file was deleted.

Loading
Loading