343 lines
9.7 KiB
JavaScript
343 lines
9.7 KiB
JavaScript
import React from 'react';
|
|
import './SkynetExport.css';
|
|
import CheckboxTree from 'react-checkbox-tree';
|
|
import { connect } from 'react-redux';
|
|
import IPCContainer from '../IPCContainer/IPCContainer';
|
|
import { notifyApplicationBusy } from '../../redux/actions/common_actions';
|
|
import { notifyError, notifyInfo } from '../../redux/actions/error_actions';
|
|
import Box from '../../components/UI/Box/Box';
|
|
import { displaySkynetExport } from '../../redux/actions/skynet_actions';
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
import {
|
|
faCheckSquare,
|
|
faChevronDown,
|
|
faChevronRight,
|
|
faFile,
|
|
faFolder,
|
|
faFolderOpen,
|
|
faHSquare,
|
|
faMinusSquare,
|
|
faPlusSquare,
|
|
faSquare,
|
|
} from '@fortawesome/free-solid-svg-icons';
|
|
import Button from '../../components/UI/Button/Button';
|
|
|
|
const Constants = require('../../constants');
|
|
|
|
const mapStateToProps = (state) => {
|
|
return {
|
|
AppBusy: state.common.AppBusy,
|
|
};
|
|
};
|
|
|
|
const mapDispatchToProps = (dispatch) => {
|
|
return {
|
|
displaySkynetExport: (display) => dispatch(displaySkynetExport(display)),
|
|
notifyApplicationBusy: (busy) =>
|
|
dispatch(notifyApplicationBusy(busy, true)),
|
|
notifyError: (msg) => dispatch(notifyError(msg)),
|
|
notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)),
|
|
};
|
|
};
|
|
|
|
export default connect(
|
|
mapStateToProps,
|
|
mapDispatchToProps
|
|
)(
|
|
class extends IPCContainer {
|
|
state = {
|
|
checked: [],
|
|
clicked: {},
|
|
expanded: [],
|
|
nodes: [],
|
|
second_stage: false,
|
|
};
|
|
|
|
componentDidMount() {
|
|
this.setRequestHandler(
|
|
Constants.IPC_Grab_Skynet_Tree_Reply,
|
|
this.onGrabSkynetTreeReply
|
|
);
|
|
this.setRequestHandler(
|
|
Constants.IPC_Export_Skylinks_Reply,
|
|
this.onExportSkylinksReply
|
|
);
|
|
this.sendRequest(Constants.IPC_Grab_Skynet_Tree, {
|
|
Version: this.props.version,
|
|
});
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
super.componentWillUnmount();
|
|
}
|
|
|
|
createNodes = (items) => {
|
|
/*
|
|
{
|
|
name: '',
|
|
path: '',
|
|
directory: true/false,
|
|
children: [],
|
|
}
|
|
*/
|
|
const ret = [];
|
|
for (const item of items) {
|
|
const treeItem = {
|
|
label: item.name,
|
|
path: item.path,
|
|
value:
|
|
item.name === '/'
|
|
? 0
|
|
: item.path
|
|
? item.path
|
|
: JSON.stringify(item),
|
|
};
|
|
|
|
if (item.directory) {
|
|
treeItem.children = this.createNodes(item.children);
|
|
}
|
|
|
|
ret.push(treeItem);
|
|
}
|
|
|
|
return ret;
|
|
};
|
|
|
|
handleNavigation = () => {
|
|
if (this.state.second_stage) {
|
|
this.props.notifyApplicationBusy(true);
|
|
this.sendRequest(Constants.IPC_Export_Skylinks, {
|
|
Version: this.props.version,
|
|
Paths: this.state.checked,
|
|
});
|
|
} else {
|
|
if (this.state.checked.length === 0) {
|
|
this.props.notifyError('No files have been checked');
|
|
} else {
|
|
this.setState({
|
|
second_stage: true,
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
onExportSkylinksReply = (_, arg) => {
|
|
this.props.notifyApplicationBusy(false);
|
|
if (arg.data.Success) {
|
|
this.setState(
|
|
{
|
|
checked: [],
|
|
clicked: {},
|
|
expanded: [],
|
|
nodes: [],
|
|
second_stage: false,
|
|
},
|
|
() => {
|
|
this.props.notifyInfo(
|
|
'Skylink Exports',
|
|
'!alternate!!copyable!' +
|
|
JSON.stringify(arg.data.Result.success, null, 2)
|
|
);
|
|
this.sendRequest(Constants.IPC_Grab_Skynet_Tree, {
|
|
Version: this.props.version,
|
|
});
|
|
}
|
|
);
|
|
} else {
|
|
this.props.notifyError(arg.data.Error);
|
|
}
|
|
};
|
|
|
|
onGrabSkynetTreeReply = (_, arg) => {
|
|
if (arg.data.Success) {
|
|
this.setState({
|
|
checked: [],
|
|
expanded: [0],
|
|
nodes: this.createNodes(arg.data.Result),
|
|
});
|
|
} else {
|
|
this.setState(
|
|
{
|
|
checked: [],
|
|
expanded: [],
|
|
nodes: [],
|
|
},
|
|
() => {
|
|
this.props.notifyError(arg.data.Error);
|
|
}
|
|
);
|
|
}
|
|
};
|
|
|
|
render() {
|
|
return this.props.AppBusy ? (
|
|
<div />
|
|
) : (
|
|
<Box
|
|
dxDark
|
|
dxStyle={{
|
|
height: '90vh',
|
|
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.displaySkynetExport(false)}
|
|
style={{ cursor: 'pointer' }}>
|
|
X
|
|
</a>
|
|
</div>
|
|
<h1 className={'SkynetExportHeading'}>
|
|
{this.state.second_stage ? 'Verify Exports' : 'Export Files'}
|
|
</h1>
|
|
<div
|
|
className={
|
|
this.state.second_stage ? 'SkynetExportList' : 'SkynetExportTree'
|
|
}>
|
|
{this.state.second_stage ? (
|
|
this.state.checked.map((path) => {
|
|
return (
|
|
<input
|
|
readOnly
|
|
className={'ConfigurationItemInput'}
|
|
key={path}
|
|
style={{
|
|
width: '100%',
|
|
marginBottom: 'var(--default_spacing)',
|
|
}}
|
|
type={'text'}
|
|
value={path}
|
|
/>
|
|
);
|
|
})
|
|
) : (
|
|
<CheckboxTree
|
|
checked={this.state.checked}
|
|
expanded={this.state.expanded}
|
|
expandOnClick
|
|
showExpandAll
|
|
icons={{
|
|
check: (
|
|
<FontAwesomeIcon
|
|
icon={faCheckSquare}
|
|
fixedWidth
|
|
style={{ padding: 0, margin: 0 }}
|
|
/>
|
|
),
|
|
uncheck: (
|
|
<FontAwesomeIcon
|
|
icon={faSquare}
|
|
fixedWidth
|
|
style={{ padding: 0, margin: 0 }}
|
|
/>
|
|
),
|
|
halfCheck: (
|
|
<FontAwesomeIcon
|
|
icon={faHSquare}
|
|
fixedWidth
|
|
style={{ padding: 0, margin: 0 }}
|
|
/>
|
|
),
|
|
expandClose: (
|
|
<FontAwesomeIcon
|
|
icon={faChevronRight}
|
|
fixedWidth
|
|
style={{ padding: 0, margin: 0 }}
|
|
/>
|
|
),
|
|
expandOpen: (
|
|
<FontAwesomeIcon
|
|
icon={faChevronDown}
|
|
fixedWidth
|
|
style={{ padding: 0, margin: 0 }}
|
|
/>
|
|
),
|
|
expandAll: (
|
|
<FontAwesomeIcon
|
|
icon={faPlusSquare}
|
|
fixedWidth
|
|
style={{ padding: 0, margin: 0 }}
|
|
/>
|
|
),
|
|
collapseAll: (
|
|
<FontAwesomeIcon
|
|
icon={faMinusSquare}
|
|
fixedWidth
|
|
style={{ padding: 0, margin: 0 }}
|
|
/>
|
|
),
|
|
parentClose: (
|
|
<FontAwesomeIcon
|
|
icon={faFolder}
|
|
fixedWidth
|
|
color={'var(--heading_text_color)'}
|
|
style={{ padding: 0, margin: 0 }}
|
|
/>
|
|
),
|
|
parentOpen: (
|
|
<FontAwesomeIcon
|
|
icon={faFolderOpen}
|
|
fixedWidth
|
|
color={'var(--heading_text_color)'}
|
|
style={{ padding: 0, margin: 0 }}
|
|
/>
|
|
),
|
|
leaf: (
|
|
<FontAwesomeIcon
|
|
icon={faFile}
|
|
fixedWidth
|
|
color={'var(--text_color)'}
|
|
style={{ padding: 0, margin: 0 }}
|
|
/>
|
|
),
|
|
}}
|
|
nodes={this.state.nodes}
|
|
onClick={(clicked) => this.setState({ clicked })}
|
|
onCheck={(checked) => this.setState({ checked })}
|
|
onExpand={(expanded) => this.setState({ expanded })}
|
|
/>
|
|
)}
|
|
</div>
|
|
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
|
{this.state.second_stage ? (
|
|
<Button
|
|
buttonStyles={{
|
|
height: 'auto',
|
|
marginLeft: 'var(--default_spacing)',
|
|
marginTop: 'var(--default_spacing)',
|
|
width: 'auto',
|
|
}}
|
|
clicked={() =>
|
|
this.setState({
|
|
second_stage: false,
|
|
})
|
|
}>
|
|
{'Back'}
|
|
</Button>
|
|
) : null}
|
|
<Button
|
|
buttonStyles={{
|
|
height: 'auto',
|
|
marginLeft: 'var(--default_spacing)',
|
|
marginTop: 'var(--default_spacing)',
|
|
width: 'auto',
|
|
}}
|
|
clicked={this.handleNavigation}>
|
|
{this.state.second_stage ? 'Export' : 'Next'}
|
|
</Button>
|
|
</div>
|
|
</Box>
|
|
);
|
|
}
|
|
}
|
|
);
|