瀏覽代碼

[ui-importer] show field separator and other dropdown only for CSV (#4123)

Ram Prasad Agarwal 7 月之前
父節點
當前提交
827b1d3381

+ 39 - 8
desktop/core/src/desktop/js/apps/newimporter/ImporterFilePreview/SourceConfiguration/SourceConfiguration.test.tsx

@@ -3,15 +3,14 @@ import { render, fireEvent, waitFor } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
 import '@testing-library/jest-dom';
 import SourceConfiguration from './SourceConfiguration';
-import { FileFormatResponse } from '../../types';
-import { separator } from '../../constants';
+import { FileFormatResponse, ImporterFileTypes } from '../../types';
 
 describe('SourceConfiguration Component', () => {
   const mockSetFileFormat = jest.fn();
   const mockFileFormat: FileFormatResponse = {
     quoteChar: '"',
     recordSeparator: '\\n',
-    type: 'csv',
+    type: ImporterFileTypes.EXCEL,
     hasHeader: true,
     fieldSeparator: ',',
     status: 0
@@ -22,27 +21,59 @@ describe('SourceConfiguration Component', () => {
   });
 
   it('should render the component', () => {
-    const { getByText, getAllByRole } = render(
+    const { getByText } = render(
       <SourceConfiguration fileFormat={mockFileFormat} setFileFormat={mockSetFileFormat} />
     );
     expect(getByText('Configure source')).toBeInTheDocument();
-    expect(getAllByRole('combobox')).toHaveLength(5);
   });
 
-  it('calls setFileFormat on option change', async () => {
+  it('should call setFileFormat on option change', async () => {
     const { getByText, getAllByRole } = render(
       <SourceConfiguration fileFormat={mockFileFormat} setFileFormat={mockSetFileFormat} />
     );
 
     const selectElement = getAllByRole('combobox')[0];
     await userEvent.click(selectElement);
-    fireEvent.click(getByText(separator[3].label));
+    fireEvent.click(getByText('CSV'));
 
     await waitFor(() =>
       expect(mockSetFileFormat).toHaveBeenCalledWith({
         ...mockFileFormat,
-        fieldSeparator: separator[3].value
+        type: ImporterFileTypes.CSV
       })
     );
   });
+
+  it('should show fieldSepator and other downdown when fileType is CSV', () => {
+    const { getAllByRole, getByText } = render(
+      <SourceConfiguration
+        fileFormat={{ ...mockFileFormat, type: ImporterFileTypes.CSV }}
+        setFileFormat={mockSetFileFormat}
+      />
+    );
+
+    const selectElement = getAllByRole('combobox');
+
+    expect(selectElement).toHaveLength(5);
+    expect(getByText('File Type')).toBeInTheDocument();
+    expect(getByText('Has Header')).toBeInTheDocument();
+    expect(getByText('Field Separator')).toBeInTheDocument();
+    expect(getByText('Record Separator')).toBeInTheDocument();
+    expect(getByText('Quote Character')).toBeInTheDocument();
+  });
+
+  it('should not show fieldSepator and other downdown when fileType is not CSV', () => {
+    const { getAllByRole, getByText, queryByText } = render(
+      <SourceConfiguration fileFormat={mockFileFormat} setFileFormat={mockSetFileFormat} />
+    );
+
+    const selectElement = getAllByRole('combobox');
+
+    expect(selectElement).toHaveLength(2);
+    expect(getByText('File Type')).toBeInTheDocument();
+    expect(getByText('Has Header')).toBeInTheDocument();
+    expect(queryByText('Field Separator')).not.toBeInTheDocument();
+    expect(queryByText('Record Separator')).not.toBeInTheDocument();
+    expect(queryByText('Quote Character')).not.toBeInTheDocument();
+  });
 });

+ 3 - 1
desktop/core/src/desktop/js/apps/newimporter/ImporterFilePreview/SourceConfiguration/SourceConfiguration.tsx

@@ -45,6 +45,8 @@ const SourceConfiguration = ({
     [fileFormat, setFileFormat]
   );
 
+  const filteredSourceConfigs = sourceConfigs.filter(config => !config.hidden?.(fileFormat?.type));
+
   return (
     <details className="hue-importer-configuration">
       <summary className="hue-importer-configuration__summary">
@@ -52,7 +54,7 @@ const SourceConfiguration = ({
         {t('Configure source')}
       </summary>
       <div className="hue-importer-configuration-options">
-        {sourceConfigs.map(config => (
+        {filteredSourceConfigs.map(config => (
           <div key={config.name}>
             <label htmlFor={config.name}>{t(config.label)}</label>
             <Select

+ 2 - 2
desktop/core/src/desktop/js/apps/newimporter/ImporterSourceSelector/ImporterSourceSelector.tsx

@@ -19,7 +19,7 @@ import Button from 'cuix/dist/components/Button';
 import DocumentationIcon from '@cloudera/cuix-core/icons/react/DocumentationIcon';
 import { hueWindow } from 'types/types';
 
-import { FileMetaData, LocalFileUploadResponse } from '../types';
+import { FileMetaData, ImporterFileSource, LocalFileUploadResponse } from '../types';
 import { i18nReact } from '../../../utils/i18nReact';
 import { UPLOAD_LOCAL_FILE_API_URL } from '../api';
 import useSaveData from '../../../utils/hooks/useSaveData/useSaveData';
@@ -72,7 +72,7 @@ const ImporterSourceSelector = ({ setFileMetaData }: ImporterSourceSelectorProps
           setFileMetaData({
             path: data.local_file_url,
             type: data.file_type,
-            source: 'localfile'
+            source: ImporterFileSource.LOCAL
           });
         },
         onError: error => {

+ 26 - 19
desktop/core/src/desktop/js/apps/newimporter/constants.ts

@@ -14,7 +14,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import { FileFormatResponse } from './types';
+import { FileFormatResponse, ImporterFileTypes } from './types';
 
 export const separator = [
   { value: ',', label: 'Comma (,)' },
@@ -32,38 +32,45 @@ export const separator = [
 export const sourceConfigs: {
   name: keyof FileFormatResponse;
   label: string;
-  options: { label: string; value: string | boolean }[];
+  hidden?: (type?: ImporterFileTypes) => boolean;
+  options: {
+    label: string;
+    value: string | boolean;
+  }[];
 }[] = [
+  {
+    name: 'type',
+    label: 'File Type',
+    options: [
+      { value: ImporterFileTypes.CSV, label: 'CSV' },
+      { value: ImporterFileTypes.JSON, label: 'JSON' },
+      { value: ImporterFileTypes.EXCEL, label: 'Excel' }
+    ]
+  },
+  {
+    name: 'hasHeader',
+    label: 'Has Header',
+    options: [
+      { value: true, label: 'Yes' },
+      { value: false, label: 'No' }
+    ]
+  },
   {
     name: 'fieldSeparator',
     label: 'Field Separator',
+    hidden: (type?: ImporterFileTypes) => type !== ImporterFileTypes.CSV,
     options: separator
   },
   {
     name: 'recordSeparator',
     label: 'Record Separator',
+    hidden: (type?: ImporterFileTypes) => type !== ImporterFileTypes.CSV,
     options: separator
   },
   {
     name: 'quoteChar',
     label: 'Quote Character',
+    hidden: (type?: ImporterFileTypes) => type !== ImporterFileTypes.CSV,
     options: separator
-  },
-  {
-    name: 'hasHeader',
-    label: 'Has Header',
-    options: [
-      { value: true, label: 'Yes' },
-      { value: false, label: 'No' }
-    ]
-  },
-  {
-    name: 'type',
-    label: 'File Type',
-    options: [
-      { value: 'csv', label: 'CSV File' },
-      { value: 'json', label: 'JSON' },
-      { value: 'excel', label: 'Excel File' }
-    ]
   }
 ];

+ 15 - 4
desktop/core/src/desktop/js/apps/newimporter/types.ts

@@ -14,9 +14,20 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+export const enum ImporterFileTypes {
+  CSV = 'csv',
+  JSON = 'json',
+  EXCEL = 'excel'
+}
+
+export enum ImporterFileSource {
+  LOCAL = 'localfile',
+  REMOTE = 'file'
+}
+
 export interface LocalFileUploadResponse {
   local_file_url: string;
-  file_type: string;
+  file_type: ImporterFileTypes;
 }
 
 export interface FileFormatResponse {
@@ -25,13 +36,13 @@ export interface FileFormatResponse {
   quoteChar: string;
   recordSeparator: string;
   status: number;
-  type: string;
+  type: ImporterFileTypes;
 }
 
 export interface FileMetaData {
   path: string;
-  type?: string;
-  source: 'localfile' | 'file';
+  type: ImporterFileTypes;
+  source: ImporterFileSource;
 }
 
 export type GuessFieldTypesColumn = {