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
2021-03-11 18:15:08 -06:00

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>
);
}
}
);