This repository has been archived on 2025-09-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
repertory-ui/src/containers/SkynetExport/SkynetExport.js

236 lines
8.5 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 style={{overflowX: 'auto', overflowY: 'auto', height: 'calc(90vh - 80px)'}}>
{
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>
);
}
});