Fix/csv import (#1397)

* feat: add ability to enable or disable header selection

* feat: limit to max of 200 records for now

* fix: bigger modal

* feat: add missing standard fields for company

* fix: person fields

* feat: add hotkeys on dialog

* feat: mobile device

* fix: company import error

* fix: csv import crash

* fix: use scoped hotkey
This commit is contained in:
Jérémy M
2023-09-04 11:50:12 +02:00
committed by GitHub
parent f29d843db9
commit c0cb3a47f3
19 changed files with 213 additions and 86 deletions

View File

@ -45,7 +45,7 @@ export const ModalCloseButton = ({ onClose }: ModalCloseButtonProps) => {
message: 'Are you sure? Your current information will not be saved.',
buttons: [
{ title: 'Cancel' },
{ title: 'Exit', onClick: onClose, accent: 'danger' },
{ title: 'Exit', onClick: onClose, accent: 'danger', role: 'confirm' },
],
});
}

View File

@ -3,15 +3,22 @@ import styled from '@emotion/styled';
import { useSpreadsheetImportInternal } from '@/spreadsheet-import/hooks/useSpreadsheetImportInternal';
import { Modal } from '@/ui/modal/components/Modal';
import { MOBILE_VIEWPORT } from '@/ui/theme/constants/theme';
import { ModalCloseButton } from './ModalCloseButton';
const StyledModal = styled(Modal)`
height: 61%;
min-height: 500px;
min-width: 600px;
min-height: 600px;
min-width: 800px;
position: relative;
width: 53%;
width: 63%;
@media (max-width: ${MOBILE_VIEWPORT}px) {
min-width: auto;
min-height: auto;
width: 100%;
height: 100%;
}
`;
const StyledRtlLtr = styled.div`

View File

@ -12,6 +12,8 @@ export const defaultSpreadsheetImportProps: Partial<SpreadsheetOptions<any>> = {
matchColumnsStepHook: async (table) => table,
dateFormat: 'yyyy-mm-dd', // ISO 8601,
parseRaw: true,
selectHeader: false,
maxRecords: 200,
} as const;
export const SpreadsheetImport = <T extends string>(

View File

@ -21,6 +21,8 @@ import { UserTableColumn } from './components/UserTableColumn';
const StyledContent = styled(Modal.Content)`
align-items: center;
padding-left: ${({ theme }) => theme.spacing(6)};
padding-right: ${({ theme }) => theme.spacing(6)};
`;
const StyledColumnsContainer = styled.div`
@ -224,6 +226,7 @@ export const MatchColumnsStep = <T extends string>({
title: 'Continue',
onClick: handleAlertOnContinue,
variant: 'primary',
role: 'confirm',
},
],
});

View File

@ -19,7 +19,7 @@ const StyledGrid = styled.div`
display: flex;
flex-direction: column;
margin-top: ${({ theme }) => theme.spacing(8)};
width: 75%;
width: 100%;
`;
type HeightProps = {

View File

@ -9,6 +9,8 @@ import { Modal } from '@/ui/modal/components/Modal';
const StyledContent = styled(Modal.Content)`
align-items: center;
padding-left: ${({ theme }) => theme.spacing(6)};
padding-right: ${({ theme }) => theme.spacing(6)};
`;
const StyledHeading = styled(Heading)`

View File

@ -5,6 +5,7 @@ import { useSpreadsheetImportInternal } from '@/spreadsheet-import/hooks/useSpre
import { Modal } from '@/ui/modal/components/Modal';
import { StepBar } from '@/ui/step-bar/components/StepBar';
import { useStepBar } from '@/ui/step-bar/hooks/useStepBar';
import { MOBILE_VIEWPORT } from '@/ui/theme/constants/theme';
import { UploadFlow } from './UploadFlow';
@ -15,6 +16,10 @@ const StyledHeader = styled(Modal.Header)`
padding: 0px;
padding-left: ${({ theme }) => theme.spacing(30)};
padding-right: ${({ theme }) => theme.spacing(30)};
@media (max-width: ${MOBILE_VIEWPORT}px) {
padding-left: ${({ theme }) => theme.spacing(4)};
padding-right: ${({ theme }) => theme.spacing(4)};
}
`;
const stepTitles = {

View File

@ -72,6 +72,7 @@ export const UploadFlow = ({ nextStep }: Props) => {
uploadStepHook,
selectHeaderStepHook,
matchColumnsStepHook,
selectHeader,
} = useSpreadsheetImportInternal();
const { enqueueSnackBar } = useSnackBar();
@ -109,10 +110,27 @@ export const UploadFlow = ({ nextStep }: Props) => {
const mappedWorkbook = await uploadStepHook(
mapWorkbook(workbook),
);
setState({
type: StepType.selectHeader,
data: mappedWorkbook,
});
if (selectHeader) {
setState({
type: StepType.selectHeader,
data: mappedWorkbook,
});
} else {
// Automatically select first row as header
const trimmedData = mappedWorkbook.slice(1);
const { data, headerValues } = await selectHeaderStepHook(
mappedWorkbook[0],
trimmedData,
);
setState({
type: StepType.matchColumns,
data,
headerValues,
});
}
} catch (e) {
errorToast((e as Error).message);
}

View File

@ -17,6 +17,11 @@ import { Modal } from '@/ui/modal/components/Modal';
import { generateColumns } from './components/columns';
import type { Meta } from './types';
const StyledContent = styled(Modal.Content)`
padding-left: ${({ theme }) => theme.spacing(6)};
padding-right: ${({ theme }) => theme.spacing(6)};
`;
const StyledToolbar = styled.div`
display: flex;
flex-direction: row;
@ -175,6 +180,7 @@ export const ValidationStep = <T extends string>({
title: 'Submit',
variant: 'primary',
onClick: submitData,
role: 'confirm',
},
],
});
@ -183,7 +189,7 @@ export const ValidationStep = <T extends string>({
return (
<>
<Modal.Content>
<StyledContent>
<Heading
title="Review your import"
description="Correct the issues and fill the missing data."
@ -225,7 +231,7 @@ export const ValidationStep = <T extends string>({
}}
/>
</StyledScrollContainer>
</Modal.Content>
</StyledContent>
<ContinueButton onContinue={onContinue} title="Confirm" />
</>
);

View File

@ -50,6 +50,8 @@ export type SpreadsheetOptions<Keys extends string> = {
parseRaw?: boolean;
// Use for right-to-left (RTL) support
rtl?: boolean;
// Allow header selection
selectHeader?: boolean;
};
export type RawData = Array<string | undefined>;