Просмотр исходного кода

[frontend]Added new folder functionalities to storage browser

Nidhi Bhat G 1 год назад
Родитель
Сommit
527f957c7c

+ 24 - 18
desktop/core/src/desktop/js/apps/storageBrowser/InputModal/InputModal.tsx

@@ -13,9 +13,9 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
-import React, { useRef } from 'react';
+import React, { useState } from 'react';
 import Modal from 'cuix/dist/components/Modal';
-import { Input, InputRef } from 'antd';
+import { Input } from 'antd';
 import { i18nReact } from '../../../utils/i18nReact';
 
 import './InputModal.scss';
@@ -26,8 +26,8 @@ interface InputModalProps {
   inputLabel: string;
   inputPlaceholder?: string;
   okText?: string;
-  onCancel: () => void;
-  onOk: (name: string) => void;
+  onClose: () => void;
+  onCreate: (name: string) => void;
   showModal: boolean;
   title: string;
 }
@@ -44,35 +44,41 @@ const InputModal: React.FC<InputModalProps> = ({
   inputLabel,
   inputPlaceholder,
   okText,
-  onCancel,
-  onOk,
+  onClose,
+  onCreate,
   showModal,
   title
 }): JSX.Element => {
   const { t } = i18nReact.useTranslation();
-  const textInput = useRef<InputRef>(null);
-
-  const extractText = (): string => {
-    let nameText: string;
-    if (textInput.current !== null) {
-      nameText = textInput.current.input.value;
-    }
-    return nameText;
-  };
+  const [textInput, setTextInput] = useState<string>('');
 
   return (
     <Modal
       cancelText={t(cancelText)}
       className="hue-input-modal"
       okText={t(okText)}
-      onCancel={onCancel}
-      onOk={() => onOk(extractText())}
+      onCancel={() => {
+        setTextInput('');
+        onClose();
+      }}
+      onOk={() => {
+        onCreate(textInput);
+        setTextInput('');
+        onClose();
+      }}
       open={showModal}
       title={t(title)}
     >
       <div className="hue-input-modal__description">{t(description)}</div>
       <div className="hue-input-modal__input-label">{t(inputLabel)}</div>
-      <Input className="hue-input-modal__input" ref={textInput} placeholder={t(inputPlaceholder)} />
+      <Input
+        className="hue-input-modal__input"
+        value={textInput}
+        onInput={e => {
+          setTextInput((e.target as HTMLInputElement).value);
+        }}
+        placeholder={t(inputPlaceholder)}
+      />
     </Modal>
   );
 };

+ 33 - 16
desktop/core/src/desktop/js/apps/storageBrowser/StorageBrowserPage/StorageBrowserTabContents/StorageBrowserTabContent.tsx

@@ -32,8 +32,9 @@ import PlusCircleIcon from '@cloudera/cuix-core/icons/react/PlusCircleIcon';
 import { FileOutlined } from '@ant-design/icons';
 
 import PathBrowser from '../../../../reactComponents/FileChooser/PathBrowser/PathBrowser';
+import InputModal from '../../InputModal/InputModal';
 import StorageBrowserTable from '../StorageBrowserTable/StorageBrowserTable';
-import { fetchFiles } from '../../../../reactComponents/FileChooser/api';
+import { fetchFiles, mkdir } from '../../../../reactComponents/FileChooser/api';
 import {
   PathAndFileData,
   StorageBrowserTableData,
@@ -67,6 +68,8 @@ const StorageBrowserTabContent: React.FC<StorageBrowserTabContentProps> = ({
   const [sortOrder, setSortOrder] = useState<SortOrder>(SortOrder.NONE);
   //TODO: Add filter functionality
   const [filterData] = useState<string>('');
+  const [showNewFolderModal, setShowNewFolderModal] = useState<boolean>();
+  const [refreshKey, setRefreshKey] = useState<number>(0);
 
   const { t } = i18nReact.useTranslation();
 
@@ -84,7 +87,10 @@ const StorageBrowserTabContent: React.FC<StorageBrowserTabContentProps> = ({
         {
           icon: <FolderIcon />,
           key: 'new_folder',
-          label: t('New Folder')
+          label: t('New Folder'),
+          onClick: () => {
+            setShowNewFolderModal(true);
+          }
         }
       ]
     },
@@ -95,18 +101,8 @@ const StorageBrowserTabContent: React.FC<StorageBrowserTabContentProps> = ({
       children: [
         {
           icon: <ImportIcon />,
-          key: 'upload_file',
-          label: t('File')
-        },
-        {
-          icon: <ImportIcon />,
-          key: 'upload_folder',
-          label: t('Folder')
-        },
-        {
-          icon: <ImportIcon />,
-          key: 'upload_zip',
-          label: t('Zip Folder')
+          key: 'upload',
+          label: t('New Upload')
         }
       ]
     }
@@ -135,6 +131,18 @@ const StorageBrowserTabContent: React.FC<StorageBrowserTabContentProps> = ({
     }
   ];
 
+  //TODO:Add loading after calling mkdir api
+  const handleCreateNewFolder = (folderName: string) => {
+    mkdir(folderName, filePath)
+      .then(() => {
+        setRefreshKey(oldKey => oldKey + 1);
+      })
+      .catch(error => {
+        // eslint-disable-next-line no-restricted-syntax
+        console.log(error);
+      });
+  };
+
   useEffect(() => {
     setloadingFiles(true);
     fetchFiles(filePath, pageSize, pageNumber, filterData, sortByColumn, sortOrder)
@@ -161,7 +169,7 @@ const StorageBrowserTabContent: React.FC<StorageBrowserTabContentProps> = ({
       .finally(() => {
         setloadingFiles(false);
       });
-  }, [filePath, pageSize, pageNumber, sortByColumn, sortOrder]);
+  }, [filePath, pageSize, pageNumber, sortByColumn, sortOrder, refreshKey]);
 
   return (
     <Spin spinning={loadingFiles}>
@@ -226,7 +234,16 @@ const StorageBrowserTabContent: React.FC<StorageBrowserTabContentProps> = ({
           onSortOrderChange={setSortOrder}
           sortByColumn={sortByColumn}
           sortOrder={sortOrder}
-        ></StorageBrowserTable>
+        />
+        <InputModal
+          title={'Create New Folder'}
+          description={'You can add a new folder to your storage browser'}
+          inputLabel={'Enter folder name here'}
+          okText={'Create'}
+          showModal={showNewFolderModal}
+          onCreate={handleCreateNewFolder}
+          onClose={() => setShowNewFolderModal(!showNewFolderModal)}
+        />
       </div>
     </Spin>
   );

+ 10 - 1
desktop/core/src/desktop/js/reactComponents/FileChooser/api.ts

@@ -13,13 +13,14 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
-
+import axios, { AxiosResponse } from 'axios';
 import { get } from '../../api/utils';
 import { CancellablePromise } from '../../api/cancellablePromise';
 import { PathAndFileData, SortOrder } from './types';
 
 const FILESYSTEMS_API_URL = '/api/v1/storage/filesystems';
 const VIEWFILES_API_URl = '/api/v1/storage/view=';
+const MAKE_DIRECTORY_API_URL = '/api/v1/storage/mkdir';
 
 export interface ApiFileSystem {
   file_system: string;
@@ -65,3 +66,11 @@ export const fetchFiles = (
       descending
   );
 };
+
+export const mkdir = async (folderName: string, path: string): Promise<AxiosResponse> => {
+  const createDirFormData = new FormData();
+  createDirFormData.append('name', folderName);
+  createDirFormData.append('path', path);
+  const response = await axios.post(MAKE_DIRECTORY_API_URL, createDirFormData);
+  return response;
+};