Partial import processing
This commit is contained in:
27
src/App.js
27
src/App.js
@@ -61,9 +61,9 @@ class App extends IPCContainer {
|
||||
(prevProps.ReleaseVersion !== this.props.ReleaseVersion) ||
|
||||
(prevProps.VersionLookup !== this.props.VersionLookup)) {
|
||||
this.props.saveState();
|
||||
} else if (Object.keys(this.props.ProviderState).filter(k=> {
|
||||
return this.props.ProviderState[k] !== prevProps.ProviderState[k];
|
||||
}).length > 0) {
|
||||
} else if (Object.keys(this.props.ProviderState).filter(k => {
|
||||
return this.props.ProviderState[k] !== prevProps.ProviderState[k];
|
||||
}).length > 0) {
|
||||
this.props.saveState();
|
||||
}
|
||||
}
|
||||
@@ -105,7 +105,7 @@ class App extends IPCContainer {
|
||||
!missingDependencies &&
|
||||
!this.props.InstallActive;
|
||||
|
||||
const remoteSupported = this.props.LocationsLookup[selectedVersion] &&
|
||||
const remoteSupported = this.props.LocationsLookup[selectedVersion] &&
|
||||
this.props.LocationsLookup[selectedVersion].supports_remote;
|
||||
|
||||
const gooboxS3Supported = this.props.LocationsLookup[selectedVersion] &&
|
||||
@@ -155,23 +155,24 @@ class App extends IPCContainer {
|
||||
const showSkynetImport = !showConfig &&
|
||||
!showDependencies &&
|
||||
!this.props.DownloadActive &&
|
||||
!this.props.DisplayError &&
|
||||
!this.props.DisplayInfo &&
|
||||
!showNewReleases &&
|
||||
!this.props.RebootRequired &&
|
||||
!this.props.DisplaySelectAppPlatform &&
|
||||
!showUpgrade &&
|
||||
this.props.DisplayImport;
|
||||
|
||||
const configDisplay = createModalConditionally(showConfig, <Configuration version={selectedVersion} remoteSupported={remoteSupported} />);
|
||||
const configDisplay = createModalConditionally(showConfig, <Configuration version={selectedVersion}
|
||||
remoteSupported={remoteSupported}/>);
|
||||
const confirmDisplay = createModalConditionally(this.props.DisplayConfirmYesNo, <YesNo/>);
|
||||
const dependencyDisplay = createModalConditionally(showDependencies, <DependencyList/>, false, this.props.InstallActive);
|
||||
const downloadDisplay = createModalConditionally(this.props.DownloadActive, <DownloadProgress />, false, true);
|
||||
const dependencyDisplay = createModalConditionally(showDependencies,
|
||||
<DependencyList/>, false, this.props.InstallActive);
|
||||
const downloadDisplay = createModalConditionally(this.props.DownloadActive, <DownloadProgress/>, false, true);
|
||||
const errorDisplay = createModalConditionally(this.props.DisplayError, <ErrorDetails/>, true);
|
||||
const infoDisplay = createModalConditionally(this.props.DisplayInfo, <InfoDetails/>, true);
|
||||
const newReleasesDisplay = createModalConditionally(showNewReleases, <NewReleases/>);
|
||||
const rebootDisplay = createModalConditionally(this.props.RebootRequired, <Reboot />);
|
||||
const selectAppPlatformDisplay = createModalConditionally(this.props.DisplaySelectAppPlatform, <SelectAppPlatform/>);
|
||||
const rebootDisplay = createModalConditionally(this.props.RebootRequired, <Reboot/>);
|
||||
const selectAppPlatformDisplay = createModalConditionally(this.props.DisplaySelectAppPlatform,
|
||||
<SelectAppPlatform/>);
|
||||
const upgradeDisplay = createModalConditionally(showUpgrade, <UpgradeUI/>);
|
||||
const importDisplay = createModalConditionally(showSkynetImport, <SkynetImport/>);
|
||||
|
||||
@@ -233,7 +234,7 @@ class App extends IPCContainer {
|
||||
col={dimensions => dimensions.columns - 6}
|
||||
colSpan={5}
|
||||
row={1}
|
||||
rowSpan={remain=>remain - 1}/>
|
||||
rowSpan={remain => remain - 1}/>
|
||||
</Grid>
|
||||
</Box>
|
||||
</div>
|
||||
@@ -294,7 +295,7 @@ const mapStateToProps = state => {
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
displaySelectAppPlatform: display => dispatch(displaySelectAppPlatform(display)),
|
||||
loadReleases: ()=> dispatch(loadReleases()),
|
||||
loadReleases: () => dispatch(loadReleases()),
|
||||
notifyError: (msg, critical, callback) => dispatch(notifyError(msg, critical, callback)),
|
||||
saveState: () => dispatch(saveState()),
|
||||
setDismissNewReleasesAvailable: dismiss => dispatch(setDismissNewReleasesAvailable),
|
||||
|
||||
@@ -20,7 +20,7 @@ const mapDispatchToProps = dispatch => {
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
||||
let msg = props.InfoMessage.message;
|
||||
const classes = ['InfoDetailsContent'];
|
||||
if (props.InfoMessage.message.startsWith("!alternate!")) {
|
||||
if (props.InfoMessage.message.startsWith('!alternate!')) {
|
||||
classes.push('Alternate');
|
||||
msg = props.InfoMessage.message.substr('!alternate!'.length)
|
||||
}
|
||||
|
||||
@@ -5,12 +5,16 @@ import './SkynetImport.css'
|
||||
import Box from '../../components/UI/Box/Box';
|
||||
import Button from '../../components/UI/Button/Button';
|
||||
import {displaySkynetImport} from '../../redux/actions/skynet_actions';
|
||||
import {notifyInfo} from '../../redux/actions/error_actions';
|
||||
import {
|
||||
notifyError,
|
||||
notifyInfo
|
||||
} from '../../redux/actions/error_actions';
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
displaySkynetImport: display => dispatch(displaySkynetImport(display)),
|
||||
notifyInfo: msg => dispatch(notifyInfo("Import Syntax", msg)),
|
||||
notifyInfo: msg => dispatch(notifyInfo('Import Syntax', msg)),
|
||||
notifyError: msg => dispatch(notifyError(msg)),
|
||||
}
|
||||
};
|
||||
|
||||
@@ -21,40 +25,93 @@ export default connect(null, mapDispatchToProps)(class extends Component {
|
||||
};
|
||||
|
||||
displaySyntax = () => {
|
||||
const msg = "!alternate!To import Skylinks into the root directory, list each Skylink on a new line:\n" +
|
||||
" AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA\n" +
|
||||
" AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg\n" +
|
||||
"\n" +
|
||||
"To import Skylinks to new or existing directories, use the following syntax:\n" +
|
||||
" directory=\"/my/sub/dir\",skylink=\"AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA\"\n" +
|
||||
" directory=\"/my/sub/dir2\",skylink=\"AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg\"\n" +
|
||||
"\n" +
|
||||
"You can also specify a password if this in an encrypted Repertory Skylink:\n" +
|
||||
" directory=\"/my/sub/dir\",skylink=\"AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA\",token=\"My Password\"\n" +
|
||||
" directory=\"/my/sub/dir\",skylink=\"AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg\",token=\"My Password\"\n" +
|
||||
"\n" +
|
||||
"To import JSON Skylinks, use the following syntax:\n" +
|
||||
" [\n" +
|
||||
" {\n" +
|
||||
" \"directory\": \"/\",\n" +
|
||||
" \"skylink\": \"AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA\",\n" +
|
||||
" \"token\": \"My Password\"\n" +
|
||||
" },\n" +
|
||||
" {\n" +
|
||||
" \"directory\": \"/my/sub/dir\",\n" +
|
||||
" \"skylink\": \"AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg\",\n" +
|
||||
" \"token\": \"My Password\"\n" +
|
||||
" }\n" +
|
||||
" ]";
|
||||
const msg = '!alternate!To import Skylinks into the root directory, list each Skylink on a new line:\n' +
|
||||
' AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA\n' +
|
||||
' AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg\n' +
|
||||
'\n' +
|
||||
'To import Skylinks to new or existing directories, use the following syntax:\n' +
|
||||
' directory="/my/sub/dir",skylink="AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA"\n' +
|
||||
' directory="/my/sub/dir2",skylink="AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg"\n' +
|
||||
'\n' +
|
||||
'You can also specify a password if this in an encrypted Repertory Skylink:\n' +
|
||||
' directory="/my/sub/dir",skylink="AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA",token="My Password"\n' +
|
||||
' directory="/my/sub/dir",skylink="AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg",token="My Password"\n' +
|
||||
'\n' +
|
||||
'To import JSON Skylinks, use the following syntax:\n' +
|
||||
' [\n' +
|
||||
' {\n' +
|
||||
' "directory": "/",\n' +
|
||||
' "skylink": "AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA",\n' +
|
||||
' "token": "My Password"\n' +
|
||||
' },\n' +
|
||||
' {\n' +
|
||||
' "directory": "/my/sub/dir",\n' +
|
||||
' "skylink": "AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg",\n' +
|
||||
' "token": "My Password"\n' +
|
||||
' }\n' +
|
||||
' ]';
|
||||
this.props.notifyInfo(msg)
|
||||
}
|
||||
|
||||
processNext = () => {
|
||||
const items = this.state.import_list.split('\n');
|
||||
let jsonItems = [];
|
||||
try {
|
||||
for (let item of items) {
|
||||
item = item.trim();
|
||||
if (item.startsWith('[')) {
|
||||
jsonItems = JSON.parse(this.state.import_list.trim());
|
||||
break;
|
||||
} else if (item.indexOf('=') >= 0) {
|
||||
const parts = item.split(',')
|
||||
let importItem = {
|
||||
directory: '/',
|
||||
skylink: '',
|
||||
token: '',
|
||||
};
|
||||
for (let part of parts) {
|
||||
part = part.trim();
|
||||
const pair = part.split('=');
|
||||
if (pair.length !== 2) {
|
||||
throw new Error('Invalid syntax for import: directory="",skylink="",token=""');
|
||||
}
|
||||
importItem = {
|
||||
...importItem,
|
||||
[pair[0].trim()]: pair[1].trim().replace(/"/g, ''),
|
||||
};
|
||||
}
|
||||
if (!importItem.skylink) {
|
||||
throw new Error('Invalid syntax for import: directory="",skylink="",token=""');
|
||||
}
|
||||
jsonItems.push(importItem);
|
||||
} else if (item.length > 0) {
|
||||
jsonItems.push({
|
||||
directory: '/',
|
||||
skylink: item,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (jsonItems.length === 0) {
|
||||
throw new Error('Nothing to import');
|
||||
}
|
||||
console.log(jsonItems);
|
||||
} catch (e) {
|
||||
this.props.notifyError(e);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Box dxDark dxStyle={{height: 'auto', padding: 'var(--default_spacing)', width: 'calc(100vw - (var(--default_spacing) * 4)'}}>
|
||||
<div style={{float: 'right', margin: 0, padding: 0, marginTop: '-4px', boxSizing: 'border-box', display: 'block'}}>
|
||||
<Box dxDark dxStyle={{
|
||||
height: 'auto',
|
||||
padding: 'var(--default_spacing)',
|
||||
width: 'calc(100vw - (var(--default_spacing) * 4)'
|
||||
}}>
|
||||
<div
|
||||
style={{float: 'right', margin: 0, padding: 0, marginTop: '-4px', boxSizing: 'border-box', display: 'block'}}>
|
||||
<a href={'#'}
|
||||
onClick={()=>this.props.displaySkynetImport(false)}
|
||||
onClick={() => this.props.displaySkynetImport(false)}
|
||||
style={{cursor: 'pointer'}}>X</a>
|
||||
</div>
|
||||
<h1 className={'SkynetImportHeading'}>Import List</h1>
|
||||
@@ -65,11 +122,17 @@ export default connect(null, mapDispatchToProps)(class extends Component {
|
||||
import_list: e.target.value,
|
||||
})}
|
||||
value={this.state.import_list}
|
||||
rows={10} />
|
||||
rows={10}/>
|
||||
|
||||
<div className={'SkynetImportButtons'}>
|
||||
<Button buttonStyles={{height: 'auto', marginTop: 'var(--default_spacing)', width: 'auto'}} clicked={this.displaySyntax}>Import Syntax...</Button>
|
||||
<Button buttonStyles={{height: 'auto', marginLeft: 'var(--default_spacing)', marginTop: 'var(--default_spacing)', width: 'auto'}}>Next</Button>
|
||||
<Button buttonStyles={{height: 'auto', marginTop: 'var(--default_spacing)', width: 'auto'}}
|
||||
clicked={this.displaySyntax}>Import Syntax...</Button>
|
||||
<Button buttonStyles={{
|
||||
height: 'auto',
|
||||
marginLeft: 'var(--default_spacing)',
|
||||
marginTop: 'var(--default_spacing)',
|
||||
width: 'auto'
|
||||
}} clicked={this.processNext}>Next</Button>
|
||||
</div>
|
||||
</Box>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user