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/Configuration/Configuration.js
2021-03-10 21:14:32 -06:00

473 lines
14 KiB
JavaScript

import React from 'react';
import './Configuration.css';
import { connect } from 'react-redux';
import Box from '../../components/UI/Box/Box';
import Button from '../../components/UI/Button/Button';
import ConfigurationItem from './ConfigurationItem/ConfigurationItem';
import Modal from '../../components/UI/Modal/Modal';
import IPCContainer from '../IPCContainer/IPCContainer';
import { displayConfiguration } from '../../redux/actions/mount_actions';
import { notifyError } from '../../redux/actions/error_actions';
import { displayPinnedManager } from '../../redux/actions/pinned_manager_actions';
const Constants = require('../../constants');
class Configuration extends IPCContainer {
_isMounted = false;
state = {
ChangedItems: [],
ChangedObjectLookup: null,
ObjectLookup: {},
OriginalItemList: [],
OriginalObjectLookup: {},
IsRemoteMount: false,
ItemList: [],
Saving: false,
ShowAdvanced: false,
Template: {},
};
checkItemChanged = (itemA, itemB) => {
if (itemA.type === 'string_array') {
if (itemA.value.length !== itemB.value.length) {
return true;
}
return itemA.value.filter((i) => !itemB.value.includes(i)).length !== 0;
}
return itemA.value !== itemB.value;
};
checkSaveRequired = () => {
const changedItems = [];
let i = 0;
for (const item of this.state.ItemList) {
if (this.checkItemChanged(this.state.OriginalItemList[i++], item)) {
changedItems.push(item);
}
}
let changedObjectLookup = null;
for (const key of Object.keys(this.state.ObjectLookup)) {
const changedObjectItems = [];
let j = 0;
for (const item of this.state.ObjectLookup[key]) {
if (
this.checkItemChanged(this.state.OriginalObjectLookup[key][j++], item)
) {
changedObjectItems.push(item);
}
}
if (changedObjectItems.length > 0) {
if (changedObjectLookup === null) {
changedObjectLookup = {};
}
changedObjectLookup[key] = changedObjectItems;
}
}
if (changedItems.length > 0 || changedObjectLookup) {
this.setState({
ChangedItems: changedItems,
ChangedObjectLookup: changedObjectLookup,
});
} else {
this.props.hideConfiguration();
}
};
componentDidMount() {
this._isMounted = true;
this.setRequestHandler(
Constants.IPC_Get_Config_Template_Reply,
this.onGetConfigTemplateReply
);
this.setRequestHandler(
Constants.IPC_Get_Config_Reply,
this.onGetConfigReply
);
this.setRequestHandler(
Constants.IPC_Set_Config_Values_Reply,
this.onSetConfigValuesReply
);
this.sendRequest(Constants.IPC_Get_Config_Template, {
Provider: this.props.DisplayConfiguration,
Remote: this.props.DisplayRemoteConfiguration,
S3: this.props.DisplayS3Configuration,
Version: this.props.version,
});
}
componentWillUnmount() {
this._isMounted = false;
super.componentWillUnmount();
}
createItemList = (config, template) => {
const objectList = [];
const itemList = Object.keys(config)
.map((key) => {
return {
advanced: template[key] ? template[key].advanced : false,
hide_remote: template[key] ? template[key].hide_remote : false,
label: key,
remote: template[key] ? template[key].remote : false,
type: template[key] ? template[key].type : null,
value:
template[key] && template[key].type === 'object'
? config[key]
: template[key] && template[key].type === 'string_array'
? config[key]
: config[key].toString(),
};
})
.filter((i) => {
let ret = template[i.label];
if (ret && template[i.label].type === 'object') {
objectList.push(i);
ret = false;
}
return ret;
});
return {
ObjectList: objectList,
ItemList: itemList,
};
};
handleItemChanged = (target, idx) => {
const itemList = [...this.state.ItemList];
itemList[idx].value =
target.type === 'textarea'
? target.string_array
: target.value.toString();
this.setState({
ItemList: itemList,
});
};
handleObjectItemChanged = (target, name, idx) => {
const itemList = [...this.state.ObjectLookup[name]];
const objectLookup = {
...this.state.ObjectLookup,
};
itemList[idx].value =
target.type === 'textarea'
? target.string_array
: target.value.toString();
objectLookup[name] = itemList;
this.setState({
ObjectLookup: objectLookup,
});
};
onGetConfigReply = (event, arg) => {
if (arg.data.Success) {
const list = this.createItemList(arg.data.Config, this.state.Template);
const itemListCopy = JSON.parse(JSON.stringify(list.ItemList));
let objectLookup = {};
for (const obj of list.ObjectList) {
const list2 = this.createItemList(
obj.value,
this.state.Template[obj.label].template
);
objectLookup[obj.label] = list2.ItemList;
}
const isRemoteMount =
this.props.remoteSupported &&
JSON.parse(
objectLookup['RemoteMount'].find((s) => s.label === 'IsRemoteMount')
.value
);
if (isRemoteMount) {
for (const obj of list.ObjectList) {
if (obj.hide_remote) {
delete objectLookup[obj.label];
}
}
}
const objectLookupCopy = JSON.parse(JSON.stringify(objectLookup));
this.setState(
{
IsRemoteMount: isRemoteMount,
ItemList: list.ItemList,
ObjectLookup: objectLookup,
OriginalItemList: itemListCopy,
OriginalObjectLookup: objectLookupCopy,
},
() => {}
);
} else {
this.props.notifyError(arg.data.Error);
}
};
onGetConfigTemplateReply = (event, arg) => {
if (arg.data.Success) {
this.setState(
{
Template: arg.data.Template,
},
() => {
this.sendRequest(Constants.IPC_Get_Config, {
Provider: this.props.DisplayConfiguration,
Remote: this.props.DisplayRemoteConfiguration,
S3: this.props.DisplayS3Configuration,
Version: this.props.version,
});
}
);
} else {
this.props.notifyError(arg.data.Error, false, () => {
if (this._isMounted) {
this.props.hideConfiguration();
}
});
}
};
onSetConfigValuesReply = () => {
this.props.hideConfiguration();
};
saveAndClose = () => {
this.setState(
{
Saving: true,
},
() => {
const changedItems = [];
for (const item of this.state.ChangedItems) {
changedItems.push({
Name: item.label,
Value:
item.type === 'string_array' ? item.value.join(';') : item.value,
});
}
if (this.state.ChangedObjectLookup) {
for (const key of Object.keys(this.state.ChangedObjectLookup)) {
for (const item of this.state.ChangedObjectLookup[key]) {
changedItems.push({
Name: key + '.' + item.label,
Value:
item.type === 'string_array'
? item.value.join(';')
: item.value,
});
}
}
}
this.sendRequest(Constants.IPC_Set_Config_Values, {
Items: changedItems,
Provider: this.props.DisplayConfiguration,
Remote: this.props.DisplayRemoteConfiguration,
S3: this.props.DisplayS3Configuration,
Version: this.props.version,
});
}
);
};
showRemoteConfigItem = (item, itemList) => {
if (
item.advanced &&
item.remote &&
this.props.remoteSupported &&
item.label !== 'IsRemoteMount'
) {
const isRemoteMount = JSON.parse(
itemList.find((s) => s.label === 'IsRemoteMount').value
);
const enableRemoteMount =
!isRemoteMount &&
JSON.parse(itemList.find((s) => s.label === 'EnableRemoteMount').value);
return item.label === 'RemoteHostNameOrIp' ||
item.label === 'RemoteMaxConnections'
? isRemoteMount
: item.label === 'RemoteReceiveTimeoutSeconds' ||
item.label === 'RemoteSendTimeoutSeconds' ||
item.label === 'RemotePort' ||
item.label === 'RemoteToken'
? isRemoteMount || enableRemoteMount
: item.label === 'EnableRemoteMount'
? !isRemoteMount
: enableRemoteMount;
}
return false;
};
render() {
let confirmSave = null;
if (this.state.ChangedItems.length > 0 || this.state.ChangedObjectLookup) {
confirmSave = (
<Modal>
<Box dxStyle={{ width: '40vw', padding: 'var(--default_spacing)' }}>
<h1 style={{ width: '100%', textAlign: 'center' }}>
Save Changes?
</h1>
<table width="100%">
<tbody>
<tr>
<td align="center" width="50%">
<Button
clicked={this.saveAndClose}
disabled={this.state.Saving}
>
Yes
</Button>
</td>
<td align="center" width="50%">
<Button
clicked={this.props.hideConfiguration}
disabled={this.state.Saving}
>
No
</Button>
</td>
</tr>
</tbody>
</table>
</Box>
</Modal>
);
}
let autoFocus = true;
let objectItems = [];
for (const key of Object.keys(this.state.ObjectLookup)) {
objectItems.push(
<div key={key}>
<h2>{key}</h2>
<div>
{this.state.ObjectLookup[key].map((k, i) => {
const shouldFocus = autoFocus;
autoFocus = false;
return !k.advanced ||
(this.state.ShowAdvanced && k.advanced && !k.remote) ||
this.showRemoteConfigItem(k, this.state.ObjectLookup[key]) ? (
<ConfigurationItem
advanced={k.advanced}
autoFocus={shouldFocus}
changed={(e) => this.handleObjectItemChanged(e, key, i)}
grouping={key}
items={this.state.Template[key].template[k.label].items}
key={i}
label={k.label}
readOnly={
this.state.IsRemoteMount &&
(k.label === 'RemoteHostNameOrIp' ||
k.label === 'RemotePort')
}
template={this.state.Template[key].template[k.label]}
value={k.value}
/>
) : null;
})}
</div>
</div>
);
}
const configurationItems = this.state.ItemList.map((k, i) => {
const shouldFocus = autoFocus;
autoFocus = false;
return (!this.state.IsRemoteMount || !k.hide_remote) &&
(!k.advanced || (this.state.ShowAdvanced && k.advanced)) ? (
<ConfigurationItem
advanced={k.advanced}
autoFocus={shouldFocus}
changed={(e) => this.handleItemChanged(e, i)}
grouping={'Settings'}
items={this.state.Template[k.label].items}
key={i}
label={k.label}
template={this.state.Template[k.label]}
value={k.value}
/>
) : null;
});
return (
<div className={'Configuration'}>
{confirmSave}
<Box dxDark dxStyle={{ padding: 'var(--default_spacing)' }}>
<div
style={{
float: 'right',
margin: 0,
padding: 0,
marginTop: '-4px',
boxSizing: 'border-box',
display: 'block',
}}
>
<a
href={'#'}
onClick={this.checkSaveRequired}
style={{ cursor: 'pointer' }}
>
X
</a>
</div>
<h1 style={{ width: '100%', textAlign: 'center' }}>
{(this.props.DisplayRemoteConfiguration
? this.props.DisplayConfiguration.substr(6)
: this.props.DisplayConfiguration) + ' Configuration '}
</h1>
<div style={{ overflowY: 'auto', height: '90%' }}>
{this.props.MState.Mounted && configurationItems.length > 0 ? (
<Button
buttonStyles={{
width: 'auto',
height: 'auto',
marginLeft: 'auto',
marginRight: '4px',
}}
clicked={() => {
this.props.displayPinnedManager(true);
return false;
}}
>
&nbsp;Pinned File Manager...&nbsp;
</Button>
) : null}
<div style={{ marginBottom: '4px' }} />
{objectItems}
{configurationItems.length > 0 ? <h2>Settings</h2> : null}
{configurationItems}
</div>
</Box>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
DisplayConfiguration: state.mounts.DisplayConfiguration,
DisplayRemoteConfiguration: state.mounts.DisplayRemoteConfiguration,
DisplayS3Configuration: state.mounts.DisplayS3Configuration,
MState: state.mounts.MountState[state.mounts.DisplayConfiguration],
Platform: state.common.Platform,
};
};
const mapDispatchToProps = (dispatch) => {
return {
displayPinnedManager: (display) => dispatch(displayPinnedManager(display)),
notifyError: (msg, critical, callback) =>
dispatch(notifyError(msg, critical, callback)),
hideConfiguration: () => dispatch(displayConfiguration(null, false)),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Configuration);