feat: validate the given imported sheet whether is empty

This commit is contained in:
Ahmed Bouhuolia
2024-04-01 02:57:30 +02:00
parent 22a016b56e
commit 785045dbad
7 changed files with 133 additions and 22 deletions

View File

@@ -0,0 +1,53 @@
import type { ReactNode } from 'react';
import { useState, createContext, useContext } from 'react';
interface AlertsManagerContextValue {
alerts: (string | number)[];
showAlert: (alert: string | number) => void;
hideAlert: (alert: string | number) => void;
hideAlerts: () => void;
isAlertActive: (alert: string | number) => boolean;
findAlert: (alert: string | number) => string | number | undefined;
}
const AlertsManagerContext = createContext<AlertsManagerContextValue>(
{} as AlertsManagerContextValue,
);
export function AlertsManager({ children }: { children: ReactNode }) {
const [alerts, setAlerts] = useState<(string | number)[]>([]);
const showAlert = (type: string | number): void => {
setAlerts([...alerts, type]);
};
const hideAlert = (type: string | number): void => {
alerts.filter((t) => t !== type);
};
const hideAlerts = (): void => {
setAlerts([]);
};
const isAlertActive = (type: string | number): boolean => {
return alerts.some((t) => t === type);
};
const findAlert = (type: string | number): number | string | undefined => {
return alerts.find((t) => t === type);
};
return (
<AlertsManagerContext.Provider
value={{
alerts,
showAlert,
hideAlert,
hideAlerts,
isAlertActive,
findAlert,
}}
>
{children}
</AlertsManagerContext.Provider>
);
}
export const useAlertsManager = () => useContext(AlertsManagerContext);

View File

@@ -3,8 +3,11 @@ import { Field } from 'formik';
import { Box, Group, Stack } from '@/components';
import styles from './ImportDropzone.module.css';
import { ImportDropzoneField } from './ImportDropzoneFile';
import { useAlertsManager } from './AlertsManager';
export function ImportDropzone() {
const { hideAlerts } = useAlertsManager();
return (
<Stack spacing={0}>
<Field id={'file'} name={'file'} type="file">
@@ -12,6 +15,7 @@ export function ImportDropzone() {
<ImportDropzoneField
value={form.file}
onChange={(file) => {
hideAlerts();
form.setFieldValue('file', file);
}}
/>

View File

@@ -5,7 +5,8 @@ import { Intent } from '@blueprintjs/core';
import { Formik, Form, FormikHelpers } from 'formik';
import * as Yup from 'yup';
import { useImportFileContext } from './ImportFileProvider';
import { ImportStepperStep } from './_types';
import { ImportAlert, ImportStepperStep } from './_types';
import { useAlertsManager } from './AlertsManager';
const initialValues = {
file: null,
@@ -28,6 +29,7 @@ export function ImportFileUploadForm({
formikProps,
formProps,
}: ImportFileUploadFormProps) {
const { showAlert, hideAlerts } = useAlertsManager();
const { mutateAsync: uploadImportFile } = useImportFileUpload();
const {
resource,
@@ -42,6 +44,7 @@ export function ImportFileUploadForm({
values: ImportFileUploadValues,
{ setSubmitting }: FormikHelpers<ImportFileUploadValues>,
) => {
hideAlerts();
if (!values.file) return;
setSubmitting(true);
@@ -69,6 +72,9 @@ export function ImportFileUploadForm({
message: 'The extenstion of uploaded file is not supported.',
});
}
if (data.errors.find((er) => er.type === 'IMPORTED_SHEET_EMPTY')) {
showAlert(ImportAlert.IMPORTED_SHEET_EMPTY);
}
setSubmitting(false);
});
};

View File

@@ -1,5 +1,5 @@
// @ts-nocheck
import { Classes } from '@blueprintjs/core';
import { Callout, Classes, Intent } from '@blueprintjs/core';
import { Stack } from '@/components';
import { ImportDropzone } from './ImportDropzone';
import { ImportSampleDownload } from './ImportSampleDownload';
@@ -7,29 +7,50 @@ import { ImportFileUploadForm } from './ImportFileUploadForm';
import { ImportFileUploadFooterActions } from './ImportFileFooterActions';
import { ImportFileContainer } from './ImportFileContainer';
import { useImportFileContext } from './ImportFileProvider';
import { AlertsManager, useAlertsManager } from './AlertsManager';
import { ImportAlert } from './_types';
function ImportFileUploadCallouts() {
const { isAlertActive } = useAlertsManager();
return (
<>
{isAlertActive(ImportAlert.IMPORTED_SHEET_EMPTY) && (
<Callout intent={Intent.DANGER} icon={null}>
The imported sheet is empty.
</Callout>
)}
</>
);
}
export function ImportFileUploadStep() {
const { exampleDownload } = useImportFileContext();
return (
<ImportFileUploadForm>
<ImportFileContainer>
<p
className={Classes.TEXT_MUTED}
style={{ marginBottom: 18, lineHeight: 1.6 }}
>
Download a sample file and compare it with your import file to ensure
it is properly formatted. It's not necessary for the columns to be in
the same order, you can map them later.
</p>
<AlertsManager>
<ImportFileUploadForm>
<ImportFileContainer>
<p
className={Classes.TEXT_MUTED}
style={{ marginBottom: 18, lineHeight: 1.6 }}
>
Download a sample file and compare it with your import file to
ensure it is properly formatted. It's not necessary for the columns
to be in the same order, you can map them later.
</p>
<Stack spacing={40}>
<ImportDropzone />
{exampleDownload && <ImportSampleDownload />}
</Stack>
</ImportFileContainer>
<Stack>
<ImportFileUploadCallouts />
<ImportFileUploadFooterActions />
</ImportFileUploadForm>
<Stack spacing={40}>
<ImportDropzone />
{exampleDownload && <ImportSampleDownload />}
</Stack>
</Stack>
</ImportFileContainer>
<ImportFileUploadFooterActions />
</ImportFileUploadForm>
</AlertsManager>
);
}

View File

@@ -3,3 +3,7 @@ export enum ImportStepperStep {
Mapping = 1,
Preview = 2,
}
export enum ImportAlert {
IMPORTED_SHEET_EMPTY = 'IMPORTED_SHEET_EMPTY'
}