Files
rowy/src/components/fields/File/TableCell.tsx

201 lines
5.2 KiB
TypeScript
Raw Normal View History

2021-09-01 15:54:20 +10:00
import { useCallback } from "react";
import { IHeavyCellProps } from "../types";
import { useDropzone } from "react-dropzone";
import _findIndex from "lodash/findIndex";
import { format } from "date-fns";
import { makeStyles, createStyles } from "@mui/styles";
2021-09-01 15:54:20 +10:00
import {
2021-09-01 15:59:30 +10:00
alpha,
2021-09-08 10:47:08 +10:00
Stack,
2021-09-01 15:59:30 +10:00
Grid,
Tooltip,
Chip,
IconButton,
CircularProgress,
} from "@mui/material";
2021-09-01 15:54:20 +10:00
import UploadIcon from "assets/icons/Upload";
2021-09-25 16:44:30 +10:00
import ChipList from "components/Table/formatters/ChipList";
2021-09-01 15:54:20 +10:00
import { useConfirmation } from "components/ConfirmationDialog";
import useUploader, { FileValue } from "hooks/useTable/useUploader";
2021-09-01 15:54:20 +10:00
import { FileIcon } from ".";
import { DATE_TIME_FORMAT } from "constants/dates";
import { useProjectContext } from "contexts/ProjectContext";
2021-09-01 15:54:20 +10:00
const useStyles = makeStyles((theme) =>
2021-09-01 15:59:30 +10:00
createStyles({
root: {
2021-09-25 16:44:30 +10:00
paddingRight: theme.spacing(0.5),
2021-09-01 15:59:30 +10:00
outline: "none",
},
dragActive: {
backgroundColor: alpha(
theme.palette.primary.main,
theme.palette.action.hoverOpacity * 2
),
"& .row-hover-iconButton": { color: theme.palette.primary.main },
},
2021-09-08 10:47:08 +10:00
chipList: {
overflow: "hidden",
flexGrow: 1,
marginLeft: "0 !important",
2021-09-01 15:59:30 +10:00
},
2021-09-24 11:01:15 +10:00
chip: { width: "100%" },
2021-09-08 10:47:08 +10:00
endButtonContainer: {},
2021-09-01 15:59:30 +10:00
circularProgress: {
2021-09-08 10:47:08 +10:00
color: theme.palette.action.active,
2021-09-01 15:59:30 +10:00
display: "block",
2021-09-08 10:47:08 +10:00
margin: theme.spacing(0, 0.5),
2021-09-01 15:59:30 +10:00
},
})
2021-09-01 15:54:20 +10:00
);
export default function File_({
2021-09-01 15:59:30 +10:00
column,
row,
value,
onSubmit,
disabled,
2021-09-01 15:54:20 +10:00
}: IHeavyCellProps) {
2021-09-01 15:59:30 +10:00
const classes = useStyles();
const { updateCell } = useProjectContext();
2021-09-01 15:59:30 +10:00
const { uploaderState, upload, deleteUpload } = useUploader();
const { progress, isLoading } = uploaderState;
const { requestConfirmation } = useConfirmation();
const onDrop = useCallback(
(acceptedFiles) => {
const file = acceptedFiles[0];
if (file) {
upload({
docRef: row.ref,
fieldName: column.key,
2021-09-01 15:59:30 +10:00
files: [file],
previousValue: value,
onComplete: (newValue) => {
if (updateCell) updateCell(row.ref, column.key, newValue);
},
});
}
},
[value]
);
const handleDelete = (ref: string) => {
const newValue = [...value];
const index = _findIndex(newValue, ["ref", ref]);
const toBeDeleted = newValue.splice(index, 1);
toBeDeleted.length && deleteUpload(toBeDeleted[0]);
onSubmit(newValue);
};
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
multiple: false,
});
const dropzoneProps = getRootProps();
return (
2021-09-08 10:47:08 +10:00
<Stack
direction="row"
2021-09-25 16:44:30 +10:00
className="cell-collapse-padding"
2021-09-01 15:59:30 +10:00
alignItems="center"
2021-09-25 16:44:30 +10:00
sx={{
height: "100%",
pr: 0.5,
...(isDragActive
? {
backgroundColor: (theme) =>
alpha(
theme.palette.primary.main,
theme.palette.action.hoverOpacity * 2
),
"& .row-hover-iconButton": { color: "primary.main" },
}
: {}),
}}
2021-09-01 15:59:30 +10:00
{...dropzoneProps}
onClick={undefined}
>
2021-09-25 16:44:30 +10:00
<ChipList>
{Array.isArray(value) &&
value.map((file: FileValue) => (
<Grid
item
key={file.downloadURL}
style={
// Truncate so multiple files still visible
value.length > 1 ? { maxWidth: `calc(100% - 12px)` } : {}
}
2021-09-01 15:59:30 +10:00
>
2021-09-25 16:44:30 +10:00
<Tooltip
title={`File last modified ${format(
file.lastModifiedTS,
DATE_TIME_FORMAT
)}`}
>
<Chip
icon={<FileIcon />}
label={file.name}
onClick={(e) => {
window.open(file.downloadURL);
e.stopPropagation();
}}
onDelete={
disabled
? undefined
: () =>
requestConfirmation({
handleConfirm: () => handleDelete(file.ref),
title: "Delete file",
2021-09-25 16:44:30 +10:00
body: "Are you sure you want to delete this file?",
confirm: "Delete",
})
}
className={classes.chip}
/>
</Tooltip>
</Grid>
))}
</ChipList>
{!isLoading ? (
!disabled && (
<IconButton
size="small"
className="row-hover-iconButton"
onClick={(e) => {
dropzoneProps.onClick!(e);
e.stopPropagation();
}}
style={{ display: "flex" }}
>
<UploadIcon />
</IconButton>
)
) : (
<div style={{ padding: 4 }}>
2021-09-01 15:59:30 +10:00
<CircularProgress
size={24}
variant={progress === 0 ? "indeterminate" : "determinate"}
value={progress}
2021-09-08 10:47:08 +10:00
thickness={4}
2021-09-25 16:44:30 +10:00
style={{ display: "block" }}
2021-09-01 15:59:30 +10:00
/>
2021-09-25 16:44:30 +10:00
</div>
)}
<input {...getInputProps()} />
2021-09-08 10:47:08 +10:00
</Stack>
2021-09-01 15:59:30 +10:00
);
2021-09-01 15:54:20 +10:00
}