feat: Add date format controll to import

This commit is contained in:
Ahmed Bouhuolia
2024-08-29 19:48:58 +02:00
parent c43123db76
commit 7e6f1efe30
11 changed files with 141 additions and 46 deletions

View File

@@ -14,7 +14,7 @@
th.label,
td.label{
width: 32% !important;
width: 30% !important;
}
thead{
@@ -31,16 +31,14 @@
tr td {
vertical-align: middle;
}
tr td{
:global(.bp4-popover-target .bp4-button),
:global(.bp4-popover-wrapper){
max-width: 250px;
}
}
}
}
.requiredSign{
color: rgb(250, 82, 82);
}
.columnSelectButton{
max-width: 250px;
min-width: 250px;
}

View File

@@ -8,9 +8,12 @@ import { EntityColumnField, useImportFileContext } from './ImportFileProvider';
import { CLASSES } from '@/constants';
import { ImportFileContainer } from './ImportFileContainer';
import { ImportStepperStep } from './_types';
import { ImportFileMapBootProvider } from './ImportFileMappingBoot';
import {
ImportFileMapBootProvider,
useImportFileMapBootContext,
} from './ImportFileMappingBoot';
import styles from './ImportFileMapping.module.scss';
import { getFieldKey } from './_utils';
import { getDateFieldKey, getFieldKey } from './_utils';
export function ImportFileMapping() {
const { importId, entityColumns } = useImportFileContext();
@@ -82,6 +85,7 @@ interface ImportFileMappingFieldsProps {
*/
function ImportFileMappingFields({ fields }: ImportFileMappingFieldsProps) {
const { sheetColumns } = useImportFileContext();
const { dateFormats } = useImportFileMapBootContext();
const items = useMemo(
() => sheetColumns.map((column) => ({ value: column, text: column })),
@@ -95,22 +99,35 @@ function ImportFileMappingFields({ fields }: ImportFileMappingFieldsProps) {
{column.required && <span className={styles.requiredSign}>*</span>}
</td>
<td className={styles.field}>
<Group spacing={4}>
<Group spacing={12} noWrap>
<FSelect
name={getFieldKey(column.key, column.group)}
name={`['${getFieldKey(column.key, column.group)}'].from`}
items={items}
popoverProps={{ minimal: true }}
minimal={true}
fill={true}
className={styles.columnSelectButton}
/>
{column.hint && (
<Hint content={column.hint} position={Position.BOTTOM} />
)}
{column.type === 'date' && (
<FSelect
name={getDateFieldKey(column.key, column.group)}
items={dateFormats}
placeholder={'Select date format'}
minimal={true}
fill={true}
valueAccessor={'key'}
textAccessor={'label'}
labelAccessor={''}
/>
)}
</Group>
</td>
</tr>
),
[items],
[items, dateFormats],
);
const columns = useMemo(
() => fields.map(columnMapper),

View File

@@ -2,8 +2,11 @@ import { Spinner } from '@blueprintjs/core';
import React, { createContext, useContext } from 'react';
import { Box } from '@/components';
import { useImportFileMeta } from '@/hooks/query/import';
import { useDateFormats } from '@/hooks/query';
interface ImportFileMapBootContextValue {}
interface ImportFileMapBootContextValue {
dateFormats: Array<any>;
}
const ImportFileMapBootContext = createContext<ImportFileMapBootContextValue>(
{} as ImportFileMapBootContextValue,
@@ -39,14 +42,22 @@ export const ImportFileMapBootProvider = ({
enabled: Boolean(importId),
});
// Fetch date format options.
const { data: dateFormats, isLoading: isDateFormatsLoading } =
useDateFormats();
const value = {
importFile,
isImportFileLoading,
isImportFileFetching,
dateFormats,
isDateFormatsLoading,
};
const isLoading = isDateFormatsLoading || isImportFileLoading;
return (
<ImportFileMapBootContext.Provider value={value}>
{isImportFileLoading ? (
{isLoading ? (
<Box style={{ padding: '2rem', textAlign: 'center' }}>
<Spinner size={26} />
</Box>

View File

@@ -13,6 +13,7 @@ export type EntityColumnField = {
required?: boolean;
hint?: string;
group?: string;
type: string;
};
export interface EntityColumn {

View File

@@ -6,8 +6,8 @@
flex: 1;
padding: 32px 20px;
padding-bottom: 80px;
min-width: 660px;
max-width: 760px;
min-width: 800px;
max-width: 800px;
width: 75%;
margin-left: auto;
margin-right: auto;

View File

@@ -12,4 +12,13 @@ export interface ImportFileMappingFormProps {
children: React.ReactNode;
}
export type ImportFileMappingFormValues = Record<string, string | null>;
export type ImportFileMappingFormValues = Record<
string,
{ from: string | null; dateFormat?: string }
>;
export type ImportFileMappingRes = {
from: string;
to: string;
group: string;
}[];

View File

@@ -17,13 +17,15 @@ import {
} from './ImportFileProvider';
import { useImportFileMapBootContext } from './ImportFileMappingBoot';
import { deepdash, transformToForm } from '@/utils';
import { ImportFileMappingFormValues } from './_types';
import { ImportFileMappingFormValues, ImportFileMappingRes } from './_types';
export const getFieldKey = (key: string, group = '') => {
return group ? `${group}.${key}` : key;
};
type ImportFileMappingRes = { from: string; to: string; group: string }[];
export const getDateFieldKey = (key: string, group: string = '') => {
return `${getFieldKey(key, group)}.dateFormat`;
};
/**
* Transformes the mapping form values to request.
@@ -34,10 +36,10 @@ export const transformValueToReq = (
value: ImportFileMappingFormValues,
): { mapping: ImportFileMappingRes[] } => {
const mapping = chain(value)
.thru(deepdash.index)
.pickBy((_value, key) => !isEmpty(get(value, key)))
.map((from, key) => ({
from,
.pickBy((_value, key) => !isEmpty(_value) && _value?.from)
.map((_value, key) => ({
from: _value.from,
dateFormat: _value.dateFormat,
to: key.includes('.') ? last(key.split('.')) : key,
group: key.includes('.') ? head(key.split('.')) : '',
}))
@@ -52,19 +54,23 @@ export const transformValueToReq = (
* @returns {Record<string, object | string>}
*/
export const transformResToFormValues = (
value: { from: string; to: string , group: string }[],
value: { from: string; to: string; group: string }[],
): Record<string, object | string> => {
return value?.reduce((acc, map) => {
const path = map?.group ? `${map.group}.${map.to}` : map.to;
set(acc, path, map.from);
const path = map?.group ? `['${map.group}.${map.to}']` : map.to;
const dateFormatObj = map?.dateFormat
? { dateFormat: map?.dateFormat }
: {};
set(acc, path, { from: map?.from, ...dateFormatObj });
return acc;
}, {});
};
/**
* Retrieves the initial values of mapping form.
* @param {EntityColumn[]} entityColumns
* @param {SheetColumn[]} sheetColumns
* Retrieves the initial values of mapping form.
* @param {EntityColumn[]} entityColumns
* @param {SheetColumn[]} sheetColumns
*/
const getInitialDefaultValues = (
entityColumns: EntityColumn[],
@@ -76,10 +82,10 @@ const getInitialDefaultValues = (
const _matched = sheetColumns.find(
(column) => lowerCase(column) === _name,
);
const _key = groupKey ? `${groupKey}.${key}` : key;
const _value = _matched ? _matched : '';
const path = groupKey ? `['${groupKey}.${key}']` : key;
const from = _matched ? _matched : '';
set(acc, _key, _value);
set(acc, path, { from });
});
return acc;
}, {});
@@ -102,7 +108,6 @@ export const useImportFileMappingInitialValues = () => {
() => getInitialDefaultValues(entityColumns, sheetColumns),
[entityColumns, sheetColumns],
);
return useMemo<Record<string, any>>(
() =>
assign(