diff --git a/web/pgadmin/misc/file_manager/static/js/FileManagerModule.jsx b/web/pgadmin/misc/file_manager/static/js/FileManagerModule.jsx index fe486b714..d7f4672a2 100644 --- a/web/pgadmin/misc/file_manager/static/js/FileManagerModule.jsx +++ b/web/pgadmin/misc/file_manager/static/js/FileManagerModule.jsx @@ -74,6 +74,7 @@ export default class FileManagerModule { closeModal={closeModal} onCancel={onCancel} onOK={onOK} + sharedStorages={this.pgAdmin.server_mode == 'True' ? this.pgAdmin.shared_storage: []} /> ); }, { diff --git a/web/pgadmin/misc/file_manager/static/js/components/FileManager.jsx b/web/pgadmin/misc/file_manager/static/js/components/FileManager.jsx index 6b3365d45..8036976a5 100644 --- a/web/pgadmin/misc/file_manager/static/js/components/FileManager.jsx +++ b/web/pgadmin/misc/file_manager/static/js/components/FileManager.jsx @@ -21,7 +21,6 @@ import MoreHorizRoundedIcon from '@material-ui/icons/MoreHorizRounded'; import SyncRoundedIcon from '@material-ui/icons/SyncRounded'; import CreateNewFolderRoundedIcon from '@material-ui/icons/CreateNewFolderRounded'; import GetAppRoundedIcon from '@material-ui/icons/GetAppRounded'; -import pgAdmin from 'sources/pgadmin'; import gettext from 'sources/gettext'; import clsx from 'clsx'; import { FormFooterMessage, InputSelectNonSearch, InputText, MESSAGE_TYPE } from '../../../../../static/js/components/FormComponents'; @@ -307,7 +306,9 @@ export class FileManagerUtils { } setDialogView(view) { - this.config.options.defaultViewMode = view; + if(this.config.options != undefined) + this.config.options.defaultViewMode = view; + this.api.post(url_for('file_manager.save_file_dialog_view', { trans_id: this.transId, }), {view: view}) @@ -401,7 +402,7 @@ ConfirmFile.propTypes = { onNo: PropTypes.func }; -export default function FileManager({params, closeModal, onOK, onCancel}) { +export default function FileManager({params, closeModal, onOK, onCancel, sharedStorages=[]}) { const classes = useStyles(); const modalClasses = useModalStyles(); const apiObj = useMemo(()=>getApiInstance(), []); @@ -696,10 +697,9 @@ export default function FileManager({params, closeModal, onOK, onCancel}) { {Boolean(confirmText) && setConfirmFile([null, null])} onYes={onConfirmYes}/>} - { pgAdmin.server_mode == 'True' && pgAdmin.shared_storage.length > 0? + { sharedStorages.length > 0 && : <>} splitButton name="menu-shared-storage" ref={sharedSRef} onClick={toggleMenu} className={classes.sharedStorage}/> - : <> } { await openDir(fmUtilsObj.config?.options?.homedir, selectedSS); @@ -762,30 +762,33 @@ export default function FileManager({params, closeModal, onOK, onCancel}) { await openDir(fmUtilsObj.currPath, selectedSS); }}>{gettext('Show Hidden Files')} - - { - option.keepOpen = false; - await changeDir(option.value); - }}>{gettext('My Storage')} + { + sharedStorages.length > 0 && + + { + option.keepOpen = false; + await changeDir(option.value); + }}>{gettext('My Storage')} - { - pgAdmin.shared_storage.map((ss)=> { - return ( - { - option.keepOpen = false; - await changeDir(option.value); - }}>{gettext(ss)}); - }) - } + { + sharedStorages.map((ss)=> { + return ( + { + option.keepOpen = false; + await changeDir(option.value); + }}>{gettext(ss)}); + }) + } - + + } {showUploader && @@ -848,4 +851,5 @@ FileManager.propTypes = { closeModal: PropTypes.func, onOK: PropTypes.func, onCancel: PropTypes.func, + sharedStorages: PropTypes.array, }; diff --git a/web/pgadmin/static/js/components/Menu.jsx b/web/pgadmin/static/js/components/Menu.jsx index 7c185b598..31942ca4b 100644 --- a/web/pgadmin/static/js/components/Menu.jsx +++ b/web/pgadmin/static/js/components/Menu.jsx @@ -104,7 +104,7 @@ export const PgMenuItem = applyStatics(MenuItem)(({hasCheck=false, checked=false props.onClick(e); }; } - const dataLabel = typeof(children) == 'string' ? children : undefined; + const dataLabel = typeof(children) == 'string' ? children : props.datalabel; return {hasCheck && } {children} @@ -120,6 +120,7 @@ PgMenuItem.propTypes = { children: CustomPropTypes.children, closeOnCheck: PropTypes.bool, onClick: PropTypes.func, + dataLabel: PropTypes.string, }; export function usePgMenuGroup() { diff --git a/web/regression/javascript/file_manager/FileManager.spec.js b/web/regression/javascript/file_manager/FileManager.spec.js index 6955c731e..266977f89 100644 --- a/web/regression/javascript/file_manager/FileManager.spec.js +++ b/web/regression/javascript/file_manager/FileManager.spec.js @@ -67,7 +67,8 @@ const configData = { 'platform_type': 'darwin', 'show_volumes': true, 'homedir': '/home/', - 'last_selected_format': '*' + 'last_selected_format': '*', + 'storage_folder': '' }, 'security': { 'uploadPolicy': '', @@ -85,6 +86,8 @@ const configData = { } }; +const sharedStorageConfig = ['Shared Storage']; + const params={ dialog_type: 'select_file', }; @@ -123,6 +126,7 @@ describe('FileManger', ()=>{ closeModal={closeModal} onOK={onOK} onCancel={onCancel} + sharedStorages={sharedStorageConfig} {...props} /> ); @@ -150,6 +154,32 @@ describe('FileManger', ()=>{ }, 0); }); + it('Change Shared Storage', (done)=>{ + networkMock.onPost('/file_manager/init').reply(200, {'data': configData}); + let ctrl = ctrlMount({}); + setTimeout(()=>{ + ctrl.update(); + ctrl.find('button[name="menu-shared-storage"]').simulate('click'); + ctrl.find('Memo(MenuItem)[data-label="Shared Storage"]').simulate('click'); + ctrl.update(); + expect(ctrl.find('Shared Storage').length).toBe(0); + done(); + }, 0); + }); + + it('Change Storage to My Storage', (done)=>{ + networkMock.onPost('/file_manager/init').reply(200, {'data': configData}); + let ctrl = ctrlMount({}); + setTimeout(()=>{ + ctrl.update(); + ctrl.find('button[name="menu-shared-storage"]').simulate('click'); + ctrl.find('Memo(MenuItem)[data-label="my_storage"]').simulate('click'); + ctrl.update(); + expect(ctrl.find('my_storage').length).toBe(0); + done(); + }, 0); + }); + describe('getComparator', ()=>{ it('Filename', ()=>{ expect(getComparator({columnKey: 'Filename', direction: 'ASC'})({Filename:'a'}, {Filename:'b'})).toBe(-1); @@ -257,7 +287,7 @@ describe('FileManagerUtils', ()=>{ }); it('addFolder', async ()=>{ - let res = await fmObj.addFolder({Filename: 'newfolder'}); + let res = await fmObj.addFolder({Filename: 'newfolder', 'storage_folder': 'my_storage'}); expect(res).toEqual({ Filename: 'newfolder', Path: '/home/newfolder', @@ -279,10 +309,10 @@ describe('FileManagerUtils', ()=>{ it('deleteItem', async ()=>{ let row = {Filename: 'newfolder', Path: '/home/newfolder'}; - let path = await fmObj.deleteItem(row); + let path = await fmObj.deleteItem(row, ''); expect(path).toBe('/home/newfolder'); - path = await fmObj.deleteItem(row, 'file1'); + path = await fmObj.deleteItem(row, '', 'file1'); expect(path).toBe('/home/newfolder/file1'); }); @@ -317,7 +347,7 @@ describe('FileManagerUtils', ()=>{ it('downloadFile', async ()=>{ spyOn(pgUtils, 'downloadBlob'); - let row = {Filename: 'newfile1', Path: '/home/newfile1'}; + let row = {Filename: 'newfile1', Path: '/home/newfile1', 'storage_folder': 'my_storage'}; await fmObj.downloadFile(row); expect(pgUtils.downloadBlob).toHaveBeenCalledWith('blobdata', 'newfile1'); });