Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

Commit

Permalink
Merge pull request #851 from mturley/settings-tabs
Browse files Browse the repository at this point in the history
Add routed tabs to the Settings page to prepare for Conversion Hosts settings
  • Loading branch information
michaelkro authored Jan 24, 2019
2 parents dad48b0 + b700cdd commit 339f3bf
Show file tree
Hide file tree
Showing 10 changed files with 233 additions and 202 deletions.
5 changes: 5 additions & 0 deletions app/javascript/react/config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ export const links = [
component: Settings,
menu_item_id: 'menu_item_settings'
},
{
path: 'settings/conversion_hosts',
component: Settings,
menu_item_id: 'menu_item_settings'
},
{
path: 'plan/:id',
component: PlanContainer,
Expand Down
113 changes: 30 additions & 83 deletions app/javascript/react/screens/App/Settings/Settings.js
Original file line number Diff line number Diff line change
@@ -1,100 +1,47 @@
import React from 'react';
import PropTypes from 'prop-types';
import { reduxForm, Field } from 'redux-form';
import { Breadcrumb, Form, Button, Spinner } from 'patternfly-react';
import { Breadcrumb, Tabs, Tab } from 'patternfly-react';
import Toolbar from '../../../config/Toolbar';
import NumberInput from '../common/forms/NumberInput';
import GeneralSettings from './screens/GeneralSettings';
import ConversionHostsSettings from './screens/ConversionHostsSettings';

export class Settings extends React.Component {
componentDidMount() {
const { fetchServersAction, fetchServersUrl, fetchSettingsAction, fetchSettingsUrl } = this.props;
fetchServersAction(fetchServersUrl);
fetchSettingsAction(fetchSettingsUrl);
}
const Settings = props => {
const { match, redirectTo } = props;

onApplyClick = () => {
const { patchSettingsAction, servers, settingsForm } = this.props;
patchSettingsAction(servers, settingsForm.values);
};
// TODO remove this when we are ready to release ConversionHostsSettings
const hideConversionHostSettings = true;

render() {
const { isFetchingServers, isFetchingSettings, isSavingSettings, savedSettings, settingsForm } = this.props;

const toolbarContent = (
return (
<React.Fragment>
<Toolbar>
<Breadcrumb.Item href="/dashboard/maintab?tab=compute">{__('Compute')}</Breadcrumb.Item>
<Breadcrumb.Item href="#/plans">{__('Migration')}</Breadcrumb.Item>
<Breadcrumb.Item active>{__('Migration Settings')}</Breadcrumb.Item>
</Toolbar>
);

const hasUnsavedChanges =
settingsForm &&
settingsForm.values &&
Object.keys(savedSettings).some(key => savedSettings[key] !== settingsForm.values[key]);

const settingsContent = (
<Spinner loading={isFetchingServers || isFetchingSettings} style={{ marginTop: 15 }}>
<div className="migration-settings">
{hideConversionHostSettings ? (
<React.Fragment>
<h2>{__('Concurrent Migrations')}</h2>
<Form style={{ padding: '0 20px' }}>
<Form.FormGroup>
<Form.ControlLabel>{__('Maximum concurrent migrations per conversion host')}</Form.ControlLabel>
<div style={{ width: 100 }}>
<Field
id="max_concurrent_tasks_per_host"
name="max_concurrent_tasks_per_host"
component={NumberInput}
normalize={NumberInput.normalizeStringToInt}
min={1}
/>
</div>
</Form.FormGroup>
<Form.FormGroup>
<Button bsStyle="primary" onClick={this.onApplyClick} disabled={!hasUnsavedChanges || isSavingSettings}>
{__('Apply')}
</Button>
<br />
{isSavingSettings && (
<div style={{ paddingTop: 10 }}>
<Spinner loading size="xs" inline />
{__(' Applying...')}
</div>
)}
</Form.FormGroup>
</Form>
<GeneralSettings />
</React.Fragment>
) : (
<div style={{ marginTop: 10 }}>
<Tabs id="settings-tabs" activeKey={match.path} onSelect={key => redirectTo(key)}>
<Tab eventKey="/settings" title={__('Concurrent Migrations')}>
<GeneralSettings />
</Tab>
<Tab eventKey="/settings/conversion_hosts" title={__('Conversion Hosts')}>
<ConversionHostsSettings />
</Tab>
</Tabs>
</div>
</Spinner>
);

return (
<React.Fragment>
{toolbarContent}
{settingsContent}
</React.Fragment>
);
}
}

Settings.propTypes = {
fetchServersAction: PropTypes.func,
fetchSettingsAction: PropTypes.func,
patchSettingsAction: PropTypes.func,
isFetchingServers: PropTypes.bool,
isFetchingSettings: PropTypes.bool,
isSavingSettings: PropTypes.bool,
servers: PropTypes.array,
savedSettings: PropTypes.object,
settingsForm: PropTypes.object,
fetchServersUrl: PropTypes.string,
fetchSettingsUrl: PropTypes.string
)}
</React.Fragment>
);
};

Settings.defaultProps = {
fetchServersUrl: '/api/servers',
fetchSettingsUrl: '/api/settings'
Settings.propTypes = {
match: PropTypes.object,
redirectTo: PropTypes.func
};

export default reduxForm({
form: 'settings'
})(Settings);
export default Settings;

This file was deleted.

16 changes: 3 additions & 13 deletions app/javascript/react/screens/App/Settings/index.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
import { connect } from 'react-redux';
import Settings from './Settings';

import * as SettingsActions from './SettingsActions';
import * as NotificationActions from '../common/NotificationList/NotificationListActions';

import reducer from './SettingsReducer';
import * as RouterActions from '../../../../redux/actions/routerActions';

export const reducers = { settings: reducer };

const mapStateToProps = ({ settings, form }, ownProps) => ({
...settings,
...ownProps.data,
settingsForm: form.settings,
initialValues: settings.savedSettings,
enableReinitialize: true,
destroyOnUnmount: false
});
const mapStateToProps = () => ({});

const mergeProps = (stateProps, dispatchProps, ownProps) => Object.assign(stateProps, ownProps.data, dispatchProps);

export default connect(
mapStateToProps,
Object.assign(SettingsActions, NotificationActions),
RouterActions,
mergeProps
)(Settings);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from 'react';

const ConversionHostsSettings = () => <h2>Hello World</h2>;

export default ConversionHostsSettings;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import ConversionHostsSettings from './ConversionHostsSettings';

export default ConversionHostsSettings;
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React from 'react';
import PropTypes from 'prop-types';
import { reduxForm, Field } from 'redux-form';
import { Form, Button, Spinner } from 'patternfly-react';
import NumberInput from '../../../common/forms/NumberInput';

export class GeneralSettings extends React.Component {
componentDidMount() {
const { fetchServersAction, fetchServersUrl, fetchSettingsAction, fetchSettingsUrl } = this.props;
fetchServersAction(fetchServersUrl);
fetchSettingsAction(fetchSettingsUrl);
}

onApplyClick = () => {
const { patchSettingsAction, servers, settingsForm } = this.props;
patchSettingsAction(servers, settingsForm.values);
};

render() {
const { isFetchingServers, isFetchingSettings, isSavingSettings, savedSettings, settingsForm } = this.props;

const hasUnsavedChanges =
settingsForm &&
settingsForm.values &&
Object.keys(savedSettings).some(key => savedSettings[key] !== settingsForm.values[key]);

return (
<Spinner loading={isFetchingServers || isFetchingSettings} style={{ marginTop: 15 }}>
<div className="migration-settings">
<Form style={{ padding: '0 20px' }}>
<Form.FormGroup>
<Form.ControlLabel>{__('Maximum concurrent migrations per conversion host')}</Form.ControlLabel>
<div style={{ width: 100 }}>
<Field
id="max_concurrent_tasks_per_host"
name="max_concurrent_tasks_per_host"
component={NumberInput}
normalize={NumberInput.normalizeStringToInt}
min={1}
/>
</div>
</Form.FormGroup>
<Form.FormGroup>
<Button bsStyle="primary" onClick={this.onApplyClick} disabled={!hasUnsavedChanges || isSavingSettings}>
{__('Apply')}
</Button>
<br />
{isSavingSettings && (
<div style={{ paddingTop: 10 }}>
<Spinner loading size="xs" inline />
{__(' Applying...')}
</div>
)}
</Form.FormGroup>
</Form>
</div>
</Spinner>
);
}
}

GeneralSettings.propTypes = {
fetchServersAction: PropTypes.func,
fetchSettingsAction: PropTypes.func,
patchSettingsAction: PropTypes.func,
isFetchingServers: PropTypes.bool,
isFetchingSettings: PropTypes.bool,
isSavingSettings: PropTypes.bool,
servers: PropTypes.array,
savedSettings: PropTypes.object,
settingsForm: PropTypes.object,
fetchServersUrl: PropTypes.string,
fetchSettingsUrl: PropTypes.string
};

GeneralSettings.defaultProps = {
fetchServersUrl: '/api/servers',
fetchSettingsUrl: '/api/settings'
};

export default reduxForm({
form: 'settings'
})(GeneralSettings);
Loading

0 comments on commit 339f3bf

Please sign in to comment.