eslint: use as-needed for arrow-body-style

When a function that is introduced by an arrow, don't insert a return
statement and its required curly braces when not needed.

Bad:

    const f = () => {
        return 1;
    }

Good:

    const f = () => 1

This patch consists of a change to .eslintrc, and automatically fixed
files (via eslint --fix).

Change-Id: I6afc3f91ee2cc44ae149e482d5633876c85c3cff
This commit is contained in:
Honza Pokorny 2018-02-21 13:28:30 -04:00
parent bc9804b753
commit 16514bf462
63 changed files with 753 additions and 913 deletions

View File

@ -1,5 +1,6 @@
{
"rules": {
"arrow-body-style": [2, "as-needed"],
"default-case": 0,
"linebreak-style": [2, "unix"],
"no-cond-assign": [2, "except-parens"],

View File

@ -121,8 +121,8 @@ describe('updateEnvironmentConfiguration', () => {
NotificationActions.notify = jest.fn(() => ({ type: 'NOTIFY' }));
});
it('dispatches actions', () => {
return store
it('dispatches actions', () =>
store
.dispatch(
EnvironmentConfigurationActions.updateEnvironmentConfiguration('myPlan')
)
@ -140,6 +140,5 @@ describe('updateEnvironmentConfiguration', () => {
stopSubmit('environmentConfigurationForm'),
NotificationActions.notify({ type: 'NOTIFY' })
]);
});
});
}));
});

View File

@ -177,18 +177,15 @@ describe('Fetching Introspection data success', () => {
.mockReturnValue(() => Promise.resolve(response));
});
it('dispatches fetchNodeIntrospectionDataSuccess', () => {
return store
.dispatch(NodesActions.fetchNodeIntrospectionData(nodeId))
.then(() => {
expect(
IronicInspectorApiService.getIntrospectionData
).toHaveBeenCalledWith(nodeId);
expect(store.getActions()).toEqual([
NodesActions.fetchNodeIntrospectionDataSuccess(nodeId, response)
]);
});
});
it('dispatches fetchNodeIntrospectionDataSuccess', () =>
store.dispatch(NodesActions.fetchNodeIntrospectionData(nodeId)).then(() => {
expect(
IronicInspectorApiService.getIntrospectionData
).toHaveBeenCalledWith(nodeId);
expect(store.getActions()).toEqual([
NodesActions.fetchNodeIntrospectionDataSuccess(nodeId, response)
]);
}));
});
describe('Fetching Introspection data error', () => {
@ -208,18 +205,15 @@ describe('Fetching Introspection data error', () => {
ErrorActions.handleErrors = jest.fn().mockReturnValue(() => {});
});
it('dispatches fetchNodeIntrospectionDataFailed', () => {
return store
.dispatch(NodesActions.fetchNodeIntrospectionData(nodeId))
.then(() => {
expect(
IronicInspectorApiService.getIntrospectionData
).toHaveBeenCalledWith(nodeId);
expect(store.getActions()).toEqual([
NodesActions.fetchNodeIntrospectionDataFailed(nodeId)
]);
});
});
it('dispatches fetchNodeIntrospectionDataFailed', () =>
store.dispatch(NodesActions.fetchNodeIntrospectionData(nodeId)).then(() => {
expect(
IronicInspectorApiService.getIntrospectionData
).toHaveBeenCalledWith(nodeId);
expect(store.getActions()).toEqual([
NodesActions.fetchNodeIntrospectionDataFailed(nodeId)
]);
}));
});
describe('Asynchronous Introspect Nodes Action', () => {
@ -235,22 +229,19 @@ describe('Asynchronous Introspect Nodes Action', () => {
.mockReturnValue(() => {});
});
it('dispatches startOperation', () => {
return store
.dispatch(NodesActions.startNodesIntrospection(nodeIds))
.then(() => {
expect(MistralApiService.runWorkflow).toHaveBeenCalledWith(
MistralConstants.BAREMETAL_INTROSPECT,
{
node_uuids: nodeIds
}
);
expect(NodesActions.pollNodeslistDuringProgress).toHaveBeenCalled();
expect(store.getActions()).toEqual([
NodesActions.startOperation(nodeIds)
]);
});
});
it('dispatches startOperation', () =>
store.dispatch(NodesActions.startNodesIntrospection(nodeIds)).then(() => {
expect(MistralApiService.runWorkflow).toHaveBeenCalledWith(
MistralConstants.BAREMETAL_INTROSPECT,
{
node_uuids: nodeIds
}
);
expect(NodesActions.pollNodeslistDuringProgress).toHaveBeenCalled();
expect(store.getActions()).toEqual([
NodesActions.startOperation(nodeIds)
]);
}));
});
describe('nodesIntrospectionFinished', () => {
@ -327,8 +318,8 @@ describe('startProvideNodes Action', () => {
.mockReturnValue(() => {});
});
it('dispatches actions', () => {
return store.dispatch(NodesActions.startProvideNodes(nodeIds)).then(() => {
it('dispatches actions', () =>
store.dispatch(NodesActions.startProvideNodes(nodeIds)).then(() => {
expect(MistralApiService.runWorkflow).toHaveBeenCalledWith(
MistralConstants.BAREMETAL_PROVIDE,
{
@ -339,8 +330,7 @@ describe('startProvideNodes Action', () => {
expect(store.getActions()).toEqual([
NodesActions.startOperation(nodeIds)
]);
});
});
}));
});
describe('provideNodesFinished', () => {
@ -402,14 +392,13 @@ describe('Update Node thunk action', () => {
.mockReturnValue(() => Promise.resolve({ uuid: 'someId' }));
});
it('dispatches required actions', () => {
return store.dispatch(NodesActions.updateNode(nodePatch)).then(() => {
it('dispatches required actions', () =>
store.dispatch(NodesActions.updateNode(nodePatch)).then(() => {
expect(store.getActions()).toEqual([
NodesActions.updateNodePending('someId'),
NodesActions.updateNodeSuccess({ uuid: 'someId' })
]);
});
});
}));
});
describe('Delete Nodes thunk action', () => {
@ -422,12 +411,11 @@ describe('Delete Nodes thunk action', () => {
.mockReturnValue(() => Promise.resolve());
});
it('successfully deletes a set of nodes', () => {
return store.dispatch(NodesActions.deleteNodes(nodeIds)).then(() => {
it('successfully deletes a set of nodes', () =>
store.dispatch(NodesActions.deleteNodes(nodeIds)).then(() => {
expect(store.getActions()).toEqual([
NodesActions.startOperation(nodeIds),
NodesActions.deleteNodeSuccess(nodeIds[0])
]);
});
});
}));
});

View File

@ -77,8 +77,8 @@ describe('ParametersActions', () => {
.mockReturnValue(() => Promise.resolve(responseBody));
});
it('dispatches actions', () => {
return store
it('dispatches actions', () =>
store
.dispatch(ParametersActions.fetchParameters('overcloud'))
.then(() => {
expect(MistralApiService.runAction).toHaveBeenCalled();
@ -86,8 +86,7 @@ describe('ParametersActions', () => {
ParametersActions.fetchParametersPending(),
ParametersActions.fetchParametersSuccess(normalizedResponse)
]);
});
});
}));
});
describe('updateParameters (fail)', () => {
@ -101,8 +100,8 @@ describe('ParametersActions', () => {
ErrorActions.handleErrors = jest.fn().mockReturnValue(() => {});
});
it('calls required actions', () => {
return store
it('calls required actions', () =>
store
.dispatch(
ParametersActions.updateParameters('overcloud', { foo: 'bar' })
)
@ -123,7 +122,6 @@ describe('ParametersActions', () => {
}
})
]);
});
});
}));
});
});

View File

@ -36,8 +36,8 @@ describe('PlansActions', () => {
.mockReturnValue(() => Promise.resolve());
});
it('dispatches actions', () => {
return store
it('dispatches actions', () =>
store
.dispatch(
PlansActions.updatePlan('somecloud', {
someFile: { contents: 'file contents' }
@ -48,8 +48,7 @@ describe('PlansActions', () => {
expect(store.getActions()).toEqual([
PlansActions.updatePlanPending('somecloud')
]);
});
});
}));
});
describe('createPlan', () => {
@ -67,15 +66,10 @@ describe('PlansActions', () => {
.mockReturnValue(() => Promise.resolve());
});
it('dispatches actions', () => {
return store
.dispatch(PlansActions.createPlan('somecloud', {}))
.then(() => {
expect(store.getActions()).toEqual([
PlansActions.createPlanPending()
]);
});
});
it('dispatches actions', () =>
store.dispatch(PlansActions.createPlan('somecloud', {})).then(() => {
expect(store.getActions()).toEqual([PlansActions.createPlanPending()]);
}));
});
describe('deletePlans', () => {
@ -87,8 +81,8 @@ describe('PlansActions', () => {
.mockReturnValue(() => Promise.resolve());
});
it('dispatches actions', () => {
return store
it('dispatches actions', () =>
store
.dispatch(PlansActions.deletePlan('somecloud', mockHistory))
.then(() => {
expect(store.getActions().map(action => action.type)).toEqual([
@ -96,8 +90,7 @@ describe('PlansActions', () => {
'DELETE_PLAN_SUCCESS',
'NOTIFY'
]);
});
});
}));
});
describe('fetchPlans', () => {
@ -124,15 +117,14 @@ describe('PlansActions', () => {
.mockReturnValue(() => Promise.resolve(apiResponseMistral));
});
it('dispatches actions', () => {
return store.dispatch(PlansActions.fetchPlans()).then(() => {
it('dispatches actions', () =>
store.dispatch(PlansActions.fetchPlans()).then(() => {
expect(MistralApiService.runAction).toHaveBeenCalled();
expect(store.getActions()).toEqual([
PlansActions.requestPlans(),
PlansActions.receivePlans(expectedPlans)
]);
});
});
}));
});
describe('fetchPlan', () => {
@ -152,14 +144,13 @@ describe('PlansActions', () => {
.mockReturnValue(() => Promise.resolve(apiResponse));
});
it('dispatches actions', () => {
return store.dispatch(PlansActions.fetchPlan('overcloud')).then(() => {
it('dispatches actions', () =>
store.dispatch(PlansActions.fetchPlan('overcloud')).then(() => {
expect(SwiftApiService.getContainer).toHaveBeenCalled();
expect(store.getActions()).toEqual([
PlansActions.requestPlan(),
PlansActions.receivePlan('overcloud', normalizedResponse)
]);
});
});
}));
});
});

View File

@ -35,15 +35,14 @@ describe('StacksActions', () => {
.mockReturnValue(() => Promise.resolve(serviceResponse));
});
it('dispatches actions', () => {
return store.dispatch(StacksActions.fetchStacks()).then(() => {
it('dispatches actions', () =>
store.dispatch(StacksActions.fetchStacks()).then(() => {
expect(HeatApiService.getStacks).toHaveBeenCalled();
expect(store.getActions()).toEqual([
StacksActions.fetchStacksPending(),
StacksActions.fetchStacksSuccess(normalizedStacks)
]);
});
});
}));
});
describe('fetchStacks (failed)', () => {
@ -56,15 +55,14 @@ describe('StacksActions', () => {
ErrorActions.handleErrors = jest.fn().mockReturnValue(() => {});
});
it('dispatches actions', () => {
return store.dispatch(StacksActions.fetchStacks()).then(() => {
it('dispatches actions', () =>
store.dispatch(StacksActions.fetchStacks()).then(() => {
expect(HeatApiService.getStacks).toHaveBeenCalled();
expect(store.getActions()).toEqual([
StacksActions.fetchStacksPending(),
StacksActions.fetchStacksFailed()
]);
});
});
}));
});
// describe('fetchStacks (failed)', () => {

View File

@ -81,8 +81,8 @@ describe('FetchValidations action', () => {
.mockReturnValue(() => Promise.resolve(response));
});
it('dispatches appropriate actions and normalizes the response', () => {
return store.dispatch(ValidationsActions.fetchValidations()).then(() => {
it('dispatches appropriate actions and normalizes the response', () =>
store.dispatch(ValidationsActions.fetchValidations()).then(() => {
expect(MistralApiService.runAction).toHaveBeenCalledWith(
MistralConstants.VALIDATIONS_LIST
);
@ -90,8 +90,7 @@ describe('FetchValidations action', () => {
ValidationsActions.fetchValidationsPending(),
ValidationsActions.fetchValidationsSuccess(normalizedResponse)
]);
});
});
}));
});
describe('RunValidation action', () => {
@ -118,8 +117,8 @@ describe('RunValidation action', () => {
.mockReturnValue(() => Promise.resolve(addWorkflowExecutionResponse));
});
it('dispatches appropriate actions', () => {
return store
it('dispatches appropriate actions', () =>
store
.dispatch(ValidationsActions.runValidation('512e', 'overcloud'))
.then(() => {
expect(MistralApiService.runWorkflow).toHaveBeenCalledWith(
@ -134,8 +133,7 @@ describe('RunValidation action', () => {
addWorkflowExecutionResponse
)
]);
});
});
}));
});
// TODO(jtomasek): this test compares 2 immutable records and even though they're the same

View File

@ -18,11 +18,9 @@ import configureMockStore from 'redux-mock-store';
import thunkMiddleware from 'redux-thunk';
export const mockGetIntl = {
getIntl: () => {
return {
formatMessage: msgObj => msgObj.defaultMessage
};
}
getIntl: () => ({
formatMessage: msgObj => msgObj.defaultMessage
})
};
export const mockStore = configureMockStore([

View File

@ -45,8 +45,8 @@ describe('fetchWorkflowExecutions action', () => {
.mockReturnValue(() => Promise.resolve(response));
});
it('dispatches appropriate actions and normalizes the response', () => {
return store
it('dispatches appropriate actions and normalizes the response', () =>
store
.dispatch(WorkflowExecutionsActions.fetchWorkflowExecutions())
.then(() => {
expect(MistralApiService.getWorkflowExecutions).toHaveBeenCalled();
@ -56,8 +56,7 @@ describe('fetchWorkflowExecutions action', () => {
normalizedResponse
)
]);
});
});
}));
});
describe('updateWorkflowExecution action', () => {
@ -69,8 +68,8 @@ describe('updateWorkflowExecution action', () => {
.mockReturnValue(() => Promise.resolve());
});
it('dispatches appropriate actions', () => {
return store
it('dispatches appropriate actions', () =>
store
.dispatch(
WorkflowExecutionsActions.updateWorkflowExecution('512e', {
state: 'PAUSED'
@ -87,6 +86,5 @@ describe('updateWorkflowExecution action', () => {
}),
WorkflowExecutionsActions.addWorkflowExecution()
]);
});
});
}));
});

View File

@ -34,9 +34,7 @@ const mockNoRowsRenderer = function() {
return 'There are no items in data';
};
const mockOnFilter = () => {
return 'Filtering Happened';
};
const mockOnFilter = () => 'Filtering Happened';
describe('DataTable component', () => {
let DataTableVdom, DataTableInstance;

View File

@ -35,8 +35,8 @@ describe('HeatApiService', () => {
.mockReturnValue(() => Promise.resolve(apiResponse));
});
it('returns a stack object based on <planName>', () => {
return store.dispatch(HeatApiService.getStacks()).then(result => {
it('returns a stack object based on <planName>', () =>
store.dispatch(HeatApiService.getStacks()).then(result => {
expect(HeatApiService.defaultRequest).toHaveBeenCalled();
expect(result).toEqual({
stacks: [
@ -44,7 +44,6 @@ describe('HeatApiService', () => {
{ stack_name: 'anothercloud', stack_status: 'CREATE_FAILED' }
]
});
});
});
}));
});
});

View File

@ -87,13 +87,11 @@ UserAuthenticator.propTypes = {
location: PropTypes.object.isRequired
};
const mapStateToProps = state => {
return {
isAuthenticated: state.login.isAuthenticated,
isAuthenticating: state.login.isAuthenticating,
keystoneAuthTokenId: state.login.tokenId
};
};
const mapStateToProps = state => ({
isAuthenticated: state.login.isAuthenticated,
isAuthenticating: state.login.isAuthenticating,
keystoneAuthTokenId: state.login.tokenId
});
const mapDispatchToProps = dispatch => ({
authenticateUserViaToken: tokenId =>

View File

@ -134,23 +134,21 @@ ValidationsWarning.propTypes = {
};
export const DeployButton = injectIntl(
({ deploy, disabled, intl, isRequestingPlanDeploy }) => {
return (
<button
type="button"
disabled={disabled}
className="btn btn-lg btn-primary"
onClick={() => deploy()}
({ deploy, disabled, intl, isRequestingPlanDeploy }) => (
<button
type="button"
disabled={disabled}
className="btn btn-lg btn-primary"
onClick={() => deploy()}
>
<InlineLoader
loaded={!isRequestingPlanDeploy}
content={intl.formatMessage(messages.requestingDeploymentLoader)}
>
<InlineLoader
loaded={!isRequestingPlanDeploy}
content={intl.formatMessage(messages.requestingDeploymentLoader)}
>
<FormattedMessage {...messages.deployButton} />
</InlineLoader>
</button>
);
}
<FormattedMessage {...messages.deployButton} />
</InlineLoader>
</button>
)
);
DeployButton.propTypes = {
deploy: PropTypes.func.isRequired,

View File

@ -173,34 +173,30 @@ DeploymentDetail.propTypes = {
stacksLoaded: PropTypes.bool.isRequired
};
const mapStateToProps = state => {
return {
allPreDeploymentValidationsSuccessful: allPreDeploymentValidationsSuccessful(
state
),
currentPlan: getCurrentPlan(state),
currentPlanName: getCurrentPlanName(state),
currentStack: getCurrentStack(state),
currentStackDeploymentProgress: getCurrentStackDeploymentProgress(state),
currentStackResources: state.stacks.resources,
currentStackResourcesLoaded: state.stacks.resourcesLoaded,
environmentConfigurationSummary: getEnvironmentConfigurationSummary(state),
overcloudInfo: getOvercloudInfo(state),
stacksLoaded: state.stacks.isLoaded
};
};
const mapStateToProps = state => ({
allPreDeploymentValidationsSuccessful: allPreDeploymentValidationsSuccessful(
state
),
currentPlan: getCurrentPlan(state),
currentPlanName: getCurrentPlanName(state),
currentStack: getCurrentStack(state),
currentStackDeploymentProgress: getCurrentStackDeploymentProgress(state),
currentStackResources: state.stacks.resources,
currentStackResourcesLoaded: state.stacks.resourcesLoaded,
environmentConfigurationSummary: getEnvironmentConfigurationSummary(state),
overcloudInfo: getOvercloudInfo(state),
stacksLoaded: state.stacks.isLoaded
});
const mapDispatchToProps = dispatch => {
return {
deployPlan: planName => dispatch(PlanActions.deployPlan(planName)),
fetchStackResources: stack =>
dispatch(StacksActions.fetchResources(stack.stack_name, stack.id)),
runPreDeploymentValidations: planName =>
dispatch(
ValidationsActions.runValidationGroups(['pre-deployment'], planName)
)
};
};
const mapDispatchToProps = dispatch => ({
deployPlan: planName => dispatch(PlanActions.deployPlan(planName)),
fetchStackResources: stack =>
dispatch(StacksActions.fetchResources(stack.stack_name, stack.id)),
runPreDeploymentValidations: planName =>
dispatch(
ValidationsActions.runValidationGroups(['pre-deployment'], planName)
)
});
export default injectIntl(
connect(mapStateToProps, mapDispatchToProps)(DeploymentDetail)

View File

@ -87,11 +87,9 @@ class StackResourcesTable extends React.Component {
let dataKeys = ['resource_name', 'resource_status'];
return filterString
? data.filter(row => {
let result = dataKeys.filter(dataKey => {
return row[dataKey]
.toLowerCase()
.includes(filterString.toLowerCase());
});
let result = dataKeys.filter(dataKey =>
row[dataKey].toLowerCase().includes(filterString.toLowerCase())
);
return result.length > 0;
})
: data;

View File

@ -28,21 +28,19 @@ const messages = defineMessages({
}
});
const ConfigurePlanStep = props => {
return (
<div>
<DeploymentConfigurationSummary {...props} />
<br />
<Link
className="btn btn-default"
id="ConfigurePlanStep__EditDeploymentLink"
to={`/plans/${props.planName}/configuration`}
>
<FormattedMessage {...messages.editConfigurationLink} />
</Link>
</div>
);
};
const ConfigurePlanStep = props => (
<div>
<DeploymentConfigurationSummary {...props} />
<br />
<Link
className="btn btn-default"
id="ConfigurePlanStep__EditDeploymentLink"
to={`/plans/${props.planName}/configuration`}
>
<FormattedMessage {...messages.editConfigurationLink} />
</Link>
</div>
);
ConfigurePlanStep.propTypes = {
fetchEnvironmentConfiguration: PropTypes.func.isRequired,
isFetching: PropTypes.bool.isRequired,

View File

@ -17,21 +17,19 @@
import React from 'react';
import PropTypes from 'prop-types';
export const DeploymentPlanStep = ({ children, disabled, title, tooltip }) => {
return (
<li className={disabled ? 'disabled' : null}>
<h3>
<span>{title}</span>
{tooltip ? (
<span data-tooltip={tooltip} className="tooltip-right">
<span className="pficon pficon-info" />
</span>
) : null}
</h3>
{children}
</li>
);
};
export const DeploymentPlanStep = ({ children, disabled, title, tooltip }) => (
<li className={disabled ? 'disabled' : null}>
<h3>
<span>{title}</span>
{tooltip ? (
<span data-tooltip={tooltip} className="tooltip-right">
<span className="pficon pficon-info" />
</span>
) : null}
</h3>
{children}
</li>
);
DeploymentPlanStep.propTypes = {
children: PropTypes.node,

View File

@ -25,12 +25,10 @@ const messages = defineMessages({
}
});
const HardwareStep = () => {
return (
<Link className="btn btn-default" to="/nodes/register">
<FormattedMessage {...messages.registerNodes} />
</Link>
);
};
const HardwareStep = () => (
<Link className="btn btn-default" to="/nodes/register">
<FormattedMessage {...messages.registerNodes} />
</Link>
);
export default HardwareStep;

View File

@ -40,22 +40,20 @@ const EnvironmentCheckBox = ({
meta,
required,
...rest
}) => {
return (
<FormGroup
controlId={id}
validationState={getValidationState({ ...meta, touched: true })}
>
<Col smOffset={labelColumns} sm={inputColumns}>
<Checkbox {...input} {...rest}>
<span className={cx({ 'required-pf': required })}>{label}</span>
</Checkbox>
<InputMessage {...meta} touched />
<InputDescription description={description} />
</Col>
</FormGroup>
);
};
}) => (
<FormGroup
controlId={id}
validationState={getValidationState({ ...meta, touched: true })}
>
<Col smOffset={labelColumns} sm={inputColumns}>
<Checkbox {...input} {...rest}>
<span className={cx({ 'required-pf': required })}>{label}</span>
</Checkbox>
<InputMessage {...meta} touched />
<InputDescription description={description} />
</Col>
</FormGroup>
);
EnvironmentCheckBox.propTypes = {
description: PropTypes.node,
id: PropTypes.string.isRequired,

View File

@ -71,18 +71,14 @@ I18nDropdown.propTypes = {
languages: ImmutablePropTypes.map.isRequired
};
const mapStateToProps = state => {
return {
languages: getEnabledLanguages(state),
currentLanguage: getCurrentLanguage(state)
};
};
const mapStateToProps = state => ({
languages: getEnabledLanguages(state),
currentLanguage: getCurrentLanguage(state)
});
const mapDispatchToProps = dispatch => {
return {
chooseLanguage: language => dispatch(I18nActions.chooseLanguage(language))
};
};
const mapDispatchToProps = dispatch => ({
chooseLanguage: language => dispatch(I18nActions.chooseLanguage(language))
});
export default injectIntl(
connect(mapStateToProps, mapDispatchToProps)(I18nDropdown)

View File

@ -58,17 +58,13 @@ I18nProvider.defaultProps = {
messages: {}
};
const mapDispatchToProps = dispatch => {
return {
detectLanguage: language => dispatch(I18nActions.detectLanguage(language))
};
};
const mapDispatchToProps = dispatch => ({
detectLanguage: language => dispatch(I18nActions.detectLanguage(language))
});
const mapStateToProps = state => {
return {
language: getCurrentLanguage(state),
messages: getCurrentLanguageMessages(state)
};
};
const mapStateToProps = state => ({
language: getCurrentLanguage(state),
messages: getCurrentLanguageMessages(state)
});
export default connect(mapStateToProps, mapDispatchToProps)(I18nProvider);

View File

@ -22,13 +22,11 @@ import { injectIntl } from 'react-intl';
class LanguageInput extends React.Component {
_renderOptions() {
return this.props.languages
.map((langName, langKey) => {
return (
<option key={`lang-${langKey}`} value={langKey}>
{langName}
</option>
);
})
.map((langName, langKey) => (
<option key={`lang-${langKey}`} value={langKey}>
{langName}
</option>
))
.toList();
}

View File

@ -226,12 +226,10 @@ function mapStateToProps(state) {
};
}
const mapDispatchToProps = dispatch => {
return {
chooseLanguage: language => dispatch(I18nActions.chooseLanguage(language)),
authenticateUser: (formData, formFields, nextPath) =>
dispatch(LoginActions.authenticateUser(formData, formFields, nextPath))
};
};
const mapDispatchToProps = dispatch => ({
chooseLanguage: language => dispatch(I18nActions.chooseLanguage(language)),
authenticateUser: (formData, formFields, nextPath) =>
dispatch(LoginActions.authenticateUser(formData, formFields, nextPath))
});
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(Login));

View File

@ -118,21 +118,19 @@ class NodeExtendedInfo extends React.Component {
<dd>
{node
.getIn(['introspectionData', 'interfaces'])
.map((ifc, k) => {
return (
<div key={k}>
{k} -{' '}
<span title={intl.formatMessage(messages.macAddress)}>
{ifc.get('mac')}
</span>{' '}
|{' '}
<span title={intl.formatMessage(messages.ipAddress)}>
{ifc.get('ip')}
</span>
{ifc.get('pxe') && '| PXE'}
</div>
);
})
.map((ifc, k) => (
<div key={k}>
{k} -{' '}
<span title={intl.formatMessage(messages.macAddress)}>
{ifc.get('mac')}
</span>{' '}
|{' '}
<span title={intl.formatMessage(messages.ipAddress)}>
{ifc.get('ip')}
</span>
{ifc.get('pxe') && '| PXE'}
</div>
))
.toList()}
</dd>
</dl>

View File

@ -130,11 +130,9 @@ class NodesTable extends React.Component {
let dataKeys = ['name'];
return filterString
? data.filter(row => {
let result = dataKeys.filter(dataKey => {
return row[dataKey]
.toLowerCase()
.includes(filterString.toLowerCase());
});
let result = dataKeys.filter(dataKey =>
row[dataKey].toLowerCase().includes(filterString.toLowerCase())
);
return result.length > 0;
})
: data;

View File

@ -183,27 +183,23 @@ NodesToolbar.propTypes = {
submitNodesToolbarForm: PropTypes.func.isRequired,
updateFilter: PropTypes.func.isRequired
};
const mapDispatchToProps = dispatch => {
return {
clearActiveFilters: () => dispatch(clearActiveFilters('nodesToolbar')),
deleteActiveFilter: uuid =>
dispatch(deleteActiveFilter('nodesToolbar', uuid)),
submitNodesToolbarForm: () => dispatch(submit('nodesToolbar')),
addActiveFilter: data => dispatch(addActiveFilter('nodesToolbar', data)),
updateFilter: data => dispatch(updateFilter('nodesToolbar', data))
};
};
const mapStateToProps = state => {
return {
activeFilters: getActiveFilters(state, 'nodesToolbar'),
filteredNodesCount: getFilteredNodes(state).size,
filteredNodes: getFilteredNodes(state),
nodesToolbarFilter: getFilterByName(state, 'nodesToolbar').delete(
'activeFilters'
),
nodesCount: getNodes(state).size
};
};
const mapDispatchToProps = dispatch => ({
clearActiveFilters: () => dispatch(clearActiveFilters('nodesToolbar')),
deleteActiveFilter: uuid =>
dispatch(deleteActiveFilter('nodesToolbar', uuid)),
submitNodesToolbarForm: () => dispatch(submit('nodesToolbar')),
addActiveFilter: data => dispatch(addActiveFilter('nodesToolbar', data)),
updateFilter: data => dispatch(updateFilter('nodesToolbar', data))
});
const mapStateToProps = state => ({
activeFilters: getActiveFilters(state, 'nodesToolbar'),
filteredNodesCount: getFilteredNodes(state).size,
filteredNodes: getFilteredNodes(state),
nodesToolbarFilter: getFilterByName(state, 'nodesToolbar').delete(
'activeFilters'
),
nodesCount: getNodes(state).size
});
export default injectIntl(
connect(mapStateToProps, mapDispatchToProps)(NodesToolbar)
);

View File

@ -65,24 +65,22 @@ class NodesFileUpload extends React.Component {
const file = event.target.files[0];
const reader = new FileReader();
reader.onload = (f => {
return e => {
if (file.name.match(/(\.json)$/)) {
this.addNodesFromInstackenvJSON(e.target.result);
} else if (file.name.match(/(\.csv)$/)) {
// TODO(jtomasek): add CSV file support
// this.addNodesFromCSV(e.target.result);
notify({
title: formatMessage(messages.csvUnsupported),
message: formatMessage(messages.selectedFileUnsupported)
});
} else {
notify({
title: formatMessage(messages.unsupportedFileFormat),
message: formatMessage(messages.provideCsvOrInstackenvJson)
});
}
};
reader.onload = (f => e => {
if (file.name.match(/(\.json)$/)) {
this.addNodesFromInstackenvJSON(e.target.result);
} else if (file.name.match(/(\.csv)$/)) {
// TODO(jtomasek): add CSV file support
// this.addNodesFromCSV(e.target.result);
notify({
title: formatMessage(messages.csvUnsupported),
message: formatMessage(messages.selectedFileUnsupported)
});
} else {
notify({
title: formatMessage(messages.unsupportedFileFormat),
message: formatMessage(messages.provideCsvOrInstackenvJson)
});
}
})(file);
reader.readAsText(file);
this.refs.regNodesUploadFileForm.reset();

View File

@ -114,114 +114,112 @@ const RegisterNodeFields = ({
node,
intl: { formatMessage },
selectedDriver
}) => {
return (
<div>
<h4>
<FormattedMessage {...messages.nodeDetail} />
</h4>
<Fieldset legend={formatMessage(messages.general)}>
<Field
name={`${node}.name`}
component={HorizontalInput}
id={`${node}.name`}
label={formatMessage(messages.name)}
validate={[
format({
with: NODE_NAME_REGEX,
message: formatMessage(messages.nodeNameRegexp),
allowBlank: true
}),
length({ max: 255 })
]}
/>
</Fieldset>
<Fieldset legend={formatMessage(messages.management)}>
<Field
name={`${node}.pm_type`}
component={HorizontalSelect}
id={`${node}.pm_type`}
label={formatMessage(messages.driver)}
validate={required()}
required
>
{['pxe_ipmitool', 'pxe_drac'].map((value, index) => (
<option key={index}>{value}</option>
))}
</Field>
{renderDriverFields(selectedDriver, node)}
</Fieldset>
<Fieldset legend={formatMessage(messages.hardware)}>
<Field
name={`${node}.arch`}
component={HorizontalSelect}
id={`${node}.arch`}
label={formatMessage(messages.architecture)}
>
{[undefined, 'x86_64', 'i386'].map((value, index) => (
<option key={index}>{value}</option>
))}
</Field>
<Field
name={`${node}.cpu`}
component={HorizontalInput}
id={`${node}.cpu`}
label={formatMessage(messages.cpuCount)}
type="number"
min={1}
validate={numericality({
int: true,
'>': 0,
}) => (
<div>
<h4>
<FormattedMessage {...messages.nodeDetail} />
</h4>
<Fieldset legend={formatMessage(messages.general)}>
<Field
name={`${node}.name`}
component={HorizontalInput}
id={`${node}.name`}
label={formatMessage(messages.name)}
validate={[
format({
with: NODE_NAME_REGEX,
message: formatMessage(messages.nodeNameRegexp),
allowBlank: true
})}
/>
<Field
name={`${node}.memory`}
component={HorizontalInput}
id={`${node}.memory`}
label={formatMessage(messages.memoryMb)}
type="number"
min={1}
validate={numericality({
int: true,
'>': 0,
allowBlank: true
})}
/>
<Field
name={`${node}.disk`}
component={HorizontalInput}
id={`${node}.disk`}
label={formatMessage(messages.diskGb)}
type="number"
min={1}
validate={numericality({
int: true,
'>': 0,
allowBlank: true
})}
/>
</Fieldset>
<Fieldset legend={formatMessage(messages.networking)}>
<Field
name={`${node}.mac`}
component={HorizontalInput}
id={`${node}.mac`}
label={formatMessage(messages.nicMacAddresses)}
description={formatMessage(messages.macAddressesDescription)}
validate={[
arrayOfFormat({
with: MAC_ADDRESS_REGEX,
message: messages.enterValidMacAddress
})
]}
parse={value => value.split(',')}
required
/>
</Fieldset>
</div>
);
};
}),
length({ max: 255 })
]}
/>
</Fieldset>
<Fieldset legend={formatMessage(messages.management)}>
<Field
name={`${node}.pm_type`}
component={HorizontalSelect}
id={`${node}.pm_type`}
label={formatMessage(messages.driver)}
validate={required()}
required
>
{['pxe_ipmitool', 'pxe_drac'].map((value, index) => (
<option key={index}>{value}</option>
))}
</Field>
{renderDriverFields(selectedDriver, node)}
</Fieldset>
<Fieldset legend={formatMessage(messages.hardware)}>
<Field
name={`${node}.arch`}
component={HorizontalSelect}
id={`${node}.arch`}
label={formatMessage(messages.architecture)}
>
{[undefined, 'x86_64', 'i386'].map((value, index) => (
<option key={index}>{value}</option>
))}
</Field>
<Field
name={`${node}.cpu`}
component={HorizontalInput}
id={`${node}.cpu`}
label={formatMessage(messages.cpuCount)}
type="number"
min={1}
validate={numericality({
int: true,
'>': 0,
allowBlank: true
})}
/>
<Field
name={`${node}.memory`}
component={HorizontalInput}
id={`${node}.memory`}
label={formatMessage(messages.memoryMb)}
type="number"
min={1}
validate={numericality({
int: true,
'>': 0,
allowBlank: true
})}
/>
<Field
name={`${node}.disk`}
component={HorizontalInput}
id={`${node}.disk`}
label={formatMessage(messages.diskGb)}
type="number"
min={1}
validate={numericality({
int: true,
'>': 0,
allowBlank: true
})}
/>
</Fieldset>
<Fieldset legend={formatMessage(messages.networking)}>
<Field
name={`${node}.mac`}
component={HorizontalInput}
id={`${node}.mac`}
label={formatMessage(messages.nicMacAddresses)}
description={formatMessage(messages.macAddressesDescription)}
validate={[
arrayOfFormat({
with: MAC_ADDRESS_REGEX,
message: messages.enterValidMacAddress
})
]}
parse={value => value.split(',')}
required
/>
</Fieldset>
</div>
);
RegisterNodeFields.propTypes = {
intl: PropTypes.object.isRequired,
node: PropTypes.string.isRequired,

View File

@ -36,23 +36,19 @@ const messages = defineMessages({
}
});
export const RegisterNodesTabPanes = ({ fields, meta, selectedNodeIndex }) => {
return (
<div className="tab-content">
{fields.map((node, index, fields) => {
return (
<TabPane
key={index}
isActive={selectedNodeIndex === index}
// renderOnlyActive
>
<RegisterNodeFields node={node} />
</TabPane>
);
})}
</div>
);
};
export const RegisterNodesTabPanes = ({ fields, meta, selectedNodeIndex }) => (
<div className="tab-content">
{fields.map((node, index, fields) => (
<TabPane
key={index}
isActive={selectedNodeIndex === index}
// renderOnlyActive
>
<RegisterNodeFields node={node} />
</TabPane>
))}
</div>
);
RegisterNodesTabPanes.propTypes = {
fields: PropTypes.object.isRequired,
meta: PropTypes.object.isRequired,

View File

@ -42,8 +42,9 @@ class NotificationsToaster extends React.Component {
}
renderNotifications() {
return this.props.notifications.toList().map(notification => {
return (
return this.props.notifications
.toList()
.map(notification => (
<Notification
key={notification.id}
title={notification.title}
@ -55,8 +56,7 @@ class NotificationsToaster extends React.Component {
this.props.removeNotification(notification.id)
}
/>
);
});
));
}
render() {

View File

@ -36,19 +36,17 @@ class ParameterInputList extends React.Component {
this.props.emptyParametersMessage ||
this.props.intl.formatMessage(messages.noParameters);
const parameters = this.props.parameters.map(parameter => {
return (
<ParameterInput
key={parameter.name}
name={parameter.name}
label={parameter.label}
description={parameter.description}
defaultValue={parameter.default}
value={parameter.value}
type={parameter.type}
/>
);
});
const parameters = this.props.parameters.map(parameter => (
<ParameterInput
key={parameter.name}
name={parameter.name}
label={parameter.label}
description={parameter.description}
defaultValue={parameter.default}
value={parameter.value}
type={parameter.type}
/>
));
if (parameters.isEmpty()) {
return (

View File

@ -66,17 +66,15 @@ class Parameters extends React.Component {
</TabPane>
);
} else {
return this.props.enabledEnvironments.toList().map(environment => {
return (
<TabPane
isActive={this.state.activeTab === environment.file}
key={environment.file}
renderOnlyActive
>
<EnvironmentParameters environment={environment.file} />
</TabPane>
);
});
return this.props.enabledEnvironments.toList().map(environment => (
<TabPane
isActive={this.state.activeTab === environment.file}
key={environment.file}
renderOnlyActive
>
<EnvironmentParameters environment={environment.file} />
</TabPane>
));
}
}

View File

@ -166,8 +166,8 @@ const convertJsonTypeParameterValueToString = value =>
// accept empty string as valid value
['', undefined].includes(value) ? '' : JSON.stringify(value);
const getFormInitialValues = parameters => {
return parameters
const getFormInitialValues = parameters =>
parameters
.map(p => {
const value = p.value === undefined ? p.default : p.value;
if (p.type.toLowerCase() === 'json') {
@ -177,22 +177,20 @@ const getFormInitialValues = parameters => {
}
})
.toJS();
};
/**
* Filter out non updated parameters, so only parameters which have been actually changed
* get sent to updateparameters
*/
const filterFormData = (values, initialValues) => {
return pickBy(values, (value, key) => !isEqual(value, initialValues[key]));
};
const filterFormData = (values, initialValues) =>
pickBy(values, (value, key) => !isEqual(value, initialValues[key]));
/**
* Json parameter values are sent as string, this function parses them and checks if they're object
* or array. Also, parameters with undefined value are set to null
*/
const parseJsonTypeValues = (values, parameters) => {
return mapValues(values, (value, key) => {
const parseJsonTypeValues = (values, parameters) =>
mapValues(values, (value, key) => {
if (parameters.get(key).type.toLowerCase() === 'json') {
try {
return JSON.parse(value);
@ -202,7 +200,6 @@ const parseJsonTypeValues = (values, parameters) => {
}
return value === undefined ? null : value;
});
};
const handleSubmit = (
{ saveAndClose, ...values },

View File

@ -49,19 +49,17 @@ const ParametersSidebar = ({
</a>
</Tab>
<li className="spacer" />
{enabledEnvironments.map(environment => {
return (
<Tab key={environment.file} isActive={isTabActive(environment.file)}>
<a
className="link"
onClick={() => activateTab(environment.file)}
title={environment.file}
>
{environment.title}
</a>
</Tab>
);
})}
{enabledEnvironments.map(environment => (
<Tab key={environment.file} isActive={isTabActive(environment.file)}>
<a
className="link"
onClick={() => activateTab(environment.file)}
title={environment.file}
>
{environment.title}
</a>
</Tab>
))}
</ul>
</div>
);

View File

@ -52,36 +52,32 @@ class PlanFileInput extends React.Component {
let reader = new FileReader();
let file = inputFiles[i];
reader.onerror = (f => {
return e => {
this.setState({
unreadableFile: f.webkitRelativePath
});
};
reader.onerror = (f => e => {
this.setState({
unreadableFile: f.webkitRelativePath
});
})(file);
reader.onload = (f => {
return e => {
const filePath = f.webkitRelativePath.replace(/^[^\/]*\//, '');
if (!filePath.match(IGNORED_FILE_PATHS)) {
let obj = {
name: filePath,
content: e.target.result
};
files.push(obj);
}
processedFilesCount += 1;
this.setState(
{ progress: Math.round(100 / l * processedFilesCount) },
() => {
// if the last file is processed, setValue -> triggers onChange on Formsy
if (processedFilesCount === l) {
this.props.setValue(files);
this.setState({ progress: 0 });
}
reader.onload = (f => e => {
const filePath = f.webkitRelativePath.replace(/^[^\/]*\//, '');
if (!filePath.match(IGNORED_FILE_PATHS)) {
let obj = {
name: filePath,
content: e.target.result
};
files.push(obj);
}
processedFilesCount += 1;
this.setState(
{ progress: Math.round(100 / l * processedFilesCount) },
() => {
// if the last file is processed, setValue -> triggers onChange on Formsy
if (processedFilesCount === l) {
this.props.setValue(files);
this.setState({ progress: 0 });
}
);
};
}
);
})(file);
reader.readAsText(file);
}

View File

@ -38,33 +38,31 @@ const NodesAssignment = ({
nodeCountParametersByRole,
roles,
updateNodesAssignment
}) => {
return (
<NodesAssignmentForm
currentPlanName={currentPlanName}
initialValues={assignedNodesCountsByRole.toJS()}
updateNodesAssignment={updateNodesAssignment}
>
<div className="row row-cards-pf">
{roles.toList().map(role => {
return (
<RoleCard
key={role.name}
currentPlanName={currentPlanName}
name={role.name}
title={startCase(role.name)}
identifier={role.identifier}
assignedNodesCountParameter={nodeCountParametersByRole.get(
role.name
)}
availableNodesCount={availableNodesCountsByRole.get(role.name)}
/>
);
})}
</div>
</NodesAssignmentForm>
);
};
}) => (
<NodesAssignmentForm
currentPlanName={currentPlanName}
initialValues={assignedNodesCountsByRole.toJS()}
updateNodesAssignment={updateNodesAssignment}
>
<div className="row row-cards-pf">
{roles
.toList()
.map(role => (
<RoleCard
key={role.name}
currentPlanName={currentPlanName}
name={role.name}
title={startCase(role.name)}
identifier={role.identifier}
assignedNodesCountParameter={nodeCountParametersByRole.get(
role.name
)}
availableNodesCount={availableNodesCountsByRole.get(role.name)}
/>
))}
</div>
</NodesAssignmentForm>
);
NodesAssignment.propTypes = {
assignedNodesCountsByRole: ImmutablePropTypes.map.isRequired,
availableNodesCountsByRole: ImmutablePropTypes.map.isRequired,
@ -82,12 +80,10 @@ const mapStateToProps = state => ({
roles: getRoles(state)
});
const mapDispatchToProps = dispatch => {
return {
updateNodesAssignment: (currentPlanName, data) => {
dispatch(ParametersActions.updateNodesAssignment(currentPlanName, data));
}
};
};
const mapDispatchToProps = dispatch => ({
updateNodesAssignment: (currentPlanName, data) => {
dispatch(ParametersActions.updateNodesAssignment(currentPlanName, data));
}
});
export default connect(mapStateToProps, mapDispatchToProps)(NodesAssignment);

View File

@ -53,22 +53,17 @@ class RoleServices extends React.Component {
}
renderServiceTabs() {
return this.props.services.toList().map(service => {
return (
<Tab
key={service.type}
title={service.description}
isActive={service.id === this.state.selectedService}
>
<a
className="link"
onClick={this.selectService.bind(this, service.id)}
>
{service.type.split('::').pop()}
</a>
</Tab>
);
});
return this.props.services.toList().map(service => (
<Tab
key={service.type}
title={service.description}
isActive={service.id === this.state.selectedService}
>
<a className="link" onClick={this.selectService.bind(this, service.id)}>
{service.type.split('::').pop()}
</a>
</Tab>
));
}
render() {

View File

@ -18,20 +18,18 @@ import PropTypes from 'prop-types';
import React from 'react';
import { Link, Route } from 'react-router-dom';
const NavTab = ({ activeClassName, children, to, exact, location, id }) => {
return (
<Route
location={location}
path={typeof to === 'object' ? to.pathname : to}
exact={exact}
children={({ match, location }) => (
<li className={match ? activeClassName : ''} id={id}>
<Link to={to}>{children}</Link>
</li>
)}
/>
);
};
const NavTab = ({ activeClassName, children, to, exact, location, id }) => (
<Route
location={location}
path={typeof to === 'object' ? to.pathname : to}
exact={exact}
children={({ match, location }) => (
<li className={match ? activeClassName : ''} id={id}>
<Link to={to}>{children}</Link>
</li>
)}
/>
);
NavTab.propTypes = {
activeClassName: PropTypes.string.isRequired,
children: PropTypes.node,

View File

@ -18,18 +18,16 @@ import { Button } from 'react-bootstrap';
import PropTypes from 'prop-types';
import React from 'react';
export const SortDirectionInput = ({ input: { onChange, value }, title }) => {
return (
<Button
title={title}
type="button"
bsStyle="link"
onClick={() => onChange(value === 'asc' ? 'desc' : 'asc')}
>
<span className={`fa fa-sort-alpha-${value}`} />
</Button>
);
};
export const SortDirectionInput = ({ input: { onChange, value }, title }) => (
<Button
title={title}
type="button"
bsStyle="link"
onClick={() => onChange(value === 'asc' ? 'desc' : 'asc')}
>
<span className={`fa fa-sort-alpha-${value}`} />
</Button>
);
SortDirectionInput.propTypes = {
children: PropTypes.node,
input: PropTypes.object.isRequired,
@ -50,24 +48,22 @@ const getIconClass = optionKey => {
export const ContentViewSelectorInput = ({
input: { onChange, value },
options
}) => {
return (
<div>
{Object.keys(options).map(k => (
<Button
key={k}
type="button"
bsStyle="link"
title={options[k]['title']}
id={options[k]['id']}
onClick={() => onChange(k)}
>
<i className={getIconClass(k)} />
</Button>
))}
</div>
);
};
}) => (
<div>
{Object.keys(options).map(k => (
<Button
key={k}
type="button"
bsStyle="link"
title={options[k]['title']}
id={options[k]['id']}
onClick={() => onChange(k)}
>
<i className={getIconClass(k)} />
</Button>
))}
</div>
);
ContentViewSelectorInput.propTypes = {
input: PropTypes.object.isRequired,
options: PropTypes.object.isRequired

View File

@ -18,20 +18,14 @@ import { Dropdown } from 'react-bootstrap';
import PropTypes from 'prop-types';
import React from 'react';
const DropdownKebab = ({ children, id, pullRight }) => {
return (
<Dropdown className="dropdown-kebab-pf" id={id} pullRight={pullRight}>
<Dropdown.Toggle
bsStyle="link"
noCaret
onClick={e => e.stopPropagation()}
>
<span className="fa fa-ellipsis-v" />
</Dropdown.Toggle>
<Dropdown.Menu>{children}</Dropdown.Menu>
</Dropdown>
);
};
const DropdownKebab = ({ children, id, pullRight }) => (
<Dropdown className="dropdown-kebab-pf" id={id} pullRight={pullRight}>
<Dropdown.Toggle bsStyle="link" noCaret onClick={e => e.stopPropagation()}>
<span className="fa fa-ellipsis-v" />
</Dropdown.Toggle>
<Dropdown.Menu>{children}</Dropdown.Menu>
</Dropdown>
);
DropdownKebab.propTypes = {
children: PropTypes.node,
id: PropTypes.string.isRequired,

View File

@ -18,21 +18,19 @@ import PropTypes from 'prop-types';
import React from 'react';
import { Link, Route } from 'react-router-dom';
const MenuItemLink = ({ children, to, exact, location, ...rest }) => {
return (
<Route
path={to}
exact={exact}
children={({ match, location }) => (
<li onClick={e => e.stopPropagation()}>
<Link {...rest} to={to}>
{children}
</Link>
</li>
)}
/>
);
};
const MenuItemLink = ({ children, to, exact, location, ...rest }) => (
<Route
path={to}
exact={exact}
children={({ match, location }) => (
<li onClick={e => e.stopPropagation()}>
<Link {...rest} to={to}>
{children}
</Link>
</li>
)}
/>
);
MenuItemLink.propTypes = {
children: PropTypes.node,

View File

@ -22,13 +22,11 @@ export default class FormErrorList extends React.Component {
renderErrors() {
const { errors } = this.props;
if (errors.length > 1) {
const errorList = errors.map((error, index) => {
return (
<li key={index}>
{error.title} {error.message}
</li>
);
});
const errorList = errors.map((error, index) => (
<li key={index}>
{error.title} {error.message}
</li>
));
return (
<div>
<strong>{`${errors.length} Errors Found:`}</strong>

View File

@ -32,24 +32,22 @@ const HorizontalCheckBox = ({
meta,
required,
...rest
}) => {
return (
<FormGroup controlId={id} validationState={getValidationState(meta)}>
<Col
componentClass={ControlLabel}
sm={labelColumns}
className={cx({ 'required-pf': required })}
>
{label}
</Col>
<Col sm={inputColumns}>
<Checkbox {...input} {...rest} />
<InputMessage {...meta} />
<InputDescription description={description} />
</Col>
</FormGroup>
);
};
}) => (
<FormGroup controlId={id} validationState={getValidationState(meta)}>
<Col
componentClass={ControlLabel}
sm={labelColumns}
className={cx({ 'required-pf': required })}
>
{label}
</Col>
<Col sm={inputColumns}>
<Checkbox {...input} {...rest} />
<InputMessage {...meta} />
<InputDescription description={description} />
</Col>
</FormGroup>
);
HorizontalCheckBox.propTypes = {
description: PropTypes.node,
id: PropTypes.string.isRequired,

View File

@ -32,24 +32,22 @@ const HorizontalInput = ({
meta,
required,
...rest
}) => {
return (
<FormGroup controlId={id} validationState={getValidationState(meta)}>
<Col
componentClass={ControlLabel}
sm={labelColumns}
className={cx({ 'required-pf': required })}
>
{label}
</Col>
<Col sm={inputColumns}>
<FormControl type={type} {...input} {...rest} />
<InputMessage {...meta} />
<InputDescription description={description} />
</Col>
</FormGroup>
);
};
}) => (
<FormGroup controlId={id} validationState={getValidationState(meta)}>
<Col
componentClass={ControlLabel}
sm={labelColumns}
className={cx({ 'required-pf': required })}
>
{label}
</Col>
<Col sm={inputColumns}>
<FormControl type={type} {...input} {...rest} />
<InputMessage {...meta} />
<InputDescription description={description} />
</Col>
</FormGroup>
);
HorizontalInput.propTypes = {
description: PropTypes.node,
id: PropTypes.string.isRequired,

View File

@ -33,31 +33,29 @@ const HorizontalSelect = ({
meta,
required,
...rest
}) => {
return (
<FormGroup controlId={id} validationState={getValidationState(meta)}>
<Col
componentClass={ControlLabel}
sm={labelColumns}
className={cx({ 'required-pf': required })}
}) => (
<FormGroup controlId={id} validationState={getValidationState(meta)}>
<Col
componentClass={ControlLabel}
sm={labelColumns}
className={cx({ 'required-pf': required })}
>
{label}
</Col>
<Col sm={inputColumns}>
<FormControl
componentClass="select"
multiple={multiple}
{...rest}
{...input}
>
{label}
</Col>
<Col sm={inputColumns}>
<FormControl
componentClass="select"
multiple={multiple}
{...rest}
{...input}
>
{children}
</FormControl>
<InputMessage {...meta} />
<InputDescription description={description} />
</Col>
</FormGroup>
);
};
{children}
</FormControl>
<InputMessage {...meta} />
<InputDescription description={description} />
</Col>
</FormGroup>
);
HorizontalSelect.propTypes = {
children: PropTypes.node,
description: PropTypes.node,

View File

@ -70,18 +70,16 @@ NodePickerInput.defaultProps = {
};
export default NodePickerInput;
const PickerArrow = ({ direction, disabled, onClick }) => {
return (
<button
type="button"
className={`btn btn-default btn-node-picker btn-node-picker-${direction}`}
onClick={onClick}
disabled={disabled}
>
<span className={`fa fa-angle-${direction}`} aria-hidden="true" />
</button>
);
};
const PickerArrow = ({ direction, disabled, onClick }) => (
<button
type="button"
className={`btn btn-default btn-node-picker btn-node-picker-${direction}`}
onClick={onClick}
disabled={disabled}
>
<span className={`fa fa-angle-${direction}`} aria-hidden="true" />
</button>
);
PickerArrow.propTypes = {
direction: PropTypes.oneOf(['up', 'down']).isRequired,
disabled: PropTypes.bool.isRequired,

View File

@ -83,9 +83,7 @@ class DataTable extends React.Component {
render() {
let columns = this._getColumns();
let headers = columns.map(column => {
return column.props.header;
});
let headers = columns.map(column => column.props.header);
let rows = [];
for (var i = 0; i < this.props.rowsCount; ++i) {

View File

@ -19,12 +19,12 @@ import React from 'react';
export default class DataTableRow extends React.Component {
render() {
let cells = this.props.columns.map((column, index) => {
return React.cloneElement(column.props.cell, {
let cells = this.props.columns.map((column, index) =>
React.cloneElement(column.props.cell, {
rowIndex: this.props.index,
key: index
});
});
})
);
return <tr>{cells}</tr>;
}
}

View File

@ -50,23 +50,21 @@ export default class Validation extends React.Component {
}
renderValidationGroups() {
return this.props.groups.map(group => {
return (
<div key={group} className="list-view-pf-additional-info-item">
<span
className="label label-default"
onClick={() =>
this.props.addActiveFilter({
filterBy: 'group',
filterString: group
})
}
>
<small>{group}</small>
</span>
</div>
);
});
return this.props.groups.map(group => (
<div key={group} className="list-view-pf-additional-info-item">
<span
className="label label-default"
onClick={() =>
this.props.addActiveFilter({
filterBy: 'group',
filterString: group
})
}
>
<small>{group}</small>
</span>
</div>
));
}
render() {

View File

@ -86,14 +86,12 @@ class ValidationDetail extends React.Component {
}
renderValidationGroups() {
return this.props.groups.map(group => {
return (
<small key={group}>
<span className="label label-default">{group}</span>
&nbsp;
</small>
);
});
return this.props.groups.map(group => (
<small key={group}>
<span className="label label-default">{group}</span>
&nbsp;
</small>
));
}
renderValidationOutput() {

View File

@ -117,8 +117,9 @@ class ValidationsList extends React.Component {
</BlankSlate>
);
} else {
return validations.toList().map(validation => {
return (
return validations
.toList()
.map(validation => (
<Validation
key={validation.id}
name={validation.name}
@ -139,8 +140,7 @@ class ValidationsList extends React.Component {
id={validation.id}
addActiveFilter={this.props.addActiveFilter}
/>
);
});
));
}
}
@ -226,36 +226,32 @@ ValidationsList.propTypes = {
validationsLoaded: PropTypes.bool.isRequired
};
const mapDispatchToProps = dispatch => {
return {
addActiveFilter: data =>
dispatch(addActiveFilter('validationsToolbar', data)),
fetchValidations: () => dispatch(ValidationsActions.fetchValidations()),
fetchWorkflowExecutions: () =>
dispatch(WorkflowExecutionsActions.fetchWorkflowExecutions()),
runValidation: (id, currentPlanName) => {
dispatch(ValidationsActions.runValidation(id, currentPlanName));
},
stopValidation: executionId => {
dispatch(
WorkflowExecutionsActions.updateWorkflowExecution(executionId, {
state: 'PAUSED'
})
);
}
};
};
const mapDispatchToProps = dispatch => ({
addActiveFilter: data =>
dispatch(addActiveFilter('validationsToolbar', data)),
fetchValidations: () => dispatch(ValidationsActions.fetchValidations()),
fetchWorkflowExecutions: () =>
dispatch(WorkflowExecutionsActions.fetchWorkflowExecutions()),
runValidation: (id, currentPlanName) => {
dispatch(ValidationsActions.runValidation(id, currentPlanName));
},
stopValidation: executionId => {
dispatch(
WorkflowExecutionsActions.updateWorkflowExecution(executionId, {
state: 'PAUSED'
})
);
}
});
const mapStateToProps = state => {
return {
executionsLoaded: state.executions.get('executionsLoaded'),
isFetchingValidations: state.validations.get('isFetching'),
validations: getFilteredValidations(state),
validationsLoaded: state.validations.get('validationsLoaded'),
currentPlanName: getCurrentPlanName(state),
showValidations: state.validations.showValidations
};
};
const mapStateToProps = state => ({
executionsLoaded: state.executions.get('executionsLoaded'),
isFetchingValidations: state.validations.get('isFetching'),
validations: getFilteredValidations(state),
validationsLoaded: state.validations.get('validationsLoaded'),
currentPlanName: getCurrentPlanName(state),
showValidations: state.validations.showValidations
});
export default injectIntl(
connect(mapStateToProps, mapDispatchToProps)(ValidationsList)

View File

@ -140,23 +140,18 @@ ValidationsToolbar.propTypes = {
intl: PropTypes.object,
validationsCount: PropTypes.number.isRequired
};
const mapDispatchToProps = dispatch => {
return {
addActiveFilter: data =>
dispatch(addActiveFilter('validationsToolbar', data)),
clearActiveFilters: () =>
dispatch(clearActiveFilters('validationsToolbar')),
deleteActiveFilter: uuid =>
dispatch(deleteActiveFilter('validationsToolbar', uuid))
};
};
const mapStateToProps = state => {
return {
activeFilters: getActiveFilters(state, 'validationsToolbar'),
filteredValidationsCount: getFilteredValidations(state).size,
validationsCount: getValidationsWithResults(state).size
};
};
const mapDispatchToProps = dispatch => ({
addActiveFilter: data =>
dispatch(addActiveFilter('validationsToolbar', data)),
clearActiveFilters: () => dispatch(clearActiveFilters('validationsToolbar')),
deleteActiveFilter: uuid =>
dispatch(deleteActiveFilter('validationsToolbar', uuid))
});
const mapStateToProps = state => ({
activeFilters: getActiveFilters(state, 'validationsToolbar'),
filteredValidationsCount: getFilteredValidations(state).size,
validationsCount: getValidationsWithResults(state).size
});
export default injectIntl(
connect(mapStateToProps, mapDispatchToProps)(ValidationsToolbar)
);

View File

@ -50,12 +50,12 @@ export default function environmentConfigurationReducer(
case EnvironmentConfigurationConstants.UPDATE_ENVIRONMENT_CONFIGURATION_SUCCESS: {
const enabledEnvs = fromJS(action.payload);
const updatedEnvs = state.environments.map(environment => {
return environment.set(
const updatedEnvs = state.environments.map(environment =>
environment.set(
'enabled',
enabledEnvs.includes(environment.get('file'))
);
});
)
);
return state.set('environments', updatedEnvs);
}

View File

@ -30,11 +30,12 @@ export default function filtersReducer(state = initialState, action) {
// Don't add a new filter if there already is one with the same
// filterBy and filterString.
if (
state.getIn([filter, 'activeFilters']).filter(value => {
return (
value.filterBy === filterBy && value.filterString === filterString
);
}).size > 0
state
.getIn([filter, 'activeFilters'])
.filter(
value =>
value.filterBy === filterBy && value.filterString === filterString
).size > 0
) {
return state;
}

View File

@ -30,17 +30,16 @@ export const getEnvironment = (state, environmentFileName) =>
export const getEnabledEnvironments = createSelector(
getEnvironments,
environments => {
return environments.filter(environment => environment.get('enabled'));
}
environments => environments.filter(environment => environment.get('enabled'))
);
export const getEnvironmentConfigurationSummary = createSelector(
getEnabledEnvironments,
environments => {
const titlesList = environments.reduce((titlesList, environment) => {
return titlesList.push(environment.get('title'));
}, List());
const titlesList = environments.reduce(
(titlesList, environment) => titlesList.push(environment.get('title')),
List()
);
return titlesList.toArray().join(', ');
}
);
@ -50,17 +49,16 @@ export const getEnvironmentConfigurationSummary = createSelector(
*/
export const getTopicsTree = createSelector(
[topics, environmentGroups, getEnvironments],
(topics, environmentGroups, environments) => {
return topics.map(topic => {
return topic.update('environment_groups', envGroups => {
return envGroups.map(envGroup => {
return environmentGroups
(topics, environmentGroups, environments) =>
topics.map(topic =>
topic.update('environment_groups', envGroups =>
envGroups.map(envGroup =>
environmentGroups
.get(envGroup)
.update('environments', envs => {
return environments.filter((p, k) => envs.includes(k));
});
});
});
});
}
.update('environments', envs =>
environments.filter((p, k) => envs.includes(k))
)
)
)
)
);

View File

@ -16,9 +16,7 @@
import { createSelector } from 'reselect';
export const getFilterByName = (state, filterName) => {
return state.filters[filterName];
};
export const getFilterByName = (state, filterName) => state.filters[filterName];
export const getActiveFilters = createSelector(getFilterByName, filter =>
filter.get('activeFilters')

View File

@ -103,11 +103,11 @@ export const getFilteredNodes = createSelector(
.update(nodes =>
nodesToolbarFilter.get('activeFilters').reduce(
(filteredNodes, filter) =>
filteredNodes.filter(node => {
return getNodePropertyString(node, filter.filterBy)
filteredNodes.filter(node =>
getNodePropertyString(node, filter.filterBy)
.toLowerCase()
.includes(filter.filterString.toLowerCase());
}),
.includes(filter.filterString.toLowerCase())
),
nodes
)
)

View File

@ -20,7 +20,5 @@ const notifications = state => state.notifications.get('all');
export const getNonViewedNotifications = createSelector(
notifications,
notifications => {
return notifications.filterNot(notification => notification.viewed);
}
notifications => notifications.filterNot(notification => notification.viewed)
);

View File

@ -126,30 +126,27 @@ export const getRoleNetworkConfig = createSelector(
export const getEnvironmentParameters = createSelector(
[getParametersExclInternal, getResources, getEnvironment],
(parameters, resources, environment) => {
return (
resources
// get list of resources from environment resource_registry
.filter(r => environment.resourceRegistry.keySeq().includes(r.type))
// collect parameter names from those resources
.reduce(
(result, resource) =>
result.union(
_extractParameters(
resource.parameters,
resource.resources,
resources
)
),
Set()
)
// add parameters from environment's 'parameters' section to the list
.union(environment.parameterDefaults.keySeq())
.toMap()
// convert list of parameter names to map of actual parameter records
.update(filterParameters(parameters))
);
}
(parameters, resources, environment) =>
resources
// get list of resources from environment resource_registry
.filter(r => environment.resourceRegistry.keySeq().includes(r.type))
// collect parameter names from those resources
.reduce(
(result, resource) =>
result.union(
_extractParameters(
resource.parameters,
resource.resources,
resources
)
),
Set()
)
// add parameters from environment's 'parameters' section to the list
.union(environment.parameterDefaults.keySeq())
.toMap()
// convert list of parameter names to map of actual parameter records
.update(filterParameters(parameters))
);
/**
@ -195,8 +192,8 @@ export const getResourceParametersDeep = createSelector(
/**
* Recursively extracts Parameter names from a Resource and it's nested Resources
*/
const _extractParameters = (parameters, nestedResources, allResources) => {
return nestedResources.reduce((pars, res) => {
const _extractParameters = (parameters, nestedResources, allResources) =>
nestedResources.reduce((pars, res) => {
const resource = allResources.get(res);
return _extractParameters(
pars
@ -207,4 +204,3 @@ const _extractParameters = (parameters, nestedResources, allResources) => {
allResources
);
}, parameters);
};

View File

@ -40,9 +40,6 @@ export const getPlans = createSelector(plans, plans => plans);
// TODO(jtomasek): update this to list 3 last used plans
export const getAllPlansButCurrent = createSelector(
[plans, getCurrentPlanName],
(plans, currentPlanName) => {
return plans
.filter(plan => plan.name != currentPlanName)
.sortBy(plan => plan.name);
}
(plans, currentPlanName) =>
plans.filter(plan => plan.name != currentPlanName).sortBy(plan => plan.name)
);

View File

@ -41,13 +41,12 @@ export const getCurrentStack = createSelector(
*/
export const getCurrentStackDeploymentInProgress = createSelector(
[stacksSelector, getCurrentPlanName],
(stacks, currentPlanName) => {
return [
(stacks, currentPlanName) =>
[
stackStates.CREATE_IN_PROGRESS,
stackStates.UPDATE_IN_PROGRESS,
stackStates.DELETE_IN_PROGRESS
].includes(stacks.get(currentPlanName, new Stack()).stack_status);
}
].includes(stacks.get(currentPlanName, new Stack()).stack_status)
);
/**
@ -58,9 +57,9 @@ export const getCurrentStackDeploymentProgress = createSelector(
resources => {
let allResources = resources.size;
if (allResources > 0) {
let completeResources = resources.filter(r => {
return r.resource_status === 'CREATE_COMPLETE';
}).size;
let completeResources = resources.filter(
r => r.resource_status === 'CREATE_COMPLETE'
).size;
return Math.ceil(completeResources / allResources * 100);
}
return 0;

View File

@ -49,14 +49,13 @@ export const getValidationExecutionsForCurrentPlan = createSelector(
*/
export const getValidationsWithResults = createSelector(
[validations, getValidationExecutionsForCurrentPlan],
(validations, results) => {
return validations.map(validation => {
(validations, results) =>
validations.map(validation => {
const validationResults = getValidationResults(validation.id, results);
return validation
.set('results', validationResults)
.set('status', getValidationStatus(validationResults));
});
}
})
);
/**
@ -114,29 +113,25 @@ export const getValidationStatusCounts = createSelector(
* Helper function to get the most recent time a plan has been updated or
* created.
*/
export const getMostRecentPlanUpdate = (executions, planName) => {
return (
executions
.filter(
execution =>
[MistralConstants.PLAN_UPDATE, MistralConstants.PLAN_CREATE].includes(
execution.workflow_name
) && execution.getIn(['input', 'container']) === planName
)
.map(execution => execution.get('updated_at'))
.sort()
.last() || 0
);
};
export const getMostRecentPlanUpdate = (executions, planName) =>
executions
.filter(
execution =>
[MistralConstants.PLAN_UPDATE, MistralConstants.PLAN_CREATE].includes(
execution.workflow_name
) && execution.getIn(['input', 'container']) === planName
)
.map(execution => execution.get('updated_at'))
.sort()
.last() || 0;
/**
* Helper function to get a validation results by validation name
*/
const getValidationResults = (validationId, results) => {
return results.filter(
const getValidationResults = (validationId, results) =>
results.filter(
result => result.getIn(['input', 'validation_name']) === validationId
);
};
/**
* Helper function to determine validation status based on validation's results

View File

@ -29,8 +29,8 @@ export const parseNodeCapabilities = capabilities => {
/**
* Convert Node's capabilities object to string
*/
export const stringifyNodeCapabilities = capabilities => {
return Object.keys(capabilities)
export const stringifyNodeCapabilities = capabilities =>
Object.keys(capabilities)
.reduce((caps, key) => {
if (!capabilities[key]) {
return caps;
@ -40,7 +40,6 @@ export const stringifyNodeCapabilities = capabilities => {
}
}, [])
.join(',');
};
/**
* Set or update Node capability