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:
parent
bc9804b753
commit
16514bf462
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"rules": {
|
||||
"arrow-body-style": [2, "as-needed"],
|
||||
"default-case": 0,
|
||||
"linebreak-style": [2, "unix"],
|
||||
"no-cond-assign": [2, "except-parens"],
|
||||
|
|
|
@ -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' })
|
||||
]);
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
|
|
@ -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])
|
||||
]);
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
|
|
@ -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', () => {
|
|||
}
|
||||
})
|
||||
]);
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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)
|
||||
]);
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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)', () => {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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([
|
||||
|
|
|
@ -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()
|
||||
]);
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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' }
|
||||
]
|
||||
});
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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 =>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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>
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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>
|
||||
|
||||
</small>
|
||||
);
|
||||
});
|
||||
return this.props.groups.map(group => (
|
||||
<small key={group}>
|
||||
<span className="label label-default">{group}</span>
|
||||
|
||||
</small>
|
||||
));
|
||||
}
|
||||
|
||||
renderValidationOutput() {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue