feat: style tweaks to upload attachments popover

This commit is contained in:
Ahmed Bouhuolia
2024-05-29 19:03:21 +02:00
parent ceb133e29a
commit 6e50de1d28
5 changed files with 97 additions and 41 deletions

View File

@@ -6,7 +6,7 @@ export class AttachmentTransformer extends Transformer {
* @returns {string[]} * @returns {string[]}
*/ */
public excludeAttributes = (): string[] => { public excludeAttributes = (): string[] => {
return ['*']; return ['id', 'createdAt'];
}; };
/** /**
@@ -14,6 +14,6 @@ export class AttachmentTransformer extends Transformer {
* @returns {string[]} * @returns {string[]}
*/ */
public includeAttributes = (): string[] => { public includeAttributes = (): string[] => {
return ['extension', 'key']; return [];
}; };
} }

View File

@@ -1,9 +1,8 @@
.popover :global .bp4-popover-content{ .popover :global .bp4-popover-content{
min-width: 450px; min-width: 600px;
} }
.attachmentButton:not([class*=bp4-intent-]) { .attachmentButton:not([class*=bp4-intent-]) {
&, &,
&:hover{ &:hover{

View File

@@ -4,9 +4,9 @@
.hintText{ .hintText{
display: flex; display: flex;
font-size: 12px; font-size: 11px;
margin-top: 6px; margin-top: 6px;
color: #8F99A8; color: #738091;
justify-content: space-between; justify-content: space-between;
} }
@@ -15,27 +15,36 @@
} }
.attachmentItem{ .attachmentItem{
border: 1px solid #D3D8DE; border-top: 1px solid #D3D8DE;
border-radius: 3px; border-left: 1px solid #D3D8DE;
padding: 6px 10px; border-right: 1px solid #D3D8DE;
padding: 10px 14px;
justify-content: space-between; justify-content: space-between;
&:first-child {
border-radius: 3px 3px 0 0;
}
&:last-child{
border-radius: 0 0 3px 3px;
border-bottom: 1px solid #D3D8DE;
}
} }
.attachmentFilenameText{ .attachmentFilenameText{
color: #404854;
} }
.attachmentSizeText{ .attachmentSizeText,
font-size: 12px; .attachmentLoadingText{
font-size: 13px;
color: #738091; color: #738091;
} }
.attachmentContent{ .attachmentContent{
padding-left: 8px;
} }
.attachmentIcon{ .attachmentIcon{
color: #8F99A8; color: #626b7c;
} }
.label{ .label{
@@ -47,3 +56,8 @@
min-height: 140px; min-height: 140px;
padding: 10px; padding: 10px;
} }
.attachmentIconWrap{
width: 20PX;
text-align: right;
}

View File

@@ -1,4 +1,5 @@
// @ts-nocheck // @ts-nocheck
import { useState } from 'react';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import { Button, Intent, Text, Spinner } from '@blueprintjs/core'; import { Button, Intent, Text, Spinner } from '@blueprintjs/core';
import { Box, Group, Icon, Stack } from '@/components'; import { Box, Group, Icon, Stack } from '@/components';
@@ -7,7 +8,10 @@ import {
ImportDropzoneFieldProps, ImportDropzoneFieldProps,
} from '@/containers/Import/ImportDropzoneFile'; } from '@/containers/Import/ImportDropzoneFile';
import { useUncontrolled } from '@/hooks/useUncontrolled'; import { useUncontrolled } from '@/hooks/useUncontrolled';
import { useUploadAttachments } from '@/hooks/query/attachments'; import {
useGetPresignedUrlAttachment,
useUploadAttachments,
} from '@/hooks/query/attachments';
import { formatBytes } from '../Sales/Invoices/InvoiceForm/utils'; import { formatBytes } from '../Sales/Invoices/InvoiceForm/utils';
import styles from './UploadAttachmentPopoverContent.module.scss'; import styles from './UploadAttachmentPopoverContent.module.scss';
import { MIME_TYPES } from '@/components/Dropzone/mine-types'; import { MIME_TYPES } from '@/components/Dropzone/mine-types';
@@ -20,7 +24,7 @@ interface AttachmentFileCommon {
} }
interface AttachmentFileLoaded extends AttachmentFileCommon {} interface AttachmentFileLoaded extends AttachmentFileCommon {}
interface AttachmentFileLoading extends AttachmentFileCommon { interface AttachmentFileLoading extends AttachmentFileCommon {
_loading: boolean; loading: boolean;
} }
type AttachmentFile = AttachmentFileLoaded | AttachmentFileLoading; type AttachmentFile = AttachmentFileLoaded | AttachmentFileLoading;
@@ -62,7 +66,7 @@ export function UploadAttachmentsPopoverContent({
return { return {
...localFile, ...localFile,
key: newKey, key: newKey,
_loading: false, loading: false,
}; };
} }
return localFile; return localFile;
@@ -100,7 +104,7 @@ export function UploadAttachmentsPopoverContent({
originName: file.name, originName: file.name,
size: file.size, size: file.size,
key, key,
_loading: true, loading: true,
}, },
...localFiles, ...localFiles,
]); ]);
@@ -130,35 +134,38 @@ export function UploadAttachmentsPopoverContent({
{...dropzoneFieldProps} {...dropzoneFieldProps}
/> />
<Group className={styles.hintText}> <Group className={styles.hintText}>
<Box>Formats: CSV, XLSX</Box>
<Box>Maximum: 25MB</Box> <Box>Maximum: 25MB</Box>
</Group> </Group>
</Stack> </Stack>
{!isEmpty(localFiles) && ( {!isEmpty(localFiles) && (
<Stack spacing={8} className={styles.attachments}> <Stack spacing={0} className={styles.attachments}>
{localFiles.map((localFile: AttachmentFile, index: number) => ( {localFiles.map((localFile: AttachmentFile, index: number) => (
<Group <Group
position={'space-between'} position={'space-between'}
className={styles.attachmentItem} className={styles.attachmentItem}
key={index} key={index}
> >
<Group spacing={16} className={styles.attachmentContent}> <Group spacing={14} className={styles.attachmentContent}>
{localFile._loading ? ( <div className={styles.attachmentIconWrap}>
<Spinner size={20} /> {localFile.loading ? (
) : ( <Spinner size={20} />
<Icon ) : (
icon={'media'} <Icon
iconSize={16} icon={'media'}
className={styles.attachmentIcon} iconSize={16}
/> className={styles.attachmentIcon}
)} />
)}
</div>
<Stack spacing={2}> <Stack spacing={2}>
<Text className={styles.attachmentFilenameText}> <Text className={styles.attachmentFilenameText}>
{localFile.originName} {localFile.originName}
</Text> </Text>
{localFile._loading ? ( {localFile.loading ? (
<Text>Loading...</Text> <Text className={styles.attachmentLoadingText}>
Loading...
</Text>
) : ( ) : (
<Text className={styles.attachmentSizeText}> <Text className={styles.attachmentSizeText}>
{formatBytes(localFile.size)} {formatBytes(localFile.size)}
@@ -167,11 +174,9 @@ export function UploadAttachmentsPopoverContent({
</Stack> </Stack>
</Group> </Group>
{!localFile._loading && ( {!localFile.loading && (
<Group spacing={0}> <Group spacing={2}>
<Button small minimal> <ViewButton fileKey={localFile.key} />
View
</Button>
<Button <Button
small small
minimal minimal
@@ -190,3 +195,30 @@ export function UploadAttachmentsPopoverContent({
</div> </div>
); );
} }
const ViewButton = ({ fileKey }: { fileKey: string }) => {
const [isLoading, setLoading] = useState<boolean>(false);
const { mutateAsync: getAttachmentPresignedUrl } =
useGetPresignedUrlAttachment();
const handleViewBtnClick = (key: string) => () => {
setLoading(true);
getAttachmentPresignedUrl(key).then((data) => {
window.open(data.presigned_url);
setLoading(false);
});
};
return (
<Button
small
minimal
onClick={handleViewBtnClick(fileKey)}
disabled={isLoading}
intent={Intent.PRIMARY}
>
View
</Button>
);
};

View File

@@ -2,10 +2,6 @@
import { useMutation } from 'react-query'; import { useMutation } from 'react-query';
import useApiRequest from '../useRequest'; import useApiRequest from '../useRequest';
const commonInvalidateQueries = (query) => {
// Invalidate accounts.
};
/** /**
* Uploads the given attachments. * Uploads the given attachments.
*/ */
@@ -29,3 +25,18 @@ export function useDeleteAttachment(props) {
props, props,
); );
} }
/**
* Uploads the given attachments.
*/
export function useGetPresignedUrlAttachment(props) {
const apiRequest = useApiRequest();
return useMutation(
(key: string) =>
apiRequest
.get(`/attachments/${key}/presigned-url`)
.then((res) => res.data),
props,
);
}