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-05-04 12:30:18 -05:00

459 lines
14 KiB
JavaScript

import React from 'react';
import './Configuration.css';
import { connect } from 'react-redux';
import { createDismissDisplay } from '../../utils.jsx';
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;
}
if (itemA.type === 'host_list') {
if (itemA.value.length !== itemB.value.length) {
return true;
}
return (
itemA.value.filter((i) =>
itemB.value.find(
(j) =>
j.HostNameOrIp === i.HostNameOrIp &&
j.ApiPort === i.ApiPort &&
j.Protocol === i.Protocol &&
j.TimeoutMs === i.TimeoutMs &&
j.AgentString === i.AgentString &&
j.ApiPassword === i.ApiPassword &&
j.AuthURL === i.AuthURL &&
j.AuthUser === i.AuthUser &&
j.AuthPassword === i.AuthPassword
)
).length != itemA.value.length
);
}
return itemA.value !== itemB.value;
};
checkSaveRequired = () => {
let i = 0;
const changedItems = this.state.ItemList.filter((item) => {
return this.checkItemChanged(this.state.OriginalItemList[i++], item);
});
let changedObjectLookup = null;
for (const key of Object.keys(this.state.ObjectLookup)) {
let j = 0;
const changedObjectItems = this.state.ObjectLookup[key].filter((item) => {
return this.checkItemChanged(this.state.OriginalObjectLookup[key][j++], 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 === 'string_array' || template[key].type === 'object')
? config[key]
: template[key] && template[key].type === 'host_list'
? 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.type === 'host_list'
? target.value
: 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.type === 'host_list'
? target.value
: target.value.toString();
objectLookup[name] = itemList;
this.setState({
ObjectLookup: objectLookup,
});
};
onGetConfigReply = (_, 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 = (_, 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.type === 'host_list'
? JSON.stringify(item.value)
: 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.type === 'host_list'
? JSON.stringify(item.value)
: 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;
const getAutoFocus = () => {
return autoFocus;
};
const setAutoFocus = (value) => {
autoFocus = value;
};
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 = getAutoFocus();
setAutoFocus(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: '5px' }}>
{createDismissDisplay(this.checkSaveRequired)}
<h1 style={{ width: '100%', textAlign: 'center' }}>
{(this.props.DisplayRemoteConfiguration
? this.props.DisplayConfiguration.substr(6)
: this.props.DisplayS3Configuration
? this.props.DisplayConfiguration.substr(2)
: 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);