saleor-dashboard/src/components/FileUploadField/FileUploadField.tsx

148 lines
3.6 KiB
TypeScript
Raw Normal View History

File attributes (#884) * Update changelog with file attributes * Add file type attribute * Update attribute properties form * Update translation messages with file upload * Create generic attributes component (#832) * Create generic Attributes component * Add story for Attributes component * Remove deprecated attribute value type field from queries * Update test snapshots of attributes component * Add file upload field to atributes (#888) * Add story for Attributes component * Update test snapshots of attributes component * Create file upload field in attributes * Update upload file input data-test * Update storybook test snapshots of attributes * Add dedicated input props to file field * Run Cypress using custom API * Add missing error handling in file upload field Co-authored-by: Krzysztof Wolski <krzysztof.k.wolski@gmail.com> * Add file attribute upload to page attributes (#894) * Support upload file attribute for pages * Update after review * Add file attribute upload to variant attributes (#892) * Support upload file attribute for variants * Update after review * Refactor attribute values errors merging * Update after review * Add file attribute upload to product attributes (#826) * Support upload file attribute for products * Update after review * Refactor attribute values errors merging * Refactor product attribute value delete handling * Fix deleting file in file upload field * Fix delete attribute values errors handling * Add link to file upload field (#898) * Update file attributes updates (#899) * Update file attributes updates * Refactor file uploads handling * Move attributes utils to attributes directory * Fix product channel listing updates * Clear file field value if file is not passed as prop * Delete attribute values before update (#908) * Delete file attributes after file update * Triggr CI * Show skeleton in file upload field during loading Co-authored-by: Krzysztof Wolski <krzysztof.k.wolski@gmail.com>
2020-12-16 10:53:28 +00:00
import { makeStyles } from "@material-ui/core";
import Button from "@material-ui/core/Button";
import IconButton from "@material-ui/core/IconButton";
import Typography from "@material-ui/core/Typography";
import DeleteIcon from "@material-ui/icons/Delete";
import { FileFragment } from "@saleor/fragments/types/FileFragment";
import { commonMessages } from "@saleor/intl";
import React from "react";
import { useIntl } from "react-intl";
import Skeleton from "../Skeleton";
export interface FileChoiceType {
label: string;
value: string;
file?: FileFragment;
}
export interface FileUploadFieldProps {
inputProps?: React.DetailedHTMLProps<
React.InputHTMLAttributes<HTMLInputElement>,
HTMLInputElement
>;
className?: string;
disabled: boolean;
loading: boolean;
file: FileChoiceType;
error?: boolean;
helperText?: string;
onFileUpload: (file: File) => void;
onFileDelete: () => void;
}
const useStyles = makeStyles(
theme => ({
errorText: {
color: theme.palette.error.light
},
fileField: {
display: "none"
},
fileUrl: {
color: theme.palette.primary.main,
textDecoration: "none"
},
uploadFileContent: {
alignItems: "center",
color: theme.palette.primary.main,
display: "flex",
fontSize: "1rem"
},
uploadFileName: {
minWidth: "6rem"
}
}),
{ name: "FileUploadField" }
);
const FileUploadField: React.FC<FileUploadFieldProps> = props => {
const {
loading,
disabled,
file,
className,
error,
helperText,
onFileUpload,
onFileDelete,
inputProps
} = props;
const classes = useStyles({});
const intl = useIntl();
const fileInputAnchor = React.createRef<HTMLInputElement>();
const clickFileInput = () => fileInputAnchor.current.click();
const handleFileDelete = () => {
fileInputAnchor.current.value = "";
onFileDelete();
};
React.useEffect(() => {
if (!file.value) {
fileInputAnchor.current.value = "";
}
}, [file]);
return (
<>
<div className={className}>
{file.label ? (
<div className={classes.uploadFileContent}>
<div className={classes.uploadFileName}>
{loading ? (
<Skeleton />
) : (
<a
href={file.file?.url}
target="blank"
className={classes.fileUrl}
>
{file.label}
</a>
)}
</div>
<IconButton
color="primary"
onClick={handleFileDelete}
disabled={disabled || loading}
data-test="button-delete-file"
>
<DeleteIcon />
</IconButton>
</div>
) : (
<div>
<Button
onClick={clickFileInput}
disabled={disabled || loading}
variant="outlined"
color="primary"
data-test="button-upload-file"
>
{intl.formatMessage(commonMessages.chooseFile)}
</Button>
</div>
)}
{error && (
<Typography variant="caption" className={classes.errorText}>
{helperText}
</Typography>
)}
</div>
<input
className={classes.fileField}
id="fileUpload"
onChange={event => onFileUpload(event.target.files[0])}
type="file"
data-test="upload-file-input"
ref={fileInputAnchor}
{...inputProps}
/>
</>
);
};
FileUploadField.displayName = "FileUploadField";
export default FileUploadField;