Added remove remote mount

This commit is contained in:
2019-10-06 19:05:25 -05:00
parent 82fad7b706
commit aff7e8cb3a
10 changed files with 173 additions and 1 deletions

View File

@@ -27,6 +27,7 @@ import {
loadReleases, loadReleases,
setDismissUIUpgrade setDismissUIUpgrade
} from './redux/actions/release_version_actions'; } from './redux/actions/release_version_actions';
import YesNo from './components/YesNo/YesNo';
const Constants = require('./constants'); const Constants = require('./constants');
const Scheduler = require('node-schedule'); const Scheduler = require('node-schedule');
@@ -125,6 +126,7 @@ class App extends IPCContainer {
!this.props.DismissDependencies && !this.props.DismissDependencies &&
this.props.AllowMount; this.props.AllowMount;
const confirmDisplay = this.createModalConditionally(this.props.DisplayConfirmYesNo, <YesNo/>);
const infoDisplay = this.createModalConditionally(this.props.DisplayInfo, <InfoDetails/>, true); const infoDisplay = this.createModalConditionally(this.props.DisplayInfo, <InfoDetails/>, true);
const rebootDisplay = this.createModalConditionally(this.props.RebootRequired, <Reboot />); const rebootDisplay = this.createModalConditionally(this.props.RebootRequired, <Reboot />);
const configDisplay = this.createModalConditionally(showConfig, <Configuration version={selectedVersion} remoteSupported={remoteSupported} />); const configDisplay = this.createModalConditionally(showConfig, <Configuration version={selectedVersion} remoteSupported={remoteSupported} />);
@@ -165,6 +167,7 @@ class App extends IPCContainer {
{upgradeDisplay} {upgradeDisplay}
{configDisplay} {configDisplay}
{infoDisplay} {infoDisplay}
{confirmDisplay}
{downloadDisplay} {downloadDisplay}
{rebootDisplay} {rebootDisplay}
{errorDisplay} {errorDisplay}
@@ -208,6 +211,7 @@ const mapStateToProps = state => {
AppReady: state.common.AppReady, AppReady: state.common.AppReady,
DismissDependencies: state.install.DismissDependencies, DismissDependencies: state.install.DismissDependencies,
DisplayConfiguration: state.mounts.DisplayConfiguration, DisplayConfiguration: state.mounts.DisplayConfiguration,
DisplayConfirmYesNo: state.common.DisplayConfirmYesNo,
DisplayError: state.error.DisplayError, DisplayError: state.error.DisplayError,
DisplayInfo: state.error.DisplayInfo, DisplayInfo: state.error.DisplayInfo,
DisplaySelectAppPlatform: state.common.DisplaySelectAppPlatform, DisplaySelectAppPlatform: state.common.DisplaySelectAppPlatform,

View File

@@ -8,7 +8,9 @@ import Text from '../UI/Text/Text';
import Grid from '../UI/Grid/Grid'; import Grid from '../UI/Grid/Grid';
import configureImage from '../../assets/images/configure.png'; import configureImage from '../../assets/images/configure.png';
import RootElem from '../../hoc/RootElem/RootElem'; import RootElem from '../../hoc/RootElem/RootElem';
import {displayConfiguration, setProviderState} from '../../redux/actions/mount_actions'; import {displayConfiguration, removeRemoteMount, setProviderState} from '../../redux/actions/mount_actions';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import { faTrashAlt} from '@fortawesome/free-solid-svg-icons';
const mapStateToProps = (state, ownProps) => { const mapStateToProps = (state, ownProps) => {
return { return {
@@ -21,6 +23,7 @@ const mapStateToProps = (state, ownProps) => {
const mapDispatchToProps = dispatch => { const mapDispatchToProps = dispatch => {
return { return {
displayConfiguration: (provider, remote) => dispatch(displayConfiguration(provider, remote)), displayConfiguration: (provider, remote) => dispatch(displayConfiguration(provider, remote)),
removeRemoteMount: provider => dispatch(removeRemoteMount(provider)),
setProviderState: (provider, state) => dispatch(setProviderState(provider, state)), setProviderState: (provider, state) => dispatch(setProviderState(provider, state)),
} }
}; };
@@ -139,6 +142,27 @@ export default connect(mapStateToProps, mapDispatchToProps)(props => {
</RootElem> </RootElem>
); );
let removeControl;
if (props.remote) {
const removeDisabled = !props.MState.AllowMount || props.MState.Mounted;
const removeStyle = {
cursor: removeDisabled ? 'no-drop' : 'pointer'
};
const handleRemoveMount = () => {
if (!removeDisabled) {
props.removeRemoteMount(props.provider);
}
};
removeControl = (
<a col={dimensions=>dimensions.columns - 6}
href={void(0)}
onClick={handleRemoveMount}
row={secondRow + 3}
style={removeStyle}>
<FontAwesomeIcon icon={faTrashAlt}/>
</a>);
}
return ( return (
<div className={'MountItem'}> <div className={'MountItem'}>
<Grid noScroll> <Grid noScroll>
@@ -152,6 +176,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(props => {
{actionsDisplay} {actionsDisplay}
{autoMountControl} {autoMountControl}
{autoRestartControl} {autoRestartControl}
{removeControl}
</Grid> </Grid>
</div> </div>
); );

View File

View File

@@ -0,0 +1,41 @@
import {connect} from 'react-redux';
import Button from '../UI/Button/Button';
import Box from '../UI/Box/Box';
import React from 'react';
import './YesNo.css';
import {hideConfirmYesNo} from '../../redux/actions/common_actions';
const mapStateToProps = state => {
return {
Title: state.common.ConfirmTitle,
}
};
const mapDispatchToProps = dispatch => {
return {
hideConfirmYesNo: confirmed => dispatch(hideConfirmYesNo(confirmed)),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(props => {
return (
<Box dxStyle={{width: '180px', height: 'auto', padding: '8px'}}>
<div style={{width: '100%', height: 'auto'}}>
<h1 style={{width: '100%', textAlign: 'center'}}>{props.Title}</h1>
</div>
<table cellSpacing={5} width="100%">
<tbody>
<tr>
<td width="50%">
<Button buttonStyles={{width: '100%'}}
clicked={() => props.hideConfirmYesNo(true)}>Yes</Button>
</td>
<td width="50%">
<Button buttonStyles={{width: '100%'}}
clicked={() => props.hideConfirmYesNo(false)}>No</Button>
</td>
</tr>
</tbody>
</table>
</Box>);
});

View File

@@ -118,6 +118,9 @@ exports.IPC_Install_Upgrade_Reply = 'install_upgrade_reply';
exports.IPC_Mount_Drive = 'mount_drive'; exports.IPC_Mount_Drive = 'mount_drive';
exports.IPC_Mount_Drive_Reply = 'mount_drive_reply'; exports.IPC_Mount_Drive_Reply = 'mount_drive_reply';
exports.IPC_Remove_Remote_Mount = 'remove_remote_mount';
exports.IPC_Remove_Remote_Mount_Reply = 'remove_remote_mount_reply';
exports.IPC_Reboot_System = 'reboot_system'; exports.IPC_Reboot_System = 'reboot_system';
exports.IPC_Save_State = 'save_state'; exports.IPC_Save_State = 'save_state';

View File

@@ -3,6 +3,45 @@ import {createAction} from 'redux-starter-kit';
import {getIPCRenderer} from '../../utils'; import {getIPCRenderer} from '../../utils';
const ipcRenderer = getIPCRenderer(); const ipcRenderer = getIPCRenderer();
let yesNoResolvers = [];
export const confirmYesNo = title => {
return dispatch => {
return new Promise(resolve => {
dispatch(handleConfirmYesNo(true, title, resolve));
});
};
};
export const hideConfirmYesNo = confirmed => {
return dispatch => {
dispatch(handleConfirmYesNo(false, confirmed));
};
};
const handleConfirmYesNo = (show, titleOrConfirmed, resolve) => {
return dispatch => {
if (show) {
yesNoResolvers.push(resolve);
dispatch(displayConfirmYesNo(show, titleOrConfirmed))
} else {
yesNoResolvers[0](titleOrConfirmed);
yesNoResolvers.splice(0, 1);
dispatch(displayConfirmYesNo(false))
}
};
};
export const DISPLAY_CONFIRM_YES_NO = 'common/displayConfirmYesNo';
const displayConfirmYesNo = (show, title) => {
return {
type: DISPLAY_CONFIRM_YES_NO,
payload: {
show,
title
},
};
};
export const displaySelectAppPlatform = display => { export const displaySelectAppPlatform = display => {
return dispatch => { return dispatch => {

View File

@@ -1,6 +1,7 @@
import * as Constants from '../../constants'; import * as Constants from '../../constants';
import {createAction} from 'redux-starter-kit'; import {createAction} from 'redux-starter-kit';
import {getIPCRenderer} from '../../utils'; import {getIPCRenderer} from '../../utils';
import {confirmYesNo, displayConfirmYesNo} from './common_actions';
export const DISPLAY_CONFIGURATION = 'mounts/displayConfiguration'; export const DISPLAY_CONFIGURATION = 'mounts/displayConfiguration';
export const displayConfiguration = (provider, remote) => { export const displayConfiguration = (provider, remote) => {
@@ -13,6 +14,31 @@ export const displayConfiguration = (provider, remote) => {
}; };
}; };
export const removeRemoteMount = provider => {
return dispatch => {
dispatch(confirmYesNo('Delete [' + provider.substr(6) + ']?'))
.then(confirmed => {
if (confirmed) {
dispatch(removeRemoteMount2(provider));
}
});
};
};
const removeRemoteMount2 = provider => {
return dispatch => {
const ipcRenderer = getIPCRenderer();
ipcRenderer.once(Constants.IPC_Remove_Remote_Mount_Reply, (_, arg) => {
if (arg.data.Success) {
dispatch(removeRemoteMount3(provider));
}
});
ipcRenderer.send(Constants.IPC_Remove_Remote_Mount, provider.substr(6));
};
};
export const removeRemoteMount3 = createAction('mounts/removeRemoteMount3');
export const RESET_MOUNTS_STATE = 'mounts/resetMountsState'; export const RESET_MOUNTS_STATE = 'mounts/resetMountsState';
export const resetMountsState = () => { export const resetMountsState = () => {
return { return {

View File

@@ -1,5 +1,6 @@
import {createReducer} from 'redux-starter-kit'; import {createReducer} from 'redux-starter-kit';
import { import {
DISPLAY_CONFIRM_YES_NO,
notifyRebootRequired, notifyRebootRequired,
setAllowMount, setAllowMount,
setApplicationReady, setApplicationReady,
@@ -12,11 +13,20 @@ export const createCommonReducer = (platformInfo, version) => {
AllowMount: false, AllowMount: false,
AppPlatform: platformInfo.AppPlatform, AppPlatform: platformInfo.AppPlatform,
AppReady: false, AppReady: false,
DisplayConfirmYesNo: false,
ConfirmTitle: null,
DisplaySelectAppPlatform: false, DisplaySelectAppPlatform: false,
Platform: platformInfo.Platform, Platform: platformInfo.Platform,
RebootRequired: false, RebootRequired: false,
Version: version, Version: version,
}, { }, {
[DISPLAY_CONFIRM_YES_NO]: (state, action) => {
return {
...state,
DisplayConfirmYesNo: action.payload.show,
ConfirmTitle: action.payload.show ? action.payload.title : null,
}
},
[SET_DISPLAY_SELECT_APPPLATFORM]: (state, action) => { [SET_DISPLAY_SELECT_APPPLATFORM]: (state, action) => {
return { return {
...state, ...state,

View File

@@ -2,6 +2,7 @@ import * as Constants from '../../constants';
import {createReducer} from 'redux-starter-kit'; import {createReducer} from 'redux-starter-kit';
import { import {
DISPLAY_CONFIGURATION, DISPLAY_CONFIGURATION,
removeRemoteMount3,
RESET_MOUNTS_STATE, RESET_MOUNTS_STATE,
SET_ALLOW_MOUNT, SET_ALLOW_MOUNT,
setAutoMountProcessed, setAutoMountProcessed,
@@ -62,6 +63,16 @@ export const createMountReducer = state => {
DisplayRemoteConfiguration: action.payload.remote, DisplayRemoteConfiguration: action.payload.remote,
}; };
}, },
[removeRemoteMount3]: (state, action) => {
let providerState = {...state.ProviderState};
delete providerState[action.payload];
const remoteMounts = state.RemoteMounts.filter(i => i !== action.payload);
return {
...state,
ProviderState: providerState,
RemoteMounts: remoteMounts,
};
},
[RESET_MOUNTS_STATE]: (state, action) => { [RESET_MOUNTS_STATE]: (state, action) => {
return { return {
...state, ...state,

View File

@@ -2,6 +2,7 @@ const Constants = require('../../constants');
const fs = require('fs'); const fs = require('fs');
const helpers = require('../../helpers'); const helpers = require('../../helpers');
const os = require('os'); const os = require('os');
const path = require('path');
let expectedUnmount = {}; let expectedUnmount = {};
let firstMountCheck = true; let firstMountCheck = true;
@@ -230,6 +231,18 @@ const addListeners = (ipcMain, setTrayImage, standardIPCReply) => {
} }
}); });
ipcMain.on(Constants.IPC_Remove_Remote_Mount, (event, data) => {
data = data.replace(':', '_');
const dataDirectory = path.resolve(path.join(helpers.getDataDirectory(), '..', 'remote', data));
try {
helpers.removeDirectoryRecursively(dataDirectory);
standardIPCReply(event, Constants.IPC_Remove_Remote_Mount_Reply, {DataDirectory: dataDirectory});
} catch (e) {
standardIPCReply(event, Constants.IPC_Remove_Remote_Mount_Reply, {DataDirectory: dataDirectory}, e);
}
});
ipcMain.on(Constants.IPC_Unmount_All_Drives, (event, data) => { ipcMain.on(Constants.IPC_Unmount_All_Drives, (event, data) => {
unmountAllDrives(); unmountAllDrives();
standardIPCReply(event, Constants.IPC_Unmount_All_Drives_Reply); standardIPCReply(event, Constants.IPC_Unmount_All_Drives_Reply);