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": {
|
"rules": {
|
||||||
|
"arrow-body-style": [2, "as-needed"],
|
||||||
"default-case": 0,
|
"default-case": 0,
|
||||||
"linebreak-style": [2, "unix"],
|
"linebreak-style": [2, "unix"],
|
||||||
"no-cond-assign": [2, "except-parens"],
|
"no-cond-assign": [2, "except-parens"],
|
||||||
|
|
|
@ -121,8 +121,8 @@ describe('updateEnvironmentConfiguration', () => {
|
||||||
NotificationActions.notify = jest.fn(() => ({ type: 'NOTIFY' }));
|
NotificationActions.notify = jest.fn(() => ({ type: 'NOTIFY' }));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches actions', () => {
|
it('dispatches actions', () =>
|
||||||
return store
|
store
|
||||||
.dispatch(
|
.dispatch(
|
||||||
EnvironmentConfigurationActions.updateEnvironmentConfiguration('myPlan')
|
EnvironmentConfigurationActions.updateEnvironmentConfiguration('myPlan')
|
||||||
)
|
)
|
||||||
|
@ -140,6 +140,5 @@ describe('updateEnvironmentConfiguration', () => {
|
||||||
stopSubmit('environmentConfigurationForm'),
|
stopSubmit('environmentConfigurationForm'),
|
||||||
NotificationActions.notify({ type: 'NOTIFY' })
|
NotificationActions.notify({ type: 'NOTIFY' })
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -177,18 +177,15 @@ describe('Fetching Introspection data success', () => {
|
||||||
.mockReturnValue(() => Promise.resolve(response));
|
.mockReturnValue(() => Promise.resolve(response));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches fetchNodeIntrospectionDataSuccess', () => {
|
it('dispatches fetchNodeIntrospectionDataSuccess', () =>
|
||||||
return store
|
store.dispatch(NodesActions.fetchNodeIntrospectionData(nodeId)).then(() => {
|
||||||
.dispatch(NodesActions.fetchNodeIntrospectionData(nodeId))
|
expect(
|
||||||
.then(() => {
|
IronicInspectorApiService.getIntrospectionData
|
||||||
expect(
|
).toHaveBeenCalledWith(nodeId);
|
||||||
IronicInspectorApiService.getIntrospectionData
|
expect(store.getActions()).toEqual([
|
||||||
).toHaveBeenCalledWith(nodeId);
|
NodesActions.fetchNodeIntrospectionDataSuccess(nodeId, response)
|
||||||
expect(store.getActions()).toEqual([
|
]);
|
||||||
NodesActions.fetchNodeIntrospectionDataSuccess(nodeId, response)
|
}));
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Fetching Introspection data error', () => {
|
describe('Fetching Introspection data error', () => {
|
||||||
|
@ -208,18 +205,15 @@ describe('Fetching Introspection data error', () => {
|
||||||
ErrorActions.handleErrors = jest.fn().mockReturnValue(() => {});
|
ErrorActions.handleErrors = jest.fn().mockReturnValue(() => {});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches fetchNodeIntrospectionDataFailed', () => {
|
it('dispatches fetchNodeIntrospectionDataFailed', () =>
|
||||||
return store
|
store.dispatch(NodesActions.fetchNodeIntrospectionData(nodeId)).then(() => {
|
||||||
.dispatch(NodesActions.fetchNodeIntrospectionData(nodeId))
|
expect(
|
||||||
.then(() => {
|
IronicInspectorApiService.getIntrospectionData
|
||||||
expect(
|
).toHaveBeenCalledWith(nodeId);
|
||||||
IronicInspectorApiService.getIntrospectionData
|
expect(store.getActions()).toEqual([
|
||||||
).toHaveBeenCalledWith(nodeId);
|
NodesActions.fetchNodeIntrospectionDataFailed(nodeId)
|
||||||
expect(store.getActions()).toEqual([
|
]);
|
||||||
NodesActions.fetchNodeIntrospectionDataFailed(nodeId)
|
}));
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Asynchronous Introspect Nodes Action', () => {
|
describe('Asynchronous Introspect Nodes Action', () => {
|
||||||
|
@ -235,22 +229,19 @@ describe('Asynchronous Introspect Nodes Action', () => {
|
||||||
.mockReturnValue(() => {});
|
.mockReturnValue(() => {});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches startOperation', () => {
|
it('dispatches startOperation', () =>
|
||||||
return store
|
store.dispatch(NodesActions.startNodesIntrospection(nodeIds)).then(() => {
|
||||||
.dispatch(NodesActions.startNodesIntrospection(nodeIds))
|
expect(MistralApiService.runWorkflow).toHaveBeenCalledWith(
|
||||||
.then(() => {
|
MistralConstants.BAREMETAL_INTROSPECT,
|
||||||
expect(MistralApiService.runWorkflow).toHaveBeenCalledWith(
|
{
|
||||||
MistralConstants.BAREMETAL_INTROSPECT,
|
node_uuids: nodeIds
|
||||||
{
|
}
|
||||||
node_uuids: nodeIds
|
);
|
||||||
}
|
expect(NodesActions.pollNodeslistDuringProgress).toHaveBeenCalled();
|
||||||
);
|
expect(store.getActions()).toEqual([
|
||||||
expect(NodesActions.pollNodeslistDuringProgress).toHaveBeenCalled();
|
NodesActions.startOperation(nodeIds)
|
||||||
expect(store.getActions()).toEqual([
|
]);
|
||||||
NodesActions.startOperation(nodeIds)
|
}));
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('nodesIntrospectionFinished', () => {
|
describe('nodesIntrospectionFinished', () => {
|
||||||
|
@ -327,8 +318,8 @@ describe('startProvideNodes Action', () => {
|
||||||
.mockReturnValue(() => {});
|
.mockReturnValue(() => {});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches actions', () => {
|
it('dispatches actions', () =>
|
||||||
return store.dispatch(NodesActions.startProvideNodes(nodeIds)).then(() => {
|
store.dispatch(NodesActions.startProvideNodes(nodeIds)).then(() => {
|
||||||
expect(MistralApiService.runWorkflow).toHaveBeenCalledWith(
|
expect(MistralApiService.runWorkflow).toHaveBeenCalledWith(
|
||||||
MistralConstants.BAREMETAL_PROVIDE,
|
MistralConstants.BAREMETAL_PROVIDE,
|
||||||
{
|
{
|
||||||
|
@ -339,8 +330,7 @@ describe('startProvideNodes Action', () => {
|
||||||
expect(store.getActions()).toEqual([
|
expect(store.getActions()).toEqual([
|
||||||
NodesActions.startOperation(nodeIds)
|
NodesActions.startOperation(nodeIds)
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('provideNodesFinished', () => {
|
describe('provideNodesFinished', () => {
|
||||||
|
@ -402,14 +392,13 @@ describe('Update Node thunk action', () => {
|
||||||
.mockReturnValue(() => Promise.resolve({ uuid: 'someId' }));
|
.mockReturnValue(() => Promise.resolve({ uuid: 'someId' }));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches required actions', () => {
|
it('dispatches required actions', () =>
|
||||||
return store.dispatch(NodesActions.updateNode(nodePatch)).then(() => {
|
store.dispatch(NodesActions.updateNode(nodePatch)).then(() => {
|
||||||
expect(store.getActions()).toEqual([
|
expect(store.getActions()).toEqual([
|
||||||
NodesActions.updateNodePending('someId'),
|
NodesActions.updateNodePending('someId'),
|
||||||
NodesActions.updateNodeSuccess({ uuid: 'someId' })
|
NodesActions.updateNodeSuccess({ uuid: 'someId' })
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Delete Nodes thunk action', () => {
|
describe('Delete Nodes thunk action', () => {
|
||||||
|
@ -422,12 +411,11 @@ describe('Delete Nodes thunk action', () => {
|
||||||
.mockReturnValue(() => Promise.resolve());
|
.mockReturnValue(() => Promise.resolve());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('successfully deletes a set of nodes', () => {
|
it('successfully deletes a set of nodes', () =>
|
||||||
return store.dispatch(NodesActions.deleteNodes(nodeIds)).then(() => {
|
store.dispatch(NodesActions.deleteNodes(nodeIds)).then(() => {
|
||||||
expect(store.getActions()).toEqual([
|
expect(store.getActions()).toEqual([
|
||||||
NodesActions.startOperation(nodeIds),
|
NodesActions.startOperation(nodeIds),
|
||||||
NodesActions.deleteNodeSuccess(nodeIds[0])
|
NodesActions.deleteNodeSuccess(nodeIds[0])
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -77,8 +77,8 @@ describe('ParametersActions', () => {
|
||||||
.mockReturnValue(() => Promise.resolve(responseBody));
|
.mockReturnValue(() => Promise.resolve(responseBody));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches actions', () => {
|
it('dispatches actions', () =>
|
||||||
return store
|
store
|
||||||
.dispatch(ParametersActions.fetchParameters('overcloud'))
|
.dispatch(ParametersActions.fetchParameters('overcloud'))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
expect(MistralApiService.runAction).toHaveBeenCalled();
|
expect(MistralApiService.runAction).toHaveBeenCalled();
|
||||||
|
@ -86,8 +86,7 @@ describe('ParametersActions', () => {
|
||||||
ParametersActions.fetchParametersPending(),
|
ParametersActions.fetchParametersPending(),
|
||||||
ParametersActions.fetchParametersSuccess(normalizedResponse)
|
ParametersActions.fetchParametersSuccess(normalizedResponse)
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('updateParameters (fail)', () => {
|
describe('updateParameters (fail)', () => {
|
||||||
|
@ -101,8 +100,8 @@ describe('ParametersActions', () => {
|
||||||
ErrorActions.handleErrors = jest.fn().mockReturnValue(() => {});
|
ErrorActions.handleErrors = jest.fn().mockReturnValue(() => {});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls required actions', () => {
|
it('calls required actions', () =>
|
||||||
return store
|
store
|
||||||
.dispatch(
|
.dispatch(
|
||||||
ParametersActions.updateParameters('overcloud', { foo: 'bar' })
|
ParametersActions.updateParameters('overcloud', { foo: 'bar' })
|
||||||
)
|
)
|
||||||
|
@ -123,7 +122,6 @@ describe('ParametersActions', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -36,8 +36,8 @@ describe('PlansActions', () => {
|
||||||
.mockReturnValue(() => Promise.resolve());
|
.mockReturnValue(() => Promise.resolve());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches actions', () => {
|
it('dispatches actions', () =>
|
||||||
return store
|
store
|
||||||
.dispatch(
|
.dispatch(
|
||||||
PlansActions.updatePlan('somecloud', {
|
PlansActions.updatePlan('somecloud', {
|
||||||
someFile: { contents: 'file contents' }
|
someFile: { contents: 'file contents' }
|
||||||
|
@ -48,8 +48,7 @@ describe('PlansActions', () => {
|
||||||
expect(store.getActions()).toEqual([
|
expect(store.getActions()).toEqual([
|
||||||
PlansActions.updatePlanPending('somecloud')
|
PlansActions.updatePlanPending('somecloud')
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('createPlan', () => {
|
describe('createPlan', () => {
|
||||||
|
@ -67,15 +66,10 @@ describe('PlansActions', () => {
|
||||||
.mockReturnValue(() => Promise.resolve());
|
.mockReturnValue(() => Promise.resolve());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches actions', () => {
|
it('dispatches actions', () =>
|
||||||
return store
|
store.dispatch(PlansActions.createPlan('somecloud', {})).then(() => {
|
||||||
.dispatch(PlansActions.createPlan('somecloud', {}))
|
expect(store.getActions()).toEqual([PlansActions.createPlanPending()]);
|
||||||
.then(() => {
|
}));
|
||||||
expect(store.getActions()).toEqual([
|
|
||||||
PlansActions.createPlanPending()
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('deletePlans', () => {
|
describe('deletePlans', () => {
|
||||||
|
@ -87,8 +81,8 @@ describe('PlansActions', () => {
|
||||||
.mockReturnValue(() => Promise.resolve());
|
.mockReturnValue(() => Promise.resolve());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches actions', () => {
|
it('dispatches actions', () =>
|
||||||
return store
|
store
|
||||||
.dispatch(PlansActions.deletePlan('somecloud', mockHistory))
|
.dispatch(PlansActions.deletePlan('somecloud', mockHistory))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
expect(store.getActions().map(action => action.type)).toEqual([
|
expect(store.getActions().map(action => action.type)).toEqual([
|
||||||
|
@ -96,8 +90,7 @@ describe('PlansActions', () => {
|
||||||
'DELETE_PLAN_SUCCESS',
|
'DELETE_PLAN_SUCCESS',
|
||||||
'NOTIFY'
|
'NOTIFY'
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('fetchPlans', () => {
|
describe('fetchPlans', () => {
|
||||||
|
@ -124,15 +117,14 @@ describe('PlansActions', () => {
|
||||||
.mockReturnValue(() => Promise.resolve(apiResponseMistral));
|
.mockReturnValue(() => Promise.resolve(apiResponseMistral));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches actions', () => {
|
it('dispatches actions', () =>
|
||||||
return store.dispatch(PlansActions.fetchPlans()).then(() => {
|
store.dispatch(PlansActions.fetchPlans()).then(() => {
|
||||||
expect(MistralApiService.runAction).toHaveBeenCalled();
|
expect(MistralApiService.runAction).toHaveBeenCalled();
|
||||||
expect(store.getActions()).toEqual([
|
expect(store.getActions()).toEqual([
|
||||||
PlansActions.requestPlans(),
|
PlansActions.requestPlans(),
|
||||||
PlansActions.receivePlans(expectedPlans)
|
PlansActions.receivePlans(expectedPlans)
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('fetchPlan', () => {
|
describe('fetchPlan', () => {
|
||||||
|
@ -152,14 +144,13 @@ describe('PlansActions', () => {
|
||||||
.mockReturnValue(() => Promise.resolve(apiResponse));
|
.mockReturnValue(() => Promise.resolve(apiResponse));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches actions', () => {
|
it('dispatches actions', () =>
|
||||||
return store.dispatch(PlansActions.fetchPlan('overcloud')).then(() => {
|
store.dispatch(PlansActions.fetchPlan('overcloud')).then(() => {
|
||||||
expect(SwiftApiService.getContainer).toHaveBeenCalled();
|
expect(SwiftApiService.getContainer).toHaveBeenCalled();
|
||||||
expect(store.getActions()).toEqual([
|
expect(store.getActions()).toEqual([
|
||||||
PlansActions.requestPlan(),
|
PlansActions.requestPlan(),
|
||||||
PlansActions.receivePlan('overcloud', normalizedResponse)
|
PlansActions.receivePlan('overcloud', normalizedResponse)
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -35,15 +35,14 @@ describe('StacksActions', () => {
|
||||||
.mockReturnValue(() => Promise.resolve(serviceResponse));
|
.mockReturnValue(() => Promise.resolve(serviceResponse));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches actions', () => {
|
it('dispatches actions', () =>
|
||||||
return store.dispatch(StacksActions.fetchStacks()).then(() => {
|
store.dispatch(StacksActions.fetchStacks()).then(() => {
|
||||||
expect(HeatApiService.getStacks).toHaveBeenCalled();
|
expect(HeatApiService.getStacks).toHaveBeenCalled();
|
||||||
expect(store.getActions()).toEqual([
|
expect(store.getActions()).toEqual([
|
||||||
StacksActions.fetchStacksPending(),
|
StacksActions.fetchStacksPending(),
|
||||||
StacksActions.fetchStacksSuccess(normalizedStacks)
|
StacksActions.fetchStacksSuccess(normalizedStacks)
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('fetchStacks (failed)', () => {
|
describe('fetchStacks (failed)', () => {
|
||||||
|
@ -56,15 +55,14 @@ describe('StacksActions', () => {
|
||||||
ErrorActions.handleErrors = jest.fn().mockReturnValue(() => {});
|
ErrorActions.handleErrors = jest.fn().mockReturnValue(() => {});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches actions', () => {
|
it('dispatches actions', () =>
|
||||||
return store.dispatch(StacksActions.fetchStacks()).then(() => {
|
store.dispatch(StacksActions.fetchStacks()).then(() => {
|
||||||
expect(HeatApiService.getStacks).toHaveBeenCalled();
|
expect(HeatApiService.getStacks).toHaveBeenCalled();
|
||||||
expect(store.getActions()).toEqual([
|
expect(store.getActions()).toEqual([
|
||||||
StacksActions.fetchStacksPending(),
|
StacksActions.fetchStacksPending(),
|
||||||
StacksActions.fetchStacksFailed()
|
StacksActions.fetchStacksFailed()
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// describe('fetchStacks (failed)', () => {
|
// describe('fetchStacks (failed)', () => {
|
||||||
|
|
|
@ -81,8 +81,8 @@ describe('FetchValidations action', () => {
|
||||||
.mockReturnValue(() => Promise.resolve(response));
|
.mockReturnValue(() => Promise.resolve(response));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches appropriate actions and normalizes the response', () => {
|
it('dispatches appropriate actions and normalizes the response', () =>
|
||||||
return store.dispatch(ValidationsActions.fetchValidations()).then(() => {
|
store.dispatch(ValidationsActions.fetchValidations()).then(() => {
|
||||||
expect(MistralApiService.runAction).toHaveBeenCalledWith(
|
expect(MistralApiService.runAction).toHaveBeenCalledWith(
|
||||||
MistralConstants.VALIDATIONS_LIST
|
MistralConstants.VALIDATIONS_LIST
|
||||||
);
|
);
|
||||||
|
@ -90,8 +90,7 @@ describe('FetchValidations action', () => {
|
||||||
ValidationsActions.fetchValidationsPending(),
|
ValidationsActions.fetchValidationsPending(),
|
||||||
ValidationsActions.fetchValidationsSuccess(normalizedResponse)
|
ValidationsActions.fetchValidationsSuccess(normalizedResponse)
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('RunValidation action', () => {
|
describe('RunValidation action', () => {
|
||||||
|
@ -118,8 +117,8 @@ describe('RunValidation action', () => {
|
||||||
.mockReturnValue(() => Promise.resolve(addWorkflowExecutionResponse));
|
.mockReturnValue(() => Promise.resolve(addWorkflowExecutionResponse));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches appropriate actions', () => {
|
it('dispatches appropriate actions', () =>
|
||||||
return store
|
store
|
||||||
.dispatch(ValidationsActions.runValidation('512e', 'overcloud'))
|
.dispatch(ValidationsActions.runValidation('512e', 'overcloud'))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
expect(MistralApiService.runWorkflow).toHaveBeenCalledWith(
|
expect(MistralApiService.runWorkflow).toHaveBeenCalledWith(
|
||||||
|
@ -134,8 +133,7 @@ describe('RunValidation action', () => {
|
||||||
addWorkflowExecutionResponse
|
addWorkflowExecutionResponse
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO(jtomasek): this test compares 2 immutable records and even though they're the same
|
// 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';
|
import thunkMiddleware from 'redux-thunk';
|
||||||
|
|
||||||
export const mockGetIntl = {
|
export const mockGetIntl = {
|
||||||
getIntl: () => {
|
getIntl: () => ({
|
||||||
return {
|
formatMessage: msgObj => msgObj.defaultMessage
|
||||||
formatMessage: msgObj => msgObj.defaultMessage
|
})
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mockStore = configureMockStore([
|
export const mockStore = configureMockStore([
|
||||||
|
|
|
@ -45,8 +45,8 @@ describe('fetchWorkflowExecutions action', () => {
|
||||||
.mockReturnValue(() => Promise.resolve(response));
|
.mockReturnValue(() => Promise.resolve(response));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches appropriate actions and normalizes the response', () => {
|
it('dispatches appropriate actions and normalizes the response', () =>
|
||||||
return store
|
store
|
||||||
.dispatch(WorkflowExecutionsActions.fetchWorkflowExecutions())
|
.dispatch(WorkflowExecutionsActions.fetchWorkflowExecutions())
|
||||||
.then(() => {
|
.then(() => {
|
||||||
expect(MistralApiService.getWorkflowExecutions).toHaveBeenCalled();
|
expect(MistralApiService.getWorkflowExecutions).toHaveBeenCalled();
|
||||||
|
@ -56,8 +56,7 @@ describe('fetchWorkflowExecutions action', () => {
|
||||||
normalizedResponse
|
normalizedResponse
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('updateWorkflowExecution action', () => {
|
describe('updateWorkflowExecution action', () => {
|
||||||
|
@ -69,8 +68,8 @@ describe('updateWorkflowExecution action', () => {
|
||||||
.mockReturnValue(() => Promise.resolve());
|
.mockReturnValue(() => Promise.resolve());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches appropriate actions', () => {
|
it('dispatches appropriate actions', () =>
|
||||||
return store
|
store
|
||||||
.dispatch(
|
.dispatch(
|
||||||
WorkflowExecutionsActions.updateWorkflowExecution('512e', {
|
WorkflowExecutionsActions.updateWorkflowExecution('512e', {
|
||||||
state: 'PAUSED'
|
state: 'PAUSED'
|
||||||
|
@ -87,6 +86,5 @@ describe('updateWorkflowExecution action', () => {
|
||||||
}),
|
}),
|
||||||
WorkflowExecutionsActions.addWorkflowExecution()
|
WorkflowExecutionsActions.addWorkflowExecution()
|
||||||
]);
|
]);
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -34,9 +34,7 @@ const mockNoRowsRenderer = function() {
|
||||||
return 'There are no items in data';
|
return 'There are no items in data';
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockOnFilter = () => {
|
const mockOnFilter = () => 'Filtering Happened';
|
||||||
return 'Filtering Happened';
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('DataTable component', () => {
|
describe('DataTable component', () => {
|
||||||
let DataTableVdom, DataTableInstance;
|
let DataTableVdom, DataTableInstance;
|
||||||
|
|
|
@ -35,8 +35,8 @@ describe('HeatApiService', () => {
|
||||||
.mockReturnValue(() => Promise.resolve(apiResponse));
|
.mockReturnValue(() => Promise.resolve(apiResponse));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns a stack object based on <planName>', () => {
|
it('returns a stack object based on <planName>', () =>
|
||||||
return store.dispatch(HeatApiService.getStacks()).then(result => {
|
store.dispatch(HeatApiService.getStacks()).then(result => {
|
||||||
expect(HeatApiService.defaultRequest).toHaveBeenCalled();
|
expect(HeatApiService.defaultRequest).toHaveBeenCalled();
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
stacks: [
|
stacks: [
|
||||||
|
@ -44,7 +44,6 @@ describe('HeatApiService', () => {
|
||||||
{ stack_name: 'anothercloud', stack_status: 'CREATE_FAILED' }
|
{ stack_name: 'anothercloud', stack_status: 'CREATE_FAILED' }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -87,13 +87,11 @@ UserAuthenticator.propTypes = {
|
||||||
location: PropTypes.object.isRequired
|
location: PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => ({
|
||||||
return {
|
isAuthenticated: state.login.isAuthenticated,
|
||||||
isAuthenticated: state.login.isAuthenticated,
|
isAuthenticating: state.login.isAuthenticating,
|
||||||
isAuthenticating: state.login.isAuthenticating,
|
keystoneAuthTokenId: state.login.tokenId
|
||||||
keystoneAuthTokenId: state.login.tokenId
|
});
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
authenticateUserViaToken: tokenId =>
|
authenticateUserViaToken: tokenId =>
|
||||||
|
|
|
@ -134,23 +134,21 @@ ValidationsWarning.propTypes = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DeployButton = injectIntl(
|
export const DeployButton = injectIntl(
|
||||||
({ deploy, disabled, intl, isRequestingPlanDeploy }) => {
|
({ deploy, disabled, intl, isRequestingPlanDeploy }) => (
|
||||||
return (
|
<button
|
||||||
<button
|
type="button"
|
||||||
type="button"
|
disabled={disabled}
|
||||||
disabled={disabled}
|
className="btn btn-lg btn-primary"
|
||||||
className="btn btn-lg btn-primary"
|
onClick={() => deploy()}
|
||||||
onClick={() => deploy()}
|
>
|
||||||
|
<InlineLoader
|
||||||
|
loaded={!isRequestingPlanDeploy}
|
||||||
|
content={intl.formatMessage(messages.requestingDeploymentLoader)}
|
||||||
>
|
>
|
||||||
<InlineLoader
|
<FormattedMessage {...messages.deployButton} />
|
||||||
loaded={!isRequestingPlanDeploy}
|
</InlineLoader>
|
||||||
content={intl.formatMessage(messages.requestingDeploymentLoader)}
|
</button>
|
||||||
>
|
)
|
||||||
<FormattedMessage {...messages.deployButton} />
|
|
||||||
</InlineLoader>
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
DeployButton.propTypes = {
|
DeployButton.propTypes = {
|
||||||
deploy: PropTypes.func.isRequired,
|
deploy: PropTypes.func.isRequired,
|
||||||
|
|
|
@ -173,34 +173,30 @@ DeploymentDetail.propTypes = {
|
||||||
stacksLoaded: PropTypes.bool.isRequired
|
stacksLoaded: PropTypes.bool.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => ({
|
||||||
return {
|
allPreDeploymentValidationsSuccessful: allPreDeploymentValidationsSuccessful(
|
||||||
allPreDeploymentValidationsSuccessful: allPreDeploymentValidationsSuccessful(
|
state
|
||||||
state
|
),
|
||||||
),
|
currentPlan: getCurrentPlan(state),
|
||||||
currentPlan: getCurrentPlan(state),
|
currentPlanName: getCurrentPlanName(state),
|
||||||
currentPlanName: getCurrentPlanName(state),
|
currentStack: getCurrentStack(state),
|
||||||
currentStack: getCurrentStack(state),
|
currentStackDeploymentProgress: getCurrentStackDeploymentProgress(state),
|
||||||
currentStackDeploymentProgress: getCurrentStackDeploymentProgress(state),
|
currentStackResources: state.stacks.resources,
|
||||||
currentStackResources: state.stacks.resources,
|
currentStackResourcesLoaded: state.stacks.resourcesLoaded,
|
||||||
currentStackResourcesLoaded: state.stacks.resourcesLoaded,
|
environmentConfigurationSummary: getEnvironmentConfigurationSummary(state),
|
||||||
environmentConfigurationSummary: getEnvironmentConfigurationSummary(state),
|
overcloudInfo: getOvercloudInfo(state),
|
||||||
overcloudInfo: getOvercloudInfo(state),
|
stacksLoaded: state.stacks.isLoaded
|
||||||
stacksLoaded: state.stacks.isLoaded
|
});
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = dispatch => ({
|
||||||
return {
|
deployPlan: planName => dispatch(PlanActions.deployPlan(planName)),
|
||||||
deployPlan: planName => dispatch(PlanActions.deployPlan(planName)),
|
fetchStackResources: stack =>
|
||||||
fetchStackResources: stack =>
|
dispatch(StacksActions.fetchResources(stack.stack_name, stack.id)),
|
||||||
dispatch(StacksActions.fetchResources(stack.stack_name, stack.id)),
|
runPreDeploymentValidations: planName =>
|
||||||
runPreDeploymentValidations: planName =>
|
dispatch(
|
||||||
dispatch(
|
ValidationsActions.runValidationGroups(['pre-deployment'], planName)
|
||||||
ValidationsActions.runValidationGroups(['pre-deployment'], planName)
|
)
|
||||||
)
|
});
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default injectIntl(
|
export default injectIntl(
|
||||||
connect(mapStateToProps, mapDispatchToProps)(DeploymentDetail)
|
connect(mapStateToProps, mapDispatchToProps)(DeploymentDetail)
|
||||||
|
|
|
@ -87,11 +87,9 @@ class StackResourcesTable extends React.Component {
|
||||||
let dataKeys = ['resource_name', 'resource_status'];
|
let dataKeys = ['resource_name', 'resource_status'];
|
||||||
return filterString
|
return filterString
|
||||||
? data.filter(row => {
|
? data.filter(row => {
|
||||||
let result = dataKeys.filter(dataKey => {
|
let result = dataKeys.filter(dataKey =>
|
||||||
return row[dataKey]
|
row[dataKey].toLowerCase().includes(filterString.toLowerCase())
|
||||||
.toLowerCase()
|
);
|
||||||
.includes(filterString.toLowerCase());
|
|
||||||
});
|
|
||||||
return result.length > 0;
|
return result.length > 0;
|
||||||
})
|
})
|
||||||
: data;
|
: data;
|
||||||
|
|
|
@ -28,21 +28,19 @@ const messages = defineMessages({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const ConfigurePlanStep = props => {
|
const ConfigurePlanStep = props => (
|
||||||
return (
|
<div>
|
||||||
<div>
|
<DeploymentConfigurationSummary {...props} />
|
||||||
<DeploymentConfigurationSummary {...props} />
|
<br />
|
||||||
<br />
|
<Link
|
||||||
<Link
|
className="btn btn-default"
|
||||||
className="btn btn-default"
|
id="ConfigurePlanStep__EditDeploymentLink"
|
||||||
id="ConfigurePlanStep__EditDeploymentLink"
|
to={`/plans/${props.planName}/configuration`}
|
||||||
to={`/plans/${props.planName}/configuration`}
|
>
|
||||||
>
|
<FormattedMessage {...messages.editConfigurationLink} />
|
||||||
<FormattedMessage {...messages.editConfigurationLink} />
|
</Link>
|
||||||
</Link>
|
</div>
|
||||||
</div>
|
);
|
||||||
);
|
|
||||||
};
|
|
||||||
ConfigurePlanStep.propTypes = {
|
ConfigurePlanStep.propTypes = {
|
||||||
fetchEnvironmentConfiguration: PropTypes.func.isRequired,
|
fetchEnvironmentConfiguration: PropTypes.func.isRequired,
|
||||||
isFetching: PropTypes.bool.isRequired,
|
isFetching: PropTypes.bool.isRequired,
|
||||||
|
|
|
@ -17,21 +17,19 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
export const DeploymentPlanStep = ({ children, disabled, title, tooltip }) => {
|
export const DeploymentPlanStep = ({ children, disabled, title, tooltip }) => (
|
||||||
return (
|
<li className={disabled ? 'disabled' : null}>
|
||||||
<li className={disabled ? 'disabled' : null}>
|
<h3>
|
||||||
<h3>
|
<span>{title}</span>
|
||||||
<span>{title}</span>
|
{tooltip ? (
|
||||||
{tooltip ? (
|
<span data-tooltip={tooltip} className="tooltip-right">
|
||||||
<span data-tooltip={tooltip} className="tooltip-right">
|
<span className="pficon pficon-info" />
|
||||||
<span className="pficon pficon-info" />
|
</span>
|
||||||
</span>
|
) : null}
|
||||||
) : null}
|
</h3>
|
||||||
</h3>
|
{children}
|
||||||
{children}
|
</li>
|
||||||
</li>
|
);
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
DeploymentPlanStep.propTypes = {
|
DeploymentPlanStep.propTypes = {
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
|
|
|
@ -25,12 +25,10 @@ const messages = defineMessages({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const HardwareStep = () => {
|
const HardwareStep = () => (
|
||||||
return (
|
<Link className="btn btn-default" to="/nodes/register">
|
||||||
<Link className="btn btn-default" to="/nodes/register">
|
<FormattedMessage {...messages.registerNodes} />
|
||||||
<FormattedMessage {...messages.registerNodes} />
|
</Link>
|
||||||
</Link>
|
);
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default HardwareStep;
|
export default HardwareStep;
|
||||||
|
|
|
@ -40,22 +40,20 @@ const EnvironmentCheckBox = ({
|
||||||
meta,
|
meta,
|
||||||
required,
|
required,
|
||||||
...rest
|
...rest
|
||||||
}) => {
|
}) => (
|
||||||
return (
|
<FormGroup
|
||||||
<FormGroup
|
controlId={id}
|
||||||
controlId={id}
|
validationState={getValidationState({ ...meta, touched: true })}
|
||||||
validationState={getValidationState({ ...meta, touched: true })}
|
>
|
||||||
>
|
<Col smOffset={labelColumns} sm={inputColumns}>
|
||||||
<Col smOffset={labelColumns} sm={inputColumns}>
|
<Checkbox {...input} {...rest}>
|
||||||
<Checkbox {...input} {...rest}>
|
<span className={cx({ 'required-pf': required })}>{label}</span>
|
||||||
<span className={cx({ 'required-pf': required })}>{label}</span>
|
</Checkbox>
|
||||||
</Checkbox>
|
<InputMessage {...meta} touched />
|
||||||
<InputMessage {...meta} touched />
|
<InputDescription description={description} />
|
||||||
<InputDescription description={description} />
|
</Col>
|
||||||
</Col>
|
</FormGroup>
|
||||||
</FormGroup>
|
);
|
||||||
);
|
|
||||||
};
|
|
||||||
EnvironmentCheckBox.propTypes = {
|
EnvironmentCheckBox.propTypes = {
|
||||||
description: PropTypes.node,
|
description: PropTypes.node,
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
|
|
|
@ -71,18 +71,14 @@ I18nDropdown.propTypes = {
|
||||||
languages: ImmutablePropTypes.map.isRequired
|
languages: ImmutablePropTypes.map.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => ({
|
||||||
return {
|
languages: getEnabledLanguages(state),
|
||||||
languages: getEnabledLanguages(state),
|
currentLanguage: getCurrentLanguage(state)
|
||||||
currentLanguage: getCurrentLanguage(state)
|
});
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = dispatch => ({
|
||||||
return {
|
chooseLanguage: language => dispatch(I18nActions.chooseLanguage(language))
|
||||||
chooseLanguage: language => dispatch(I18nActions.chooseLanguage(language))
|
});
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default injectIntl(
|
export default injectIntl(
|
||||||
connect(mapStateToProps, mapDispatchToProps)(I18nDropdown)
|
connect(mapStateToProps, mapDispatchToProps)(I18nDropdown)
|
||||||
|
|
|
@ -58,17 +58,13 @@ I18nProvider.defaultProps = {
|
||||||
messages: {}
|
messages: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = dispatch => ({
|
||||||
return {
|
detectLanguage: language => dispatch(I18nActions.detectLanguage(language))
|
||||||
detectLanguage: language => dispatch(I18nActions.detectLanguage(language))
|
});
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => ({
|
||||||
return {
|
language: getCurrentLanguage(state),
|
||||||
language: getCurrentLanguage(state),
|
messages: getCurrentLanguageMessages(state)
|
||||||
messages: getCurrentLanguageMessages(state)
|
});
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(I18nProvider);
|
export default connect(mapStateToProps, mapDispatchToProps)(I18nProvider);
|
||||||
|
|
|
@ -22,13 +22,11 @@ import { injectIntl } from 'react-intl';
|
||||||
class LanguageInput extends React.Component {
|
class LanguageInput extends React.Component {
|
||||||
_renderOptions() {
|
_renderOptions() {
|
||||||
return this.props.languages
|
return this.props.languages
|
||||||
.map((langName, langKey) => {
|
.map((langName, langKey) => (
|
||||||
return (
|
<option key={`lang-${langKey}`} value={langKey}>
|
||||||
<option key={`lang-${langKey}`} value={langKey}>
|
{langName}
|
||||||
{langName}
|
</option>
|
||||||
</option>
|
))
|
||||||
);
|
|
||||||
})
|
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -226,12 +226,10 @@ function mapStateToProps(state) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = dispatch => ({
|
||||||
return {
|
chooseLanguage: language => dispatch(I18nActions.chooseLanguage(language)),
|
||||||
chooseLanguage: language => dispatch(I18nActions.chooseLanguage(language)),
|
authenticateUser: (formData, formFields, nextPath) =>
|
||||||
authenticateUser: (formData, formFields, nextPath) =>
|
dispatch(LoginActions.authenticateUser(formData, formFields, nextPath))
|
||||||
dispatch(LoginActions.authenticateUser(formData, formFields, nextPath))
|
});
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(Login));
|
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(Login));
|
||||||
|
|
|
@ -118,21 +118,19 @@ class NodeExtendedInfo extends React.Component {
|
||||||
<dd>
|
<dd>
|
||||||
{node
|
{node
|
||||||
.getIn(['introspectionData', 'interfaces'])
|
.getIn(['introspectionData', 'interfaces'])
|
||||||
.map((ifc, k) => {
|
.map((ifc, k) => (
|
||||||
return (
|
<div key={k}>
|
||||||
<div key={k}>
|
{k} -{' '}
|
||||||
{k} -{' '}
|
<span title={intl.formatMessage(messages.macAddress)}>
|
||||||
<span title={intl.formatMessage(messages.macAddress)}>
|
{ifc.get('mac')}
|
||||||
{ifc.get('mac')}
|
</span>{' '}
|
||||||
</span>{' '}
|
|{' '}
|
||||||
|{' '}
|
<span title={intl.formatMessage(messages.ipAddress)}>
|
||||||
<span title={intl.formatMessage(messages.ipAddress)}>
|
{ifc.get('ip')}
|
||||||
{ifc.get('ip')}
|
</span>
|
||||||
</span>
|
{ifc.get('pxe') && '| PXE'}
|
||||||
{ifc.get('pxe') && '| PXE'}
|
</div>
|
||||||
</div>
|
))
|
||||||
);
|
|
||||||
})
|
|
||||||
.toList()}
|
.toList()}
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
|
@ -130,11 +130,9 @@ class NodesTable extends React.Component {
|
||||||
let dataKeys = ['name'];
|
let dataKeys = ['name'];
|
||||||
return filterString
|
return filterString
|
||||||
? data.filter(row => {
|
? data.filter(row => {
|
||||||
let result = dataKeys.filter(dataKey => {
|
let result = dataKeys.filter(dataKey =>
|
||||||
return row[dataKey]
|
row[dataKey].toLowerCase().includes(filterString.toLowerCase())
|
||||||
.toLowerCase()
|
);
|
||||||
.includes(filterString.toLowerCase());
|
|
||||||
});
|
|
||||||
return result.length > 0;
|
return result.length > 0;
|
||||||
})
|
})
|
||||||
: data;
|
: data;
|
||||||
|
|
|
@ -183,27 +183,23 @@ NodesToolbar.propTypes = {
|
||||||
submitNodesToolbarForm: PropTypes.func.isRequired,
|
submitNodesToolbarForm: PropTypes.func.isRequired,
|
||||||
updateFilter: PropTypes.func.isRequired
|
updateFilter: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = dispatch => ({
|
||||||
return {
|
clearActiveFilters: () => dispatch(clearActiveFilters('nodesToolbar')),
|
||||||
clearActiveFilters: () => dispatch(clearActiveFilters('nodesToolbar')),
|
deleteActiveFilter: uuid =>
|
||||||
deleteActiveFilter: uuid =>
|
dispatch(deleteActiveFilter('nodesToolbar', uuid)),
|
||||||
dispatch(deleteActiveFilter('nodesToolbar', uuid)),
|
submitNodesToolbarForm: () => dispatch(submit('nodesToolbar')),
|
||||||
submitNodesToolbarForm: () => dispatch(submit('nodesToolbar')),
|
addActiveFilter: data => dispatch(addActiveFilter('nodesToolbar', data)),
|
||||||
addActiveFilter: data => dispatch(addActiveFilter('nodesToolbar', data)),
|
updateFilter: data => dispatch(updateFilter('nodesToolbar', data))
|
||||||
updateFilter: data => dispatch(updateFilter('nodesToolbar', data))
|
});
|
||||||
};
|
const mapStateToProps = state => ({
|
||||||
};
|
activeFilters: getActiveFilters(state, 'nodesToolbar'),
|
||||||
const mapStateToProps = state => {
|
filteredNodesCount: getFilteredNodes(state).size,
|
||||||
return {
|
filteredNodes: getFilteredNodes(state),
|
||||||
activeFilters: getActiveFilters(state, 'nodesToolbar'),
|
nodesToolbarFilter: getFilterByName(state, 'nodesToolbar').delete(
|
||||||
filteredNodesCount: getFilteredNodes(state).size,
|
'activeFilters'
|
||||||
filteredNodes: getFilteredNodes(state),
|
),
|
||||||
nodesToolbarFilter: getFilterByName(state, 'nodesToolbar').delete(
|
nodesCount: getNodes(state).size
|
||||||
'activeFilters'
|
});
|
||||||
),
|
|
||||||
nodesCount: getNodes(state).size
|
|
||||||
};
|
|
||||||
};
|
|
||||||
export default injectIntl(
|
export default injectIntl(
|
||||||
connect(mapStateToProps, mapDispatchToProps)(NodesToolbar)
|
connect(mapStateToProps, mapDispatchToProps)(NodesToolbar)
|
||||||
);
|
);
|
||||||
|
|
|
@ -65,24 +65,22 @@ class NodesFileUpload extends React.Component {
|
||||||
const file = event.target.files[0];
|
const file = event.target.files[0];
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
|
|
||||||
reader.onload = (f => {
|
reader.onload = (f => e => {
|
||||||
return e => {
|
if (file.name.match(/(\.json)$/)) {
|
||||||
if (file.name.match(/(\.json)$/)) {
|
this.addNodesFromInstackenvJSON(e.target.result);
|
||||||
this.addNodesFromInstackenvJSON(e.target.result);
|
} else if (file.name.match(/(\.csv)$/)) {
|
||||||
} else if (file.name.match(/(\.csv)$/)) {
|
// TODO(jtomasek): add CSV file support
|
||||||
// TODO(jtomasek): add CSV file support
|
// this.addNodesFromCSV(e.target.result);
|
||||||
// this.addNodesFromCSV(e.target.result);
|
notify({
|
||||||
notify({
|
title: formatMessage(messages.csvUnsupported),
|
||||||
title: formatMessage(messages.csvUnsupported),
|
message: formatMessage(messages.selectedFileUnsupported)
|
||||||
message: formatMessage(messages.selectedFileUnsupported)
|
});
|
||||||
});
|
} else {
|
||||||
} else {
|
notify({
|
||||||
notify({
|
title: formatMessage(messages.unsupportedFileFormat),
|
||||||
title: formatMessage(messages.unsupportedFileFormat),
|
message: formatMessage(messages.provideCsvOrInstackenvJson)
|
||||||
message: formatMessage(messages.provideCsvOrInstackenvJson)
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
})(file);
|
})(file);
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
this.refs.regNodesUploadFileForm.reset();
|
this.refs.regNodesUploadFileForm.reset();
|
||||||
|
|
|
@ -114,114 +114,112 @@ const RegisterNodeFields = ({
|
||||||
node,
|
node,
|
||||||
intl: { formatMessage },
|
intl: { formatMessage },
|
||||||
selectedDriver
|
selectedDriver
|
||||||
}) => {
|
}) => (
|
||||||
return (
|
<div>
|
||||||
<div>
|
<h4>
|
||||||
<h4>
|
<FormattedMessage {...messages.nodeDetail} />
|
||||||
<FormattedMessage {...messages.nodeDetail} />
|
</h4>
|
||||||
</h4>
|
<Fieldset legend={formatMessage(messages.general)}>
|
||||||
<Fieldset legend={formatMessage(messages.general)}>
|
<Field
|
||||||
<Field
|
name={`${node}.name`}
|
||||||
name={`${node}.name`}
|
component={HorizontalInput}
|
||||||
component={HorizontalInput}
|
id={`${node}.name`}
|
||||||
id={`${node}.name`}
|
label={formatMessage(messages.name)}
|
||||||
label={formatMessage(messages.name)}
|
validate={[
|
||||||
validate={[
|
format({
|
||||||
format({
|
with: NODE_NAME_REGEX,
|
||||||
with: NODE_NAME_REGEX,
|
message: formatMessage(messages.nodeNameRegexp),
|
||||||
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,
|
|
||||||
allowBlank: true
|
allowBlank: true
|
||||||
})}
|
}),
|
||||||
/>
|
length({ max: 255 })
|
||||||
<Field
|
]}
|
||||||
name={`${node}.memory`}
|
/>
|
||||||
component={HorizontalInput}
|
</Fieldset>
|
||||||
id={`${node}.memory`}
|
<Fieldset legend={formatMessage(messages.management)}>
|
||||||
label={formatMessage(messages.memoryMb)}
|
<Field
|
||||||
type="number"
|
name={`${node}.pm_type`}
|
||||||
min={1}
|
component={HorizontalSelect}
|
||||||
validate={numericality({
|
id={`${node}.pm_type`}
|
||||||
int: true,
|
label={formatMessage(messages.driver)}
|
||||||
'>': 0,
|
validate={required()}
|
||||||
allowBlank: true
|
required
|
||||||
})}
|
>
|
||||||
/>
|
{['pxe_ipmitool', 'pxe_drac'].map((value, index) => (
|
||||||
<Field
|
<option key={index}>{value}</option>
|
||||||
name={`${node}.disk`}
|
))}
|
||||||
component={HorizontalInput}
|
</Field>
|
||||||
id={`${node}.disk`}
|
{renderDriverFields(selectedDriver, node)}
|
||||||
label={formatMessage(messages.diskGb)}
|
</Fieldset>
|
||||||
type="number"
|
<Fieldset legend={formatMessage(messages.hardware)}>
|
||||||
min={1}
|
<Field
|
||||||
validate={numericality({
|
name={`${node}.arch`}
|
||||||
int: true,
|
component={HorizontalSelect}
|
||||||
'>': 0,
|
id={`${node}.arch`}
|
||||||
allowBlank: true
|
label={formatMessage(messages.architecture)}
|
||||||
})}
|
>
|
||||||
/>
|
{[undefined, 'x86_64', 'i386'].map((value, index) => (
|
||||||
</Fieldset>
|
<option key={index}>{value}</option>
|
||||||
<Fieldset legend={formatMessage(messages.networking)}>
|
))}
|
||||||
<Field
|
</Field>
|
||||||
name={`${node}.mac`}
|
<Field
|
||||||
component={HorizontalInput}
|
name={`${node}.cpu`}
|
||||||
id={`${node}.mac`}
|
component={HorizontalInput}
|
||||||
label={formatMessage(messages.nicMacAddresses)}
|
id={`${node}.cpu`}
|
||||||
description={formatMessage(messages.macAddressesDescription)}
|
label={formatMessage(messages.cpuCount)}
|
||||||
validate={[
|
type="number"
|
||||||
arrayOfFormat({
|
min={1}
|
||||||
with: MAC_ADDRESS_REGEX,
|
validate={numericality({
|
||||||
message: messages.enterValidMacAddress
|
int: true,
|
||||||
})
|
'>': 0,
|
||||||
]}
|
allowBlank: true
|
||||||
parse={value => value.split(',')}
|
})}
|
||||||
required
|
/>
|
||||||
/>
|
<Field
|
||||||
</Fieldset>
|
name={`${node}.memory`}
|
||||||
</div>
|
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 = {
|
RegisterNodeFields.propTypes = {
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
node: PropTypes.string.isRequired,
|
node: PropTypes.string.isRequired,
|
||||||
|
|
|
@ -36,23 +36,19 @@ const messages = defineMessages({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export const RegisterNodesTabPanes = ({ fields, meta, selectedNodeIndex }) => {
|
export const RegisterNodesTabPanes = ({ fields, meta, selectedNodeIndex }) => (
|
||||||
return (
|
<div className="tab-content">
|
||||||
<div className="tab-content">
|
{fields.map((node, index, fields) => (
|
||||||
{fields.map((node, index, fields) => {
|
<TabPane
|
||||||
return (
|
key={index}
|
||||||
<TabPane
|
isActive={selectedNodeIndex === index}
|
||||||
key={index}
|
// renderOnlyActive
|
||||||
isActive={selectedNodeIndex === index}
|
>
|
||||||
// renderOnlyActive
|
<RegisterNodeFields node={node} />
|
||||||
>
|
</TabPane>
|
||||||
<RegisterNodeFields node={node} />
|
))}
|
||||||
</TabPane>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
RegisterNodesTabPanes.propTypes = {
|
RegisterNodesTabPanes.propTypes = {
|
||||||
fields: PropTypes.object.isRequired,
|
fields: PropTypes.object.isRequired,
|
||||||
meta: PropTypes.object.isRequired,
|
meta: PropTypes.object.isRequired,
|
||||||
|
|
|
@ -42,8 +42,9 @@ class NotificationsToaster extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderNotifications() {
|
renderNotifications() {
|
||||||
return this.props.notifications.toList().map(notification => {
|
return this.props.notifications
|
||||||
return (
|
.toList()
|
||||||
|
.map(notification => (
|
||||||
<Notification
|
<Notification
|
||||||
key={notification.id}
|
key={notification.id}
|
||||||
title={notification.title}
|
title={notification.title}
|
||||||
|
@ -55,8 +56,7 @@ class NotificationsToaster extends React.Component {
|
||||||
this.props.removeNotification(notification.id)
|
this.props.removeNotification(notification.id)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
);
|
));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -36,19 +36,17 @@ class ParameterInputList extends React.Component {
|
||||||
this.props.emptyParametersMessage ||
|
this.props.emptyParametersMessage ||
|
||||||
this.props.intl.formatMessage(messages.noParameters);
|
this.props.intl.formatMessage(messages.noParameters);
|
||||||
|
|
||||||
const parameters = this.props.parameters.map(parameter => {
|
const parameters = this.props.parameters.map(parameter => (
|
||||||
return (
|
<ParameterInput
|
||||||
<ParameterInput
|
key={parameter.name}
|
||||||
key={parameter.name}
|
name={parameter.name}
|
||||||
name={parameter.name}
|
label={parameter.label}
|
||||||
label={parameter.label}
|
description={parameter.description}
|
||||||
description={parameter.description}
|
defaultValue={parameter.default}
|
||||||
defaultValue={parameter.default}
|
value={parameter.value}
|
||||||
value={parameter.value}
|
type={parameter.type}
|
||||||
type={parameter.type}
|
/>
|
||||||
/>
|
));
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (parameters.isEmpty()) {
|
if (parameters.isEmpty()) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -66,17 +66,15 @@ class Parameters extends React.Component {
|
||||||
</TabPane>
|
</TabPane>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return this.props.enabledEnvironments.toList().map(environment => {
|
return this.props.enabledEnvironments.toList().map(environment => (
|
||||||
return (
|
<TabPane
|
||||||
<TabPane
|
isActive={this.state.activeTab === environment.file}
|
||||||
isActive={this.state.activeTab === environment.file}
|
key={environment.file}
|
||||||
key={environment.file}
|
renderOnlyActive
|
||||||
renderOnlyActive
|
>
|
||||||
>
|
<EnvironmentParameters environment={environment.file} />
|
||||||
<EnvironmentParameters environment={environment.file} />
|
</TabPane>
|
||||||
</TabPane>
|
));
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,8 +166,8 @@ const convertJsonTypeParameterValueToString = value =>
|
||||||
// accept empty string as valid value
|
// accept empty string as valid value
|
||||||
['', undefined].includes(value) ? '' : JSON.stringify(value);
|
['', undefined].includes(value) ? '' : JSON.stringify(value);
|
||||||
|
|
||||||
const getFormInitialValues = parameters => {
|
const getFormInitialValues = parameters =>
|
||||||
return parameters
|
parameters
|
||||||
.map(p => {
|
.map(p => {
|
||||||
const value = p.value === undefined ? p.default : p.value;
|
const value = p.value === undefined ? p.default : p.value;
|
||||||
if (p.type.toLowerCase() === 'json') {
|
if (p.type.toLowerCase() === 'json') {
|
||||||
|
@ -177,22 +177,20 @@ const getFormInitialValues = parameters => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.toJS();
|
.toJS();
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter out non updated parameters, so only parameters which have been actually changed
|
* Filter out non updated parameters, so only parameters which have been actually changed
|
||||||
* get sent to updateparameters
|
* get sent to updateparameters
|
||||||
*/
|
*/
|
||||||
const filterFormData = (values, initialValues) => {
|
const filterFormData = (values, initialValues) =>
|
||||||
return pickBy(values, (value, key) => !isEqual(value, initialValues[key]));
|
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
|
* 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
|
* or array. Also, parameters with undefined value are set to null
|
||||||
*/
|
*/
|
||||||
const parseJsonTypeValues = (values, parameters) => {
|
const parseJsonTypeValues = (values, parameters) =>
|
||||||
return mapValues(values, (value, key) => {
|
mapValues(values, (value, key) => {
|
||||||
if (parameters.get(key).type.toLowerCase() === 'json') {
|
if (parameters.get(key).type.toLowerCase() === 'json') {
|
||||||
try {
|
try {
|
||||||
return JSON.parse(value);
|
return JSON.parse(value);
|
||||||
|
@ -202,7 +200,6 @@ const parseJsonTypeValues = (values, parameters) => {
|
||||||
}
|
}
|
||||||
return value === undefined ? null : value;
|
return value === undefined ? null : value;
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmit = (
|
const handleSubmit = (
|
||||||
{ saveAndClose, ...values },
|
{ saveAndClose, ...values },
|
||||||
|
|
|
@ -49,19 +49,17 @@ const ParametersSidebar = ({
|
||||||
</a>
|
</a>
|
||||||
</Tab>
|
</Tab>
|
||||||
<li className="spacer" />
|
<li className="spacer" />
|
||||||
{enabledEnvironments.map(environment => {
|
{enabledEnvironments.map(environment => (
|
||||||
return (
|
<Tab key={environment.file} isActive={isTabActive(environment.file)}>
|
||||||
<Tab key={environment.file} isActive={isTabActive(environment.file)}>
|
<a
|
||||||
<a
|
className="link"
|
||||||
className="link"
|
onClick={() => activateTab(environment.file)}
|
||||||
onClick={() => activateTab(environment.file)}
|
title={environment.file}
|
||||||
title={environment.file}
|
>
|
||||||
>
|
{environment.title}
|
||||||
{environment.title}
|
</a>
|
||||||
</a>
|
</Tab>
|
||||||
</Tab>
|
))}
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -52,36 +52,32 @@ class PlanFileInput extends React.Component {
|
||||||
let reader = new FileReader();
|
let reader = new FileReader();
|
||||||
let file = inputFiles[i];
|
let file = inputFiles[i];
|
||||||
|
|
||||||
reader.onerror = (f => {
|
reader.onerror = (f => e => {
|
||||||
return e => {
|
this.setState({
|
||||||
this.setState({
|
unreadableFile: f.webkitRelativePath
|
||||||
unreadableFile: f.webkitRelativePath
|
});
|
||||||
});
|
|
||||||
};
|
|
||||||
})(file);
|
})(file);
|
||||||
|
|
||||||
reader.onload = (f => {
|
reader.onload = (f => e => {
|
||||||
return e => {
|
const filePath = f.webkitRelativePath.replace(/^[^\/]*\//, '');
|
||||||
const filePath = f.webkitRelativePath.replace(/^[^\/]*\//, '');
|
if (!filePath.match(IGNORED_FILE_PATHS)) {
|
||||||
if (!filePath.match(IGNORED_FILE_PATHS)) {
|
let obj = {
|
||||||
let obj = {
|
name: filePath,
|
||||||
name: filePath,
|
content: e.target.result
|
||||||
content: e.target.result
|
};
|
||||||
};
|
files.push(obj);
|
||||||
files.push(obj);
|
}
|
||||||
}
|
processedFilesCount += 1;
|
||||||
processedFilesCount += 1;
|
this.setState(
|
||||||
this.setState(
|
{ progress: Math.round(100 / l * processedFilesCount) },
|
||||||
{ progress: Math.round(100 / l * processedFilesCount) },
|
() => {
|
||||||
() => {
|
// if the last file is processed, setValue -> triggers onChange on Formsy
|
||||||
// if the last file is processed, setValue -> triggers onChange on Formsy
|
if (processedFilesCount === l) {
|
||||||
if (processedFilesCount === l) {
|
this.props.setValue(files);
|
||||||
this.props.setValue(files);
|
this.setState({ progress: 0 });
|
||||||
this.setState({ progress: 0 });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
}
|
||||||
};
|
);
|
||||||
})(file);
|
})(file);
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,33 +38,31 @@ const NodesAssignment = ({
|
||||||
nodeCountParametersByRole,
|
nodeCountParametersByRole,
|
||||||
roles,
|
roles,
|
||||||
updateNodesAssignment
|
updateNodesAssignment
|
||||||
}) => {
|
}) => (
|
||||||
return (
|
<NodesAssignmentForm
|
||||||
<NodesAssignmentForm
|
currentPlanName={currentPlanName}
|
||||||
currentPlanName={currentPlanName}
|
initialValues={assignedNodesCountsByRole.toJS()}
|
||||||
initialValues={assignedNodesCountsByRole.toJS()}
|
updateNodesAssignment={updateNodesAssignment}
|
||||||
updateNodesAssignment={updateNodesAssignment}
|
>
|
||||||
>
|
<div className="row row-cards-pf">
|
||||||
<div className="row row-cards-pf">
|
{roles
|
||||||
{roles.toList().map(role => {
|
.toList()
|
||||||
return (
|
.map(role => (
|
||||||
<RoleCard
|
<RoleCard
|
||||||
key={role.name}
|
key={role.name}
|
||||||
currentPlanName={currentPlanName}
|
currentPlanName={currentPlanName}
|
||||||
name={role.name}
|
name={role.name}
|
||||||
title={startCase(role.name)}
|
title={startCase(role.name)}
|
||||||
identifier={role.identifier}
|
identifier={role.identifier}
|
||||||
assignedNodesCountParameter={nodeCountParametersByRole.get(
|
assignedNodesCountParameter={nodeCountParametersByRole.get(
|
||||||
role.name
|
role.name
|
||||||
)}
|
)}
|
||||||
availableNodesCount={availableNodesCountsByRole.get(role.name)}
|
availableNodesCount={availableNodesCountsByRole.get(role.name)}
|
||||||
/>
|
/>
|
||||||
);
|
))}
|
||||||
})}
|
</div>
|
||||||
</div>
|
</NodesAssignmentForm>
|
||||||
</NodesAssignmentForm>
|
);
|
||||||
);
|
|
||||||
};
|
|
||||||
NodesAssignment.propTypes = {
|
NodesAssignment.propTypes = {
|
||||||
assignedNodesCountsByRole: ImmutablePropTypes.map.isRequired,
|
assignedNodesCountsByRole: ImmutablePropTypes.map.isRequired,
|
||||||
availableNodesCountsByRole: ImmutablePropTypes.map.isRequired,
|
availableNodesCountsByRole: ImmutablePropTypes.map.isRequired,
|
||||||
|
@ -82,12 +80,10 @@ const mapStateToProps = state => ({
|
||||||
roles: getRoles(state)
|
roles: getRoles(state)
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = dispatch => ({
|
||||||
return {
|
updateNodesAssignment: (currentPlanName, data) => {
|
||||||
updateNodesAssignment: (currentPlanName, data) => {
|
dispatch(ParametersActions.updateNodesAssignment(currentPlanName, data));
|
||||||
dispatch(ParametersActions.updateNodesAssignment(currentPlanName, data));
|
}
|
||||||
}
|
});
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(NodesAssignment);
|
export default connect(mapStateToProps, mapDispatchToProps)(NodesAssignment);
|
||||||
|
|
|
@ -53,22 +53,17 @@ class RoleServices extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderServiceTabs() {
|
renderServiceTabs() {
|
||||||
return this.props.services.toList().map(service => {
|
return this.props.services.toList().map(service => (
|
||||||
return (
|
<Tab
|
||||||
<Tab
|
key={service.type}
|
||||||
key={service.type}
|
title={service.description}
|
||||||
title={service.description}
|
isActive={service.id === this.state.selectedService}
|
||||||
isActive={service.id === this.state.selectedService}
|
>
|
||||||
>
|
<a className="link" onClick={this.selectService.bind(this, service.id)}>
|
||||||
<a
|
{service.type.split('::').pop()}
|
||||||
className="link"
|
</a>
|
||||||
onClick={this.selectService.bind(this, service.id)}
|
</Tab>
|
||||||
>
|
));
|
||||||
{service.type.split('::').pop()}
|
|
||||||
</a>
|
|
||||||
</Tab>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -18,20 +18,18 @@ import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link, Route } from 'react-router-dom';
|
import { Link, Route } from 'react-router-dom';
|
||||||
|
|
||||||
const NavTab = ({ activeClassName, children, to, exact, location, id }) => {
|
const NavTab = ({ activeClassName, children, to, exact, location, id }) => (
|
||||||
return (
|
<Route
|
||||||
<Route
|
location={location}
|
||||||
location={location}
|
path={typeof to === 'object' ? to.pathname : to}
|
||||||
path={typeof to === 'object' ? to.pathname : to}
|
exact={exact}
|
||||||
exact={exact}
|
children={({ match, location }) => (
|
||||||
children={({ match, location }) => (
|
<li className={match ? activeClassName : ''} id={id}>
|
||||||
<li className={match ? activeClassName : ''} id={id}>
|
<Link to={to}>{children}</Link>
|
||||||
<Link to={to}>{children}</Link>
|
</li>
|
||||||
</li>
|
)}
|
||||||
)}
|
/>
|
||||||
/>
|
);
|
||||||
);
|
|
||||||
};
|
|
||||||
NavTab.propTypes = {
|
NavTab.propTypes = {
|
||||||
activeClassName: PropTypes.string.isRequired,
|
activeClassName: PropTypes.string.isRequired,
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
|
|
|
@ -18,18 +18,16 @@ import { Button } from 'react-bootstrap';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
export const SortDirectionInput = ({ input: { onChange, value }, title }) => {
|
export const SortDirectionInput = ({ input: { onChange, value }, title }) => (
|
||||||
return (
|
<Button
|
||||||
<Button
|
title={title}
|
||||||
title={title}
|
type="button"
|
||||||
type="button"
|
bsStyle="link"
|
||||||
bsStyle="link"
|
onClick={() => onChange(value === 'asc' ? 'desc' : 'asc')}
|
||||||
onClick={() => onChange(value === 'asc' ? 'desc' : 'asc')}
|
>
|
||||||
>
|
<span className={`fa fa-sort-alpha-${value}`} />
|
||||||
<span className={`fa fa-sort-alpha-${value}`} />
|
</Button>
|
||||||
</Button>
|
);
|
||||||
);
|
|
||||||
};
|
|
||||||
SortDirectionInput.propTypes = {
|
SortDirectionInput.propTypes = {
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
input: PropTypes.object.isRequired,
|
input: PropTypes.object.isRequired,
|
||||||
|
@ -50,24 +48,22 @@ const getIconClass = optionKey => {
|
||||||
export const ContentViewSelectorInput = ({
|
export const ContentViewSelectorInput = ({
|
||||||
input: { onChange, value },
|
input: { onChange, value },
|
||||||
options
|
options
|
||||||
}) => {
|
}) => (
|
||||||
return (
|
<div>
|
||||||
<div>
|
{Object.keys(options).map(k => (
|
||||||
{Object.keys(options).map(k => (
|
<Button
|
||||||
<Button
|
key={k}
|
||||||
key={k}
|
type="button"
|
||||||
type="button"
|
bsStyle="link"
|
||||||
bsStyle="link"
|
title={options[k]['title']}
|
||||||
title={options[k]['title']}
|
id={options[k]['id']}
|
||||||
id={options[k]['id']}
|
onClick={() => onChange(k)}
|
||||||
onClick={() => onChange(k)}
|
>
|
||||||
>
|
<i className={getIconClass(k)} />
|
||||||
<i className={getIconClass(k)} />
|
</Button>
|
||||||
</Button>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
);
|
||||||
);
|
|
||||||
};
|
|
||||||
ContentViewSelectorInput.propTypes = {
|
ContentViewSelectorInput.propTypes = {
|
||||||
input: PropTypes.object.isRequired,
|
input: PropTypes.object.isRequired,
|
||||||
options: PropTypes.object.isRequired
|
options: PropTypes.object.isRequired
|
||||||
|
|
|
@ -18,20 +18,14 @@ import { Dropdown } from 'react-bootstrap';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const DropdownKebab = ({ children, id, pullRight }) => {
|
const DropdownKebab = ({ children, id, pullRight }) => (
|
||||||
return (
|
<Dropdown className="dropdown-kebab-pf" id={id} pullRight={pullRight}>
|
||||||
<Dropdown className="dropdown-kebab-pf" id={id} pullRight={pullRight}>
|
<Dropdown.Toggle bsStyle="link" noCaret onClick={e => e.stopPropagation()}>
|
||||||
<Dropdown.Toggle
|
<span className="fa fa-ellipsis-v" />
|
||||||
bsStyle="link"
|
</Dropdown.Toggle>
|
||||||
noCaret
|
<Dropdown.Menu>{children}</Dropdown.Menu>
|
||||||
onClick={e => e.stopPropagation()}
|
</Dropdown>
|
||||||
>
|
);
|
||||||
<span className="fa fa-ellipsis-v" />
|
|
||||||
</Dropdown.Toggle>
|
|
||||||
<Dropdown.Menu>{children}</Dropdown.Menu>
|
|
||||||
</Dropdown>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
DropdownKebab.propTypes = {
|
DropdownKebab.propTypes = {
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
|
|
|
@ -18,21 +18,19 @@ import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link, Route } from 'react-router-dom';
|
import { Link, Route } from 'react-router-dom';
|
||||||
|
|
||||||
const MenuItemLink = ({ children, to, exact, location, ...rest }) => {
|
const MenuItemLink = ({ children, to, exact, location, ...rest }) => (
|
||||||
return (
|
<Route
|
||||||
<Route
|
path={to}
|
||||||
path={to}
|
exact={exact}
|
||||||
exact={exact}
|
children={({ match, location }) => (
|
||||||
children={({ match, location }) => (
|
<li onClick={e => e.stopPropagation()}>
|
||||||
<li onClick={e => e.stopPropagation()}>
|
<Link {...rest} to={to}>
|
||||||
<Link {...rest} to={to}>
|
{children}
|
||||||
{children}
|
</Link>
|
||||||
</Link>
|
</li>
|
||||||
</li>
|
)}
|
||||||
)}
|
/>
|
||||||
/>
|
);
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
MenuItemLink.propTypes = {
|
MenuItemLink.propTypes = {
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
|
|
|
@ -22,13 +22,11 @@ export default class FormErrorList extends React.Component {
|
||||||
renderErrors() {
|
renderErrors() {
|
||||||
const { errors } = this.props;
|
const { errors } = this.props;
|
||||||
if (errors.length > 1) {
|
if (errors.length > 1) {
|
||||||
const errorList = errors.map((error, index) => {
|
const errorList = errors.map((error, index) => (
|
||||||
return (
|
<li key={index}>
|
||||||
<li key={index}>
|
{error.title} {error.message}
|
||||||
{error.title} {error.message}
|
</li>
|
||||||
</li>
|
));
|
||||||
);
|
|
||||||
});
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<strong>{`${errors.length} Errors Found:`}</strong>
|
<strong>{`${errors.length} Errors Found:`}</strong>
|
||||||
|
|
|
@ -32,24 +32,22 @@ const HorizontalCheckBox = ({
|
||||||
meta,
|
meta,
|
||||||
required,
|
required,
|
||||||
...rest
|
...rest
|
||||||
}) => {
|
}) => (
|
||||||
return (
|
<FormGroup controlId={id} validationState={getValidationState(meta)}>
|
||||||
<FormGroup controlId={id} validationState={getValidationState(meta)}>
|
<Col
|
||||||
<Col
|
componentClass={ControlLabel}
|
||||||
componentClass={ControlLabel}
|
sm={labelColumns}
|
||||||
sm={labelColumns}
|
className={cx({ 'required-pf': required })}
|
||||||
className={cx({ 'required-pf': required })}
|
>
|
||||||
>
|
{label}
|
||||||
{label}
|
</Col>
|
||||||
</Col>
|
<Col sm={inputColumns}>
|
||||||
<Col sm={inputColumns}>
|
<Checkbox {...input} {...rest} />
|
||||||
<Checkbox {...input} {...rest} />
|
<InputMessage {...meta} />
|
||||||
<InputMessage {...meta} />
|
<InputDescription description={description} />
|
||||||
<InputDescription description={description} />
|
</Col>
|
||||||
</Col>
|
</FormGroup>
|
||||||
</FormGroup>
|
);
|
||||||
);
|
|
||||||
};
|
|
||||||
HorizontalCheckBox.propTypes = {
|
HorizontalCheckBox.propTypes = {
|
||||||
description: PropTypes.node,
|
description: PropTypes.node,
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
|
|
|
@ -32,24 +32,22 @@ const HorizontalInput = ({
|
||||||
meta,
|
meta,
|
||||||
required,
|
required,
|
||||||
...rest
|
...rest
|
||||||
}) => {
|
}) => (
|
||||||
return (
|
<FormGroup controlId={id} validationState={getValidationState(meta)}>
|
||||||
<FormGroup controlId={id} validationState={getValidationState(meta)}>
|
<Col
|
||||||
<Col
|
componentClass={ControlLabel}
|
||||||
componentClass={ControlLabel}
|
sm={labelColumns}
|
||||||
sm={labelColumns}
|
className={cx({ 'required-pf': required })}
|
||||||
className={cx({ 'required-pf': required })}
|
>
|
||||||
>
|
{label}
|
||||||
{label}
|
</Col>
|
||||||
</Col>
|
<Col sm={inputColumns}>
|
||||||
<Col sm={inputColumns}>
|
<FormControl type={type} {...input} {...rest} />
|
||||||
<FormControl type={type} {...input} {...rest} />
|
<InputMessage {...meta} />
|
||||||
<InputMessage {...meta} />
|
<InputDescription description={description} />
|
||||||
<InputDescription description={description} />
|
</Col>
|
||||||
</Col>
|
</FormGroup>
|
||||||
</FormGroup>
|
);
|
||||||
);
|
|
||||||
};
|
|
||||||
HorizontalInput.propTypes = {
|
HorizontalInput.propTypes = {
|
||||||
description: PropTypes.node,
|
description: PropTypes.node,
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
|
|
|
@ -33,31 +33,29 @@ const HorizontalSelect = ({
|
||||||
meta,
|
meta,
|
||||||
required,
|
required,
|
||||||
...rest
|
...rest
|
||||||
}) => {
|
}) => (
|
||||||
return (
|
<FormGroup controlId={id} validationState={getValidationState(meta)}>
|
||||||
<FormGroup controlId={id} validationState={getValidationState(meta)}>
|
<Col
|
||||||
<Col
|
componentClass={ControlLabel}
|
||||||
componentClass={ControlLabel}
|
sm={labelColumns}
|
||||||
sm={labelColumns}
|
className={cx({ 'required-pf': required })}
|
||||||
className={cx({ 'required-pf': required })}
|
>
|
||||||
|
{label}
|
||||||
|
</Col>
|
||||||
|
<Col sm={inputColumns}>
|
||||||
|
<FormControl
|
||||||
|
componentClass="select"
|
||||||
|
multiple={multiple}
|
||||||
|
{...rest}
|
||||||
|
{...input}
|
||||||
>
|
>
|
||||||
{label}
|
{children}
|
||||||
</Col>
|
</FormControl>
|
||||||
<Col sm={inputColumns}>
|
<InputMessage {...meta} />
|
||||||
<FormControl
|
<InputDescription description={description} />
|
||||||
componentClass="select"
|
</Col>
|
||||||
multiple={multiple}
|
</FormGroup>
|
||||||
{...rest}
|
);
|
||||||
{...input}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</FormControl>
|
|
||||||
<InputMessage {...meta} />
|
|
||||||
<InputDescription description={description} />
|
|
||||||
</Col>
|
|
||||||
</FormGroup>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
HorizontalSelect.propTypes = {
|
HorizontalSelect.propTypes = {
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
description: PropTypes.node,
|
description: PropTypes.node,
|
||||||
|
|
|
@ -70,18 +70,16 @@ NodePickerInput.defaultProps = {
|
||||||
};
|
};
|
||||||
export default NodePickerInput;
|
export default NodePickerInput;
|
||||||
|
|
||||||
const PickerArrow = ({ direction, disabled, onClick }) => {
|
const PickerArrow = ({ direction, disabled, onClick }) => (
|
||||||
return (
|
<button
|
||||||
<button
|
type="button"
|
||||||
type="button"
|
className={`btn btn-default btn-node-picker btn-node-picker-${direction}`}
|
||||||
className={`btn btn-default btn-node-picker btn-node-picker-${direction}`}
|
onClick={onClick}
|
||||||
onClick={onClick}
|
disabled={disabled}
|
||||||
disabled={disabled}
|
>
|
||||||
>
|
<span className={`fa fa-angle-${direction}`} aria-hidden="true" />
|
||||||
<span className={`fa fa-angle-${direction}`} aria-hidden="true" />
|
</button>
|
||||||
</button>
|
);
|
||||||
);
|
|
||||||
};
|
|
||||||
PickerArrow.propTypes = {
|
PickerArrow.propTypes = {
|
||||||
direction: PropTypes.oneOf(['up', 'down']).isRequired,
|
direction: PropTypes.oneOf(['up', 'down']).isRequired,
|
||||||
disabled: PropTypes.bool.isRequired,
|
disabled: PropTypes.bool.isRequired,
|
||||||
|
|
|
@ -83,9 +83,7 @@ class DataTable extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
let columns = this._getColumns();
|
let columns = this._getColumns();
|
||||||
|
|
||||||
let headers = columns.map(column => {
|
let headers = columns.map(column => column.props.header);
|
||||||
return column.props.header;
|
|
||||||
});
|
|
||||||
|
|
||||||
let rows = [];
|
let rows = [];
|
||||||
for (var i = 0; i < this.props.rowsCount; ++i) {
|
for (var i = 0; i < this.props.rowsCount; ++i) {
|
||||||
|
|
|
@ -19,12 +19,12 @@ import React from 'react';
|
||||||
|
|
||||||
export default class DataTableRow extends React.Component {
|
export default class DataTableRow extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
let cells = this.props.columns.map((column, index) => {
|
let cells = this.props.columns.map((column, index) =>
|
||||||
return React.cloneElement(column.props.cell, {
|
React.cloneElement(column.props.cell, {
|
||||||
rowIndex: this.props.index,
|
rowIndex: this.props.index,
|
||||||
key: index
|
key: index
|
||||||
});
|
})
|
||||||
});
|
);
|
||||||
return <tr>{cells}</tr>;
|
return <tr>{cells}</tr>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,23 +50,21 @@ export default class Validation extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderValidationGroups() {
|
renderValidationGroups() {
|
||||||
return this.props.groups.map(group => {
|
return this.props.groups.map(group => (
|
||||||
return (
|
<div key={group} className="list-view-pf-additional-info-item">
|
||||||
<div key={group} className="list-view-pf-additional-info-item">
|
<span
|
||||||
<span
|
className="label label-default"
|
||||||
className="label label-default"
|
onClick={() =>
|
||||||
onClick={() =>
|
this.props.addActiveFilter({
|
||||||
this.props.addActiveFilter({
|
filterBy: 'group',
|
||||||
filterBy: 'group',
|
filterString: group
|
||||||
filterString: group
|
})
|
||||||
})
|
}
|
||||||
}
|
>
|
||||||
>
|
<small>{group}</small>
|
||||||
<small>{group}</small>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
));
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -86,14 +86,12 @@ class ValidationDetail extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderValidationGroups() {
|
renderValidationGroups() {
|
||||||
return this.props.groups.map(group => {
|
return this.props.groups.map(group => (
|
||||||
return (
|
<small key={group}>
|
||||||
<small key={group}>
|
<span className="label label-default">{group}</span>
|
||||||
<span className="label label-default">{group}</span>
|
|
||||||
|
</small>
|
||||||
</small>
|
));
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderValidationOutput() {
|
renderValidationOutput() {
|
||||||
|
|
|
@ -117,8 +117,9 @@ class ValidationsList extends React.Component {
|
||||||
</BlankSlate>
|
</BlankSlate>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return validations.toList().map(validation => {
|
return validations
|
||||||
return (
|
.toList()
|
||||||
|
.map(validation => (
|
||||||
<Validation
|
<Validation
|
||||||
key={validation.id}
|
key={validation.id}
|
||||||
name={validation.name}
|
name={validation.name}
|
||||||
|
@ -139,8 +140,7 @@ class ValidationsList extends React.Component {
|
||||||
id={validation.id}
|
id={validation.id}
|
||||||
addActiveFilter={this.props.addActiveFilter}
|
addActiveFilter={this.props.addActiveFilter}
|
||||||
/>
|
/>
|
||||||
);
|
));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,36 +226,32 @@ ValidationsList.propTypes = {
|
||||||
validationsLoaded: PropTypes.bool.isRequired
|
validationsLoaded: PropTypes.bool.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = dispatch => ({
|
||||||
return {
|
addActiveFilter: data =>
|
||||||
addActiveFilter: data =>
|
dispatch(addActiveFilter('validationsToolbar', data)),
|
||||||
dispatch(addActiveFilter('validationsToolbar', data)),
|
fetchValidations: () => dispatch(ValidationsActions.fetchValidations()),
|
||||||
fetchValidations: () => dispatch(ValidationsActions.fetchValidations()),
|
fetchWorkflowExecutions: () =>
|
||||||
fetchWorkflowExecutions: () =>
|
dispatch(WorkflowExecutionsActions.fetchWorkflowExecutions()),
|
||||||
dispatch(WorkflowExecutionsActions.fetchWorkflowExecutions()),
|
runValidation: (id, currentPlanName) => {
|
||||||
runValidation: (id, currentPlanName) => {
|
dispatch(ValidationsActions.runValidation(id, currentPlanName));
|
||||||
dispatch(ValidationsActions.runValidation(id, currentPlanName));
|
},
|
||||||
},
|
stopValidation: executionId => {
|
||||||
stopValidation: executionId => {
|
dispatch(
|
||||||
dispatch(
|
WorkflowExecutionsActions.updateWorkflowExecution(executionId, {
|
||||||
WorkflowExecutionsActions.updateWorkflowExecution(executionId, {
|
state: 'PAUSED'
|
||||||
state: 'PAUSED'
|
})
|
||||||
})
|
);
|
||||||
);
|
}
|
||||||
}
|
});
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => ({
|
||||||
return {
|
executionsLoaded: state.executions.get('executionsLoaded'),
|
||||||
executionsLoaded: state.executions.get('executionsLoaded'),
|
isFetchingValidations: state.validations.get('isFetching'),
|
||||||
isFetchingValidations: state.validations.get('isFetching'),
|
validations: getFilteredValidations(state),
|
||||||
validations: getFilteredValidations(state),
|
validationsLoaded: state.validations.get('validationsLoaded'),
|
||||||
validationsLoaded: state.validations.get('validationsLoaded'),
|
currentPlanName: getCurrentPlanName(state),
|
||||||
currentPlanName: getCurrentPlanName(state),
|
showValidations: state.validations.showValidations
|
||||||
showValidations: state.validations.showValidations
|
});
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default injectIntl(
|
export default injectIntl(
|
||||||
connect(mapStateToProps, mapDispatchToProps)(ValidationsList)
|
connect(mapStateToProps, mapDispatchToProps)(ValidationsList)
|
||||||
|
|
|
@ -140,23 +140,18 @@ ValidationsToolbar.propTypes = {
|
||||||
intl: PropTypes.object,
|
intl: PropTypes.object,
|
||||||
validationsCount: PropTypes.number.isRequired
|
validationsCount: PropTypes.number.isRequired
|
||||||
};
|
};
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = dispatch => ({
|
||||||
return {
|
addActiveFilter: data =>
|
||||||
addActiveFilter: data =>
|
dispatch(addActiveFilter('validationsToolbar', data)),
|
||||||
dispatch(addActiveFilter('validationsToolbar', data)),
|
clearActiveFilters: () => dispatch(clearActiveFilters('validationsToolbar')),
|
||||||
clearActiveFilters: () =>
|
deleteActiveFilter: uuid =>
|
||||||
dispatch(clearActiveFilters('validationsToolbar')),
|
dispatch(deleteActiveFilter('validationsToolbar', uuid))
|
||||||
deleteActiveFilter: uuid =>
|
});
|
||||||
dispatch(deleteActiveFilter('validationsToolbar', uuid))
|
const mapStateToProps = state => ({
|
||||||
};
|
activeFilters: getActiveFilters(state, 'validationsToolbar'),
|
||||||
};
|
filteredValidationsCount: getFilteredValidations(state).size,
|
||||||
const mapStateToProps = state => {
|
validationsCount: getValidationsWithResults(state).size
|
||||||
return {
|
});
|
||||||
activeFilters: getActiveFilters(state, 'validationsToolbar'),
|
|
||||||
filteredValidationsCount: getFilteredValidations(state).size,
|
|
||||||
validationsCount: getValidationsWithResults(state).size
|
|
||||||
};
|
|
||||||
};
|
|
||||||
export default injectIntl(
|
export default injectIntl(
|
||||||
connect(mapStateToProps, mapDispatchToProps)(ValidationsToolbar)
|
connect(mapStateToProps, mapDispatchToProps)(ValidationsToolbar)
|
||||||
);
|
);
|
||||||
|
|
|
@ -50,12 +50,12 @@ export default function environmentConfigurationReducer(
|
||||||
|
|
||||||
case EnvironmentConfigurationConstants.UPDATE_ENVIRONMENT_CONFIGURATION_SUCCESS: {
|
case EnvironmentConfigurationConstants.UPDATE_ENVIRONMENT_CONFIGURATION_SUCCESS: {
|
||||||
const enabledEnvs = fromJS(action.payload);
|
const enabledEnvs = fromJS(action.payload);
|
||||||
const updatedEnvs = state.environments.map(environment => {
|
const updatedEnvs = state.environments.map(environment =>
|
||||||
return environment.set(
|
environment.set(
|
||||||
'enabled',
|
'enabled',
|
||||||
enabledEnvs.includes(environment.get('file'))
|
enabledEnvs.includes(environment.get('file'))
|
||||||
);
|
)
|
||||||
});
|
);
|
||||||
return state.set('environments', updatedEnvs);
|
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
|
// Don't add a new filter if there already is one with the same
|
||||||
// filterBy and filterString.
|
// filterBy and filterString.
|
||||||
if (
|
if (
|
||||||
state.getIn([filter, 'activeFilters']).filter(value => {
|
state
|
||||||
return (
|
.getIn([filter, 'activeFilters'])
|
||||||
value.filterBy === filterBy && value.filterString === filterString
|
.filter(
|
||||||
);
|
value =>
|
||||||
}).size > 0
|
value.filterBy === filterBy && value.filterString === filterString
|
||||||
|
).size > 0
|
||||||
) {
|
) {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,17 +30,16 @@ export const getEnvironment = (state, environmentFileName) =>
|
||||||
|
|
||||||
export const getEnabledEnvironments = createSelector(
|
export const getEnabledEnvironments = createSelector(
|
||||||
getEnvironments,
|
getEnvironments,
|
||||||
environments => {
|
environments => environments.filter(environment => environment.get('enabled'))
|
||||||
return environments.filter(environment => environment.get('enabled'));
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getEnvironmentConfigurationSummary = createSelector(
|
export const getEnvironmentConfigurationSummary = createSelector(
|
||||||
getEnabledEnvironments,
|
getEnabledEnvironments,
|
||||||
environments => {
|
environments => {
|
||||||
const titlesList = environments.reduce((titlesList, environment) => {
|
const titlesList = environments.reduce(
|
||||||
return titlesList.push(environment.get('title'));
|
(titlesList, environment) => titlesList.push(environment.get('title')),
|
||||||
}, List());
|
List()
|
||||||
|
);
|
||||||
return titlesList.toArray().join(', ');
|
return titlesList.toArray().join(', ');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -50,17 +49,16 @@ export const getEnvironmentConfigurationSummary = createSelector(
|
||||||
*/
|
*/
|
||||||
export const getTopicsTree = createSelector(
|
export const getTopicsTree = createSelector(
|
||||||
[topics, environmentGroups, getEnvironments],
|
[topics, environmentGroups, getEnvironments],
|
||||||
(topics, environmentGroups, environments) => {
|
(topics, environmentGroups, environments) =>
|
||||||
return topics.map(topic => {
|
topics.map(topic =>
|
||||||
return topic.update('environment_groups', envGroups => {
|
topic.update('environment_groups', envGroups =>
|
||||||
return envGroups.map(envGroup => {
|
envGroups.map(envGroup =>
|
||||||
return environmentGroups
|
environmentGroups
|
||||||
.get(envGroup)
|
.get(envGroup)
|
||||||
.update('environments', envs => {
|
.update('environments', envs =>
|
||||||
return environments.filter((p, k) => envs.includes(k));
|
environments.filter((p, k) => envs.includes(k))
|
||||||
});
|
)
|
||||||
});
|
)
|
||||||
});
|
)
|
||||||
});
|
)
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
|
@ -16,9 +16,7 @@
|
||||||
|
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
|
|
||||||
export const getFilterByName = (state, filterName) => {
|
export const getFilterByName = (state, filterName) => state.filters[filterName];
|
||||||
return state.filters[filterName];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getActiveFilters = createSelector(getFilterByName, filter =>
|
export const getActiveFilters = createSelector(getFilterByName, filter =>
|
||||||
filter.get('activeFilters')
|
filter.get('activeFilters')
|
||||||
|
|
|
@ -103,11 +103,11 @@ export const getFilteredNodes = createSelector(
|
||||||
.update(nodes =>
|
.update(nodes =>
|
||||||
nodesToolbarFilter.get('activeFilters').reduce(
|
nodesToolbarFilter.get('activeFilters').reduce(
|
||||||
(filteredNodes, filter) =>
|
(filteredNodes, filter) =>
|
||||||
filteredNodes.filter(node => {
|
filteredNodes.filter(node =>
|
||||||
return getNodePropertyString(node, filter.filterBy)
|
getNodePropertyString(node, filter.filterBy)
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.includes(filter.filterString.toLowerCase());
|
.includes(filter.filterString.toLowerCase())
|
||||||
}),
|
),
|
||||||
nodes
|
nodes
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,7 +20,5 @@ const notifications = state => state.notifications.get('all');
|
||||||
|
|
||||||
export const getNonViewedNotifications = createSelector(
|
export const getNonViewedNotifications = createSelector(
|
||||||
notifications,
|
notifications,
|
||||||
notifications => {
|
notifications => notifications.filterNot(notification => notification.viewed)
|
||||||
return notifications.filterNot(notification => notification.viewed);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
|
@ -126,30 +126,27 @@ export const getRoleNetworkConfig = createSelector(
|
||||||
|
|
||||||
export const getEnvironmentParameters = createSelector(
|
export const getEnvironmentParameters = createSelector(
|
||||||
[getParametersExclInternal, getResources, getEnvironment],
|
[getParametersExclInternal, getResources, getEnvironment],
|
||||||
(parameters, resources, environment) => {
|
(parameters, resources, environment) =>
|
||||||
return (
|
resources
|
||||||
resources
|
// get list of resources from environment resource_registry
|
||||||
// get list of resources from environment resource_registry
|
.filter(r => environment.resourceRegistry.keySeq().includes(r.type))
|
||||||
.filter(r => environment.resourceRegistry.keySeq().includes(r.type))
|
// collect parameter names from those resources
|
||||||
// collect parameter names from those resources
|
.reduce(
|
||||||
.reduce(
|
(result, resource) =>
|
||||||
(result, resource) =>
|
result.union(
|
||||||
result.union(
|
_extractParameters(
|
||||||
_extractParameters(
|
resource.parameters,
|
||||||
resource.parameters,
|
resource.resources,
|
||||||
resource.resources,
|
resources
|
||||||
resources
|
)
|
||||||
)
|
),
|
||||||
),
|
Set()
|
||||||
Set()
|
)
|
||||||
)
|
// add parameters from environment's 'parameters' section to the list
|
||||||
// add parameters from environment's 'parameters' section to the list
|
.union(environment.parameterDefaults.keySeq())
|
||||||
.union(environment.parameterDefaults.keySeq())
|
.toMap()
|
||||||
.toMap()
|
// convert list of parameter names to map of actual parameter records
|
||||||
// convert list of parameter names to map of actual parameter records
|
.update(filterParameters(parameters))
|
||||||
.update(filterParameters(parameters))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -195,8 +192,8 @@ export const getResourceParametersDeep = createSelector(
|
||||||
/**
|
/**
|
||||||
* Recursively extracts Parameter names from a Resource and it's nested Resources
|
* Recursively extracts Parameter names from a Resource and it's nested Resources
|
||||||
*/
|
*/
|
||||||
const _extractParameters = (parameters, nestedResources, allResources) => {
|
const _extractParameters = (parameters, nestedResources, allResources) =>
|
||||||
return nestedResources.reduce((pars, res) => {
|
nestedResources.reduce((pars, res) => {
|
||||||
const resource = allResources.get(res);
|
const resource = allResources.get(res);
|
||||||
return _extractParameters(
|
return _extractParameters(
|
||||||
pars
|
pars
|
||||||
|
@ -207,4 +204,3 @@ const _extractParameters = (parameters, nestedResources, allResources) => {
|
||||||
allResources
|
allResources
|
||||||
);
|
);
|
||||||
}, parameters);
|
}, parameters);
|
||||||
};
|
|
||||||
|
|
|
@ -40,9 +40,6 @@ export const getPlans = createSelector(plans, plans => plans);
|
||||||
// TODO(jtomasek): update this to list 3 last used plans
|
// TODO(jtomasek): update this to list 3 last used plans
|
||||||
export const getAllPlansButCurrent = createSelector(
|
export const getAllPlansButCurrent = createSelector(
|
||||||
[plans, getCurrentPlanName],
|
[plans, getCurrentPlanName],
|
||||||
(plans, currentPlanName) => {
|
(plans, currentPlanName) =>
|
||||||
return plans
|
plans.filter(plan => plan.name != currentPlanName).sortBy(plan => plan.name)
|
||||||
.filter(plan => plan.name != currentPlanName)
|
|
||||||
.sortBy(plan => plan.name);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
|
@ -41,13 +41,12 @@ export const getCurrentStack = createSelector(
|
||||||
*/
|
*/
|
||||||
export const getCurrentStackDeploymentInProgress = createSelector(
|
export const getCurrentStackDeploymentInProgress = createSelector(
|
||||||
[stacksSelector, getCurrentPlanName],
|
[stacksSelector, getCurrentPlanName],
|
||||||
(stacks, currentPlanName) => {
|
(stacks, currentPlanName) =>
|
||||||
return [
|
[
|
||||||
stackStates.CREATE_IN_PROGRESS,
|
stackStates.CREATE_IN_PROGRESS,
|
||||||
stackStates.UPDATE_IN_PROGRESS,
|
stackStates.UPDATE_IN_PROGRESS,
|
||||||
stackStates.DELETE_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 => {
|
resources => {
|
||||||
let allResources = resources.size;
|
let allResources = resources.size;
|
||||||
if (allResources > 0) {
|
if (allResources > 0) {
|
||||||
let completeResources = resources.filter(r => {
|
let completeResources = resources.filter(
|
||||||
return r.resource_status === 'CREATE_COMPLETE';
|
r => r.resource_status === 'CREATE_COMPLETE'
|
||||||
}).size;
|
).size;
|
||||||
return Math.ceil(completeResources / allResources * 100);
|
return Math.ceil(completeResources / allResources * 100);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -49,14 +49,13 @@ export const getValidationExecutionsForCurrentPlan = createSelector(
|
||||||
*/
|
*/
|
||||||
export const getValidationsWithResults = createSelector(
|
export const getValidationsWithResults = createSelector(
|
||||||
[validations, getValidationExecutionsForCurrentPlan],
|
[validations, getValidationExecutionsForCurrentPlan],
|
||||||
(validations, results) => {
|
(validations, results) =>
|
||||||
return validations.map(validation => {
|
validations.map(validation => {
|
||||||
const validationResults = getValidationResults(validation.id, results);
|
const validationResults = getValidationResults(validation.id, results);
|
||||||
return validation
|
return validation
|
||||||
.set('results', validationResults)
|
.set('results', validationResults)
|
||||||
.set('status', getValidationStatus(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
|
* Helper function to get the most recent time a plan has been updated or
|
||||||
* created.
|
* created.
|
||||||
*/
|
*/
|
||||||
export const getMostRecentPlanUpdate = (executions, planName) => {
|
export const getMostRecentPlanUpdate = (executions, planName) =>
|
||||||
return (
|
executions
|
||||||
executions
|
.filter(
|
||||||
.filter(
|
execution =>
|
||||||
execution =>
|
[MistralConstants.PLAN_UPDATE, MistralConstants.PLAN_CREATE].includes(
|
||||||
[MistralConstants.PLAN_UPDATE, MistralConstants.PLAN_CREATE].includes(
|
execution.workflow_name
|
||||||
execution.workflow_name
|
) && execution.getIn(['input', 'container']) === planName
|
||||||
) && execution.getIn(['input', 'container']) === planName
|
)
|
||||||
)
|
.map(execution => execution.get('updated_at'))
|
||||||
.map(execution => execution.get('updated_at'))
|
.sort()
|
||||||
.sort()
|
.last() || 0;
|
||||||
.last() || 0
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to get a validation results by validation name
|
* Helper function to get a validation results by validation name
|
||||||
*/
|
*/
|
||||||
const getValidationResults = (validationId, results) => {
|
const getValidationResults = (validationId, results) =>
|
||||||
return results.filter(
|
results.filter(
|
||||||
result => result.getIn(['input', 'validation_name']) === validationId
|
result => result.getIn(['input', 'validation_name']) === validationId
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to determine validation status based on validation's results
|
* 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
|
* Convert Node's capabilities object to string
|
||||||
*/
|
*/
|
||||||
export const stringifyNodeCapabilities = capabilities => {
|
export const stringifyNodeCapabilities = capabilities =>
|
||||||
return Object.keys(capabilities)
|
Object.keys(capabilities)
|
||||||
.reduce((caps, key) => {
|
.reduce((caps, key) => {
|
||||||
if (!capabilities[key]) {
|
if (!capabilities[key]) {
|
||||||
return caps;
|
return caps;
|
||||||
|
@ -40,7 +40,6 @@ export const stringifyNodeCapabilities = capabilities => {
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
.join(',');
|
.join(',');
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set or update Node capability
|
* Set or update Node capability
|
||||||
|
|
Loading…
Reference in New Issue