|
@@ -1,5 +1,5 @@
|
|
|
import { makeStyles, Theme } from '@material-ui/core';
|
|
|
-import { FC, useContext, useMemo, useState } from 'react';
|
|
|
+import { FC, ReactElement, useContext, useMemo, useState } from 'react';
|
|
|
import { useTranslation } from 'react-i18next';
|
|
|
import DialogTemplate from '../customDialog/DialogTemplate';
|
|
|
import icons from '../icons/Icons';
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
InsertStepperEnum,
|
|
|
} from './Types';
|
|
|
import { Option } from '../customSelector/Types';
|
|
|
+import { parse } from 'papaparse';
|
|
|
|
|
|
const getStyles = makeStyles((theme: Theme) => ({
|
|
|
icon: {
|
|
@@ -51,7 +52,7 @@ const InsertContainer: FC<InsertContentProps> = ({
|
|
|
|
|
|
const { t: insertTrans } = useTranslation('insert');
|
|
|
const { t: btnTrans } = useTranslation('btn');
|
|
|
- const { handleCloseDialog } = useContext(rootContext);
|
|
|
+ const { handleCloseDialog, openSnackBar } = useContext(rootContext);
|
|
|
const [activeStep, setActiveStep] = useState<InsertStepperEnum>(
|
|
|
InsertStepperEnum.import
|
|
|
);
|
|
@@ -60,21 +61,34 @@ const InsertContainer: FC<InsertContentProps> = ({
|
|
|
);
|
|
|
// const [nextDisabled, setNextDisabled] = useState<boolean>(false);
|
|
|
|
|
|
+ // selected collection name
|
|
|
+ const [collectionValue, setCollectionValue] =
|
|
|
+ useState<string>(selectedCollection);
|
|
|
+ // selected partition name
|
|
|
+ const [partitionValue, setPartitionValue] =
|
|
|
+ useState<string>(selectedPartition);
|
|
|
+ // use contain field names yes as default
|
|
|
+ const [isContainFieldNames, setIsContainFieldNames] = useState<number>(1);
|
|
|
+ // uploaded file name
|
|
|
+ const [fileName, setFileName] = useState<string>('');
|
|
|
+ // uploaded csv data (type: string)
|
|
|
+ const [csvData, setCsvData] = useState<any[]>([]);
|
|
|
+
|
|
|
const BackIcon = icons.back;
|
|
|
|
|
|
+ // modal actions part, buttons label text or component
|
|
|
const { confirm, cancel } = useMemo(() => {
|
|
|
- /**
|
|
|
- * activeStep type is InsertStepperEnum
|
|
|
- * so index 0 represents import,
|
|
|
- * index 1 represents preview,
|
|
|
- * index 2 represents status
|
|
|
- */
|
|
|
- const labelList = [
|
|
|
- {
|
|
|
+ const labelMap: {
|
|
|
+ [key in InsertStepperEnum]: {
|
|
|
+ confirm: string;
|
|
|
+ cancel: string | ReactElement;
|
|
|
+ };
|
|
|
+ } = {
|
|
|
+ [InsertStepperEnum.import]: {
|
|
|
confirm: btnTrans('next'),
|
|
|
cancel: btnTrans('cancel'),
|
|
|
},
|
|
|
- {
|
|
|
+ [InsertStepperEnum.preview]: {
|
|
|
confirm: btnTrans('insert'),
|
|
|
cancel: (
|
|
|
<>
|
|
@@ -83,12 +97,12 @@ const InsertContainer: FC<InsertContentProps> = ({
|
|
|
</>
|
|
|
),
|
|
|
},
|
|
|
- {
|
|
|
+ [InsertStepperEnum.status]: {
|
|
|
confirm: btnTrans('done'),
|
|
|
cancel: '',
|
|
|
},
|
|
|
- ];
|
|
|
- return labelList[activeStep];
|
|
|
+ };
|
|
|
+ return labelMap[activeStep];
|
|
|
}, [activeStep, btnTrans, BackIcon, classes.icon]);
|
|
|
|
|
|
const { showActions, showCancel } = useMemo(() => {
|
|
@@ -98,13 +112,35 @@ const InsertContainer: FC<InsertContentProps> = ({
|
|
|
};
|
|
|
}, [insertStatus]);
|
|
|
|
|
|
- const handleInsertData = () => {
|
|
|
- // mock status change
|
|
|
+ const checkUploadFileValidation = (fieldNamesLength: number): boolean => {
|
|
|
+ return schemaOptions.length === fieldNamesLength;
|
|
|
+ };
|
|
|
+
|
|
|
+ const previewData = useMemo(() => {
|
|
|
+ // we only show top 4 results of uploaded csv data
|
|
|
+ const end = isContainFieldNames ? 5 : 4;
|
|
|
+ return csvData.slice(0, end);
|
|
|
+ }, [csvData, isContainFieldNames]);
|
|
|
+
|
|
|
+ const handleUploadedData = (csv: string) => {
|
|
|
+ const { data } = parse(csv);
|
|
|
+ const uploadFieldNamesLength = (data as string[])[0].length;
|
|
|
+ const validation = checkUploadFileValidation(uploadFieldNamesLength);
|
|
|
+ if (!validation) {
|
|
|
+ // open snackbar
|
|
|
+ openSnackBar(insertTrans('uploadFieldNamesLenWarning'), 'error');
|
|
|
+ // reset filename
|
|
|
+ setFileName('');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ setCsvData(data);
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleInsertData = async () => {
|
|
|
setInsertStauts(InsertStatusEnum.loading);
|
|
|
- handleInsert();
|
|
|
- setTimeout(() => {
|
|
|
- setInsertStauts(InsertStatusEnum.success);
|
|
|
- }, 500);
|
|
|
+ const res = await handleInsert();
|
|
|
+ const status = res ? InsertStatusEnum.success : InsertStatusEnum.error;
|
|
|
+ setInsertStauts(status);
|
|
|
};
|
|
|
|
|
|
const handleNext = () => {
|
|
@@ -144,13 +180,25 @@ const InsertContainer: FC<InsertContentProps> = ({
|
|
|
return (
|
|
|
<InsertImport
|
|
|
collectionOptions={collectionOptions}
|
|
|
- selectedCollection={selectedCollection}
|
|
|
partitionOptions={partitionOptions}
|
|
|
- selectedPartition={selectedPartition}
|
|
|
+ selectedCollection={collectionValue}
|
|
|
+ selectedPartition={partitionValue}
|
|
|
+ handleCollectionChange={setCollectionValue}
|
|
|
+ handlePartitionChange={setPartitionValue}
|
|
|
+ handleUploadedData={handleUploadedData}
|
|
|
+ fileName={fileName}
|
|
|
+ setFileName={setFileName}
|
|
|
/>
|
|
|
);
|
|
|
case InsertStepperEnum.preview:
|
|
|
- return <InsertPreview schemaOptions={schemaOptions} />;
|
|
|
+ return (
|
|
|
+ <InsertPreview
|
|
|
+ schemaOptions={schemaOptions}
|
|
|
+ data={previewData}
|
|
|
+ isContainFieldNames={isContainFieldNames}
|
|
|
+ handleIsContainedChange={setIsContainFieldNames}
|
|
|
+ />
|
|
|
+ );
|
|
|
// default represents InsertStepperEnum.status
|
|
|
default:
|
|
|
return <InsertStatus status={insertStatus} />;
|
|
@@ -168,6 +216,8 @@ const InsertContainer: FC<InsertContentProps> = ({
|
|
|
confirmDisabled={false}
|
|
|
showActions={showActions}
|
|
|
showCancel={showCancel}
|
|
|
+ // don't show close icon when insert not finish
|
|
|
+ showCloseIcon={insertStatus !== InsertStatusEnum.loading}
|
|
|
>
|
|
|
{generateContent(activeStep)}
|
|
|
</DialogTemplate>
|