Resolve CI issues
* update prettier dependency to version which works with npm5 [MIT] https://github.com/prettier/prettier * remove favicons-webpack-plugin * autofix linting errors to make tests pass * add simple favicon using html-webpack-plugin * remove unused .gitignore lines Change-Id: I6b7d1116f522a6a1dd5e8455e85f4db958424e7c Partial-Bug: 1743722 Closes-Bug: 1743898
This commit is contained in:
parent
9941b07efb
commit
27dfe42f5e
|
@ -1,8 +1,6 @@
|
|||
node_modules
|
||||
node_modules.tar.gz
|
||||
dist
|
||||
!dist/index.html
|
||||
!dist/tripleo_ui_config.js.sample
|
||||
tests_results.xml
|
||||
tripleo-ui-*.tgz
|
||||
tripleo-ui-*.tar.gz
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -59,14 +59,13 @@
|
|||
"eslint-config-prettier": "^1.7.0",
|
||||
"eslint-plugin-prettier": "2.1.2",
|
||||
"eslint-plugin-react": "5.1.1",
|
||||
"favicons-webpack-plugin": "0.0.7",
|
||||
"file-loader": "~0.9.0",
|
||||
"html-webpack-plugin": "^2.28.0",
|
||||
"jest": "19.0.2",
|
||||
"json-loader": "^0.5.4",
|
||||
"less": "~2.7.1",
|
||||
"less-loader": "~2.2.3",
|
||||
"prettier": "1.3.1",
|
||||
"prettier": "1.10.2",
|
||||
"react-addons-test-utils": "^15.5.1",
|
||||
"react-intl-po": "^1.1.0",
|
||||
"react-test-renderer": "^15.5.4",
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
import configureMockStore from 'redux-mock-store';
|
||||
import thunkMiddleware from 'redux-thunk';
|
||||
|
||||
import EnvironmentConfigurationActions
|
||||
from '../../js/actions/EnvironmentConfigurationActions';
|
||||
import EnvironmentConfigurationActions from '../../js/actions/EnvironmentConfigurationActions';
|
||||
import NotificationActions from '../../js/actions/NotificationActions';
|
||||
import MistralApiService from '../../js/services/MistralApiService';
|
||||
import { mockGetIntl } from './utils';
|
||||
|
@ -35,7 +34,8 @@ describe('fetchEnvironmentConfiguration', () => {
|
|||
'General Deployment Options': {
|
||||
environment_groups: [
|
||||
{
|
||||
description: 'Enable basic configuration required for OpenStack Deployment',
|
||||
description:
|
||||
'Enable basic configuration required for OpenStack Deployment',
|
||||
environments: [
|
||||
{
|
||||
enabled: true,
|
||||
|
@ -54,7 +54,8 @@ describe('fetchEnvironmentConfiguration', () => {
|
|||
const normalizedResponse = {
|
||||
environmentGroups: {
|
||||
'Enable basic configuration required for OpenStack Deployment': {
|
||||
description: 'Enable basic configuration required for OpenStack Deployment',
|
||||
description:
|
||||
'Enable basic configuration required for OpenStack Deployment',
|
||||
environments: ['overcloud-resource-registry-puppet.yaml'],
|
||||
title: null
|
||||
}
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
*/
|
||||
|
||||
import IronicApiService from '../../js/services/IronicApiService';
|
||||
import IronicInspectorApiService
|
||||
from '../../js/services/IronicInspectorApiService';
|
||||
import IronicInspectorApiService from '../../js/services/IronicInspectorApiService';
|
||||
import MistralApiService from '../../js/services/MistralApiService';
|
||||
import { mockStore } from './utils';
|
||||
import NodesActions from '../../js/actions/NodesActions';
|
||||
|
@ -240,11 +239,12 @@ describe('Asynchronous Introspect Nodes Action', () => {
|
|||
return store
|
||||
.dispatch(NodesActions.startNodesIntrospection(nodeIds))
|
||||
.then(() => {
|
||||
expect(
|
||||
MistralApiService.runWorkflow
|
||||
).toHaveBeenCalledWith(MistralConstants.BAREMETAL_INTROSPECT, {
|
||||
node_uuids: nodeIds
|
||||
});
|
||||
expect(MistralApiService.runWorkflow).toHaveBeenCalledWith(
|
||||
MistralConstants.BAREMETAL_INTROSPECT,
|
||||
{
|
||||
node_uuids: nodeIds
|
||||
}
|
||||
);
|
||||
expect(NodesActions.pollNodeslistDuringProgress).toHaveBeenCalled();
|
||||
expect(store.getActions()).toEqual([
|
||||
NodesActions.startOperation(nodeIds)
|
||||
|
@ -329,11 +329,12 @@ describe('startProvideNodes Action', () => {
|
|||
|
||||
it('dispatches actions', () => {
|
||||
return store.dispatch(NodesActions.startProvideNodes(nodeIds)).then(() => {
|
||||
expect(
|
||||
MistralApiService.runWorkflow
|
||||
).toHaveBeenCalledWith(MistralConstants.BAREMETAL_PROVIDE, {
|
||||
node_uuids: nodeIds
|
||||
});
|
||||
expect(MistralApiService.runWorkflow).toHaveBeenCalledWith(
|
||||
MistralConstants.BAREMETAL_PROVIDE,
|
||||
{
|
||||
node_uuids: nodeIds
|
||||
}
|
||||
);
|
||||
expect(NodesActions.pollNodeslistDuringProgress).toHaveBeenCalled();
|
||||
expect(store.getActions()).toEqual([
|
||||
NodesActions.startOperation(nodeIds)
|
||||
|
|
|
@ -107,12 +107,13 @@ describe('ParametersActions', () => {
|
|||
ParametersActions.updateParameters('overcloud', { foo: 'bar' })
|
||||
)
|
||||
.then(() => {
|
||||
expect(
|
||||
MistralApiService.runAction
|
||||
).toHaveBeenCalledWith(MistralConstants.PARAMETERS_UPDATE, {
|
||||
container: 'overcloud',
|
||||
parameters: { foo: 'bar' }
|
||||
});
|
||||
expect(MistralApiService.runAction).toHaveBeenCalledWith(
|
||||
MistralConstants.PARAMETERS_UPDATE,
|
||||
{
|
||||
container: 'overcloud',
|
||||
parameters: { foo: 'bar' }
|
||||
}
|
||||
);
|
||||
expect(store.getActions()).toEqual([
|
||||
ReduxFormActions.startSubmit('nodesAssignment'),
|
||||
ParametersActions.updateParametersPending(),
|
||||
|
|
|
@ -19,11 +19,8 @@ import { Map } from 'immutable';
|
|||
import MistralApiService from '../../js/services/MistralApiService';
|
||||
import ValidationsActions from '../../js/actions/ValidationsActions';
|
||||
import ValidationsConstants from '../../js/constants/ValidationsConstants';
|
||||
import WorkflowExecutionsActions
|
||||
from '../../js/actions/WorkflowExecutionsActions';
|
||||
import {
|
||||
WorkflowExecution
|
||||
} from '../../js/immutableRecords/workflowExecutions';
|
||||
import WorkflowExecutionsActions from '../../js/actions/WorkflowExecutionsActions';
|
||||
import { WorkflowExecution } from '../../js/immutableRecords/workflowExecutions';
|
||||
import MistralConstants from '../../js/constants/MistralConstants';
|
||||
import { mockStore } from './utils';
|
||||
|
||||
|
@ -125,12 +122,13 @@ describe('RunValidation action', () => {
|
|||
return store
|
||||
.dispatch(ValidationsActions.runValidation('512e', 'overcloud'))
|
||||
.then(() => {
|
||||
expect(
|
||||
MistralApiService.runWorkflow
|
||||
).toHaveBeenCalledWith(MistralConstants.VALIDATIONS_RUN, {
|
||||
validation_name: '512e',
|
||||
plan: 'overcloud'
|
||||
});
|
||||
expect(MistralApiService.runWorkflow).toHaveBeenCalledWith(
|
||||
MistralConstants.VALIDATIONS_RUN,
|
||||
{
|
||||
validation_name: '512e',
|
||||
plan: 'overcloud'
|
||||
}
|
||||
);
|
||||
expect(store.getActions()).toEqual([
|
||||
WorkflowExecutionsActions.addWorkflowExecution(
|
||||
addWorkflowExecutionResponse
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
*/
|
||||
|
||||
import MistralApiService from '../../js/services/MistralApiService';
|
||||
import WorkflowExecutionsActions
|
||||
from '../../js/actions/WorkflowExecutionsActions';
|
||||
import WorkflowExecutionsActions from '../../js/actions/WorkflowExecutionsActions';
|
||||
import { mockStore } from './utils';
|
||||
|
||||
describe('fetchWorkflowExecutions action', () => {
|
||||
|
@ -78,9 +77,10 @@ describe('updateWorkflowExecution action', () => {
|
|||
})
|
||||
)
|
||||
.then(() => {
|
||||
expect(
|
||||
MistralApiService.updateWorkflowExecution
|
||||
).toHaveBeenCalledWith('512e', { state: 'PAUSED' });
|
||||
expect(MistralApiService.updateWorkflowExecution).toHaveBeenCalledWith(
|
||||
'512e',
|
||||
{ state: 'PAUSED' }
|
||||
);
|
||||
expect(store.getActions()).toEqual([
|
||||
WorkflowExecutionsActions.updateWorkflowExecutionPending('512e', {
|
||||
state: 'PAUSED'
|
||||
|
|
|
@ -73,25 +73,20 @@ describe('Login component', () => {
|
|||
});
|
||||
|
||||
describe('When user is logged in', () => {
|
||||
xit(
|
||||
'redirects to nextPath when user is logged in and visits login page',
|
||||
() => {
|
||||
loginInstance = new Login();
|
||||
loginInstance.context = {
|
||||
router: {
|
||||
getCurrentQuery() {
|
||||
return {
|
||||
nextPath: 'nodes'
|
||||
};
|
||||
}
|
||||
xit('redirects to nextPath when user is logged in and visits login page', () => {
|
||||
loginInstance = new Login();
|
||||
loginInstance.context = {
|
||||
router: {
|
||||
getCurrentQuery() {
|
||||
return {
|
||||
nextPath: 'nodes'
|
||||
};
|
||||
}
|
||||
};
|
||||
// loginInstance.context.router.transitionTo = jest.genMockFunction();
|
||||
loginInstance.componentWillMount();
|
||||
expect(loginInstance.context.router.transitionTo).toBeCalledWith(
|
||||
'nodes'
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
// loginInstance.context.router.transitionTo = jest.genMockFunction();
|
||||
loginInstance.componentWillMount();
|
||||
expect(loginInstance.context.router.transitionTo).toBeCalledWith('nodes');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -18,8 +18,7 @@ import { Map } from 'immutable';
|
|||
import React from 'react';
|
||||
import ReactShallowRenderer from 'react-test-renderer/shallow';
|
||||
|
||||
import EnvironmentConfiguration
|
||||
from '../../../js/components/environment_configuration/EnvironmentConfiguration';
|
||||
import EnvironmentConfiguration from '../../../js/components/environment_configuration/EnvironmentConfiguration';
|
||||
|
||||
describe('EnvironmentConfiguration component', () => {
|
||||
let EnvConfVdom;
|
||||
|
|
|
@ -18,8 +18,7 @@ import { fromJS } from 'immutable';
|
|||
import React from 'react';
|
||||
import ReactShallowRenderer from 'react-test-renderer/shallow';
|
||||
|
||||
import EnvironmentConfigurationTopic
|
||||
from '../../../js/components/environment_configuration/EnvironmentConfigurationTopic';
|
||||
import EnvironmentConfigurationTopic from '../../../js/components/environment_configuration/EnvironmentConfigurationTopic';
|
||||
import MockPlan from '../../mocks/MockPlan';
|
||||
|
||||
const topic = MockPlan.capabilities.topics[0];
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
import React from 'react';
|
||||
import ReactShallowRenderer from 'react-test-renderer/shallow';
|
||||
|
||||
import EnvironmentGroup
|
||||
from '../../../js/components/environment_configuration/EnvironmentGroup';
|
||||
import EnvironmentGroup from '../../../js/components/environment_configuration/EnvironmentGroup';
|
||||
import MockPlan from '../../mocks/MockPlan';
|
||||
|
||||
const envGroup = MockPlan.capabilities.topics[0].environment_groups[0];
|
||||
|
|
|
@ -42,10 +42,7 @@ describe('Nodes Component', () => {
|
|||
|
||||
xit('should listen to NodesStore changes', () => {});
|
||||
|
||||
xit(
|
||||
'should get nodes from NodesStore and store them in state on change in NodesStore',
|
||||
() => {}
|
||||
);
|
||||
xit('should get nodes from NodesStore and store them in state on change in NodesStore', () => {});
|
||||
|
||||
xit('should issue a request to list Nodes on when mounted', () => {
|
||||
spyOn(IronicApiService, 'handleGetNodes');
|
||||
|
|
|
@ -23,8 +23,7 @@ import {
|
|||
DataTableHeaderCell,
|
||||
DataTableDataFieldCell
|
||||
} from '../../../../js/components/ui/tables/DataTableCells';
|
||||
import DataTableColumn
|
||||
from '../../../../js/components/ui/tables/DataTableColumn';
|
||||
import DataTableColumn from '../../../../js/components/ui/tables/DataTableColumn';
|
||||
|
||||
const data = [
|
||||
{ uuid: 1, provision_state: 'failed' },
|
||||
|
|
|
@ -26,7 +26,8 @@ export default {
|
|||
environment_groups: [
|
||||
{
|
||||
title: null,
|
||||
description: 'Enable basic configuration required for OpenStack Deployment',
|
||||
description:
|
||||
'Enable basic configuration required for OpenStack Deployment',
|
||||
environments: {
|
||||
'overcloud-resource-registry-puppet.yaml': {
|
||||
file: 'overcloud-resource-registry-puppet.yaml',
|
||||
|
@ -43,12 +44,14 @@ export default {
|
|||
'environments/neutron-ml2-bigswitch.yaml': {
|
||||
file: 'environments/neutron-ml2-bigswitch.yaml',
|
||||
title: 'BigSwitch extensions',
|
||||
description: 'Enable Big Switch extensions, configured via puppet\n'
|
||||
description:
|
||||
'Enable Big Switch extensions, configured via puppet\n'
|
||||
},
|
||||
'environments/neutron-ml2-cisco-n1kv.yaml': {
|
||||
file: 'environments/neutron-ml2-cisco-n1kv.yaml',
|
||||
title: 'Cisco N1KV backend',
|
||||
description: 'Enable a Cisco N1KV backend, configured via puppet\n'
|
||||
description:
|
||||
'Enable a Cisco N1KV backend, configured via puppet\n'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,15 +16,10 @@
|
|||
|
||||
import { Map, fromJS } from 'immutable';
|
||||
|
||||
import EnvironmentConfigurationActions
|
||||
from '../../js/actions/EnvironmentConfigurationActions';
|
||||
import EnvironmentConfigurationConstants
|
||||
from '../../js/constants/EnvironmentConfigurationConstants';
|
||||
import environmentConfigurationReducer
|
||||
from '../../js/reducers/environmentConfigurationReducer';
|
||||
import {
|
||||
EnvironmentConfigurationState
|
||||
} from '../../js/immutableRecords/environmentConfiguration';
|
||||
import EnvironmentConfigurationActions from '../../js/actions/EnvironmentConfigurationActions';
|
||||
import EnvironmentConfigurationConstants from '../../js/constants/EnvironmentConfigurationConstants';
|
||||
import environmentConfigurationReducer from '../../js/reducers/environmentConfigurationReducer';
|
||||
import { EnvironmentConfigurationState } from '../../js/immutableRecords/environmentConfiguration';
|
||||
|
||||
const initialState = new EnvironmentConfigurationState();
|
||||
|
||||
|
@ -55,7 +50,8 @@ describe('environmentConfigurationReducer', () => {
|
|||
describe('fetchEnvironmentConfigurationPending', () => {
|
||||
let newState;
|
||||
let action = {
|
||||
type: EnvironmentConfigurationConstants.FETCH_ENVIRONMENT_CONFIGURATION_PENDING
|
||||
type:
|
||||
EnvironmentConfigurationConstants.FETCH_ENVIRONMENT_CONFIGURATION_PENDING
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
|
@ -16,13 +16,9 @@
|
|||
|
||||
import { Map, OrderedMap } from 'immutable';
|
||||
|
||||
import {
|
||||
WorkflowExecution
|
||||
} from '../../js/immutableRecords/workflowExecutions';
|
||||
import WorkflowExecutionsConstants
|
||||
from '../../js/constants/WorkflowExecutionsConstants';
|
||||
import workflowExecutionsReducer
|
||||
from '../../js/reducers/workflowExecutionsReducer';
|
||||
import { WorkflowExecution } from '../../js/immutableRecords/workflowExecutions';
|
||||
import WorkflowExecutionsConstants from '../../js/constants/WorkflowExecutionsConstants';
|
||||
import workflowExecutionsReducer from '../../js/reducers/workflowExecutionsReducer';
|
||||
import MistralConstants from '../../js/constants/MistralConstants';
|
||||
|
||||
const updatedAt = '1970-01-01T00:00:01Z';
|
||||
|
|
|
@ -23,9 +23,7 @@ import {
|
|||
FiltersInitialState
|
||||
} from '../../js/immutableRecords/filters';
|
||||
import { InitialPlanState, Plan } from '../../js/immutableRecords/plans';
|
||||
import {
|
||||
WorkflowExecution
|
||||
} from '../../js/immutableRecords/workflowExecutions';
|
||||
import { WorkflowExecution } from '../../js/immutableRecords/workflowExecutions';
|
||||
import MistralConstants from '../../js/constants/MistralConstants';
|
||||
|
||||
describe(' validations selectors', () => {
|
||||
|
|
|
@ -18,8 +18,7 @@ import { defineMessages } from 'react-intl';
|
|||
import { normalize, arrayOf } from 'normalizr';
|
||||
import yaml from 'js-yaml';
|
||||
|
||||
import EnvironmentConfigurationConstants
|
||||
from '../constants/EnvironmentConfigurationConstants';
|
||||
import EnvironmentConfigurationConstants from '../constants/EnvironmentConfigurationConstants';
|
||||
import { handleErrors } from './ErrorActions';
|
||||
import MistralApiService from '../services/MistralApiService';
|
||||
import NotificationActions from '../actions/NotificationActions';
|
||||
|
@ -30,7 +29,8 @@ import SwiftApiService from '../services/SwiftApiService';
|
|||
const messages = defineMessages({
|
||||
envConfigUpdatedNotificationMessage: {
|
||||
id: 'EnvironmentConfigurationActions.envConfigUpdatedNotificationMessage',
|
||||
defaultMessage: 'The Environment Configuration has been successfully updated.'
|
||||
defaultMessage:
|
||||
'The Environment Configuration has been successfully updated.'
|
||||
},
|
||||
envConfigUpdatedNotificationTitle: {
|
||||
id: 'EnvironmentConfigurationActions.envConfigUpdatedNotificationTitle',
|
||||
|
@ -48,8 +48,8 @@ export default {
|
|||
})
|
||||
)
|
||||
.then(response => {
|
||||
const entities = normalize(response, arrayOf(topicSchema))
|
||||
.entities || {};
|
||||
const entities =
|
||||
normalize(response, arrayOf(topicSchema)).entities || {};
|
||||
dispatch(this.fetchEnvironmentConfigurationSuccess(entities));
|
||||
})
|
||||
.catch(error => {
|
||||
|
@ -66,20 +66,23 @@ export default {
|
|||
|
||||
fetchEnvironmentConfigurationPending() {
|
||||
return {
|
||||
type: EnvironmentConfigurationConstants.FETCH_ENVIRONMENT_CONFIGURATION_PENDING
|
||||
type:
|
||||
EnvironmentConfigurationConstants.FETCH_ENVIRONMENT_CONFIGURATION_PENDING
|
||||
};
|
||||
},
|
||||
|
||||
fetchEnvironmentConfigurationSuccess(entities) {
|
||||
return {
|
||||
type: EnvironmentConfigurationConstants.FETCH_ENVIRONMENT_CONFIGURATION_SUCCESS,
|
||||
type:
|
||||
EnvironmentConfigurationConstants.FETCH_ENVIRONMENT_CONFIGURATION_SUCCESS,
|
||||
payload: entities
|
||||
};
|
||||
},
|
||||
|
||||
fetchEnvironmentConfigurationFailed(environment) {
|
||||
return {
|
||||
type: EnvironmentConfigurationConstants.FETCH_ENVIRONMENT_CONFIGURATION_FAILED
|
||||
type:
|
||||
EnvironmentConfigurationConstants.FETCH_ENVIRONMENT_CONFIGURATION_FAILED
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -128,20 +131,23 @@ export default {
|
|||
|
||||
updateEnvironmentConfigurationPending() {
|
||||
return {
|
||||
type: EnvironmentConfigurationConstants.UPDATE_ENVIRONMENT_CONFIGURATION_PENDING
|
||||
type:
|
||||
EnvironmentConfigurationConstants.UPDATE_ENVIRONMENT_CONFIGURATION_PENDING
|
||||
};
|
||||
},
|
||||
|
||||
updateEnvironmentConfigurationSuccess(enabledEnvironments) {
|
||||
return {
|
||||
type: EnvironmentConfigurationConstants.UPDATE_ENVIRONMENT_CONFIGURATION_SUCCESS,
|
||||
type:
|
||||
EnvironmentConfigurationConstants.UPDATE_ENVIRONMENT_CONFIGURATION_SUCCESS,
|
||||
payload: enabledEnvironments
|
||||
};
|
||||
},
|
||||
|
||||
updateEnvironmentConfigurationFailed(formErrors = [], formFieldErrors = {}) {
|
||||
return {
|
||||
type: EnvironmentConfigurationConstants.UPDATE_ENVIRONMENT_CONFIGURATION_FAILED,
|
||||
type:
|
||||
EnvironmentConfigurationConstants.UPDATE_ENVIRONMENT_CONFIGURATION_FAILED,
|
||||
payload: {
|
||||
formErrors,
|
||||
formFieldErrors
|
||||
|
@ -154,13 +160,13 @@ export default {
|
|||
dispatch(this.fetchEnvironmentPending(environmentPath));
|
||||
dispatch(SwiftApiService.getObject(planName, environmentPath))
|
||||
.then(response => {
|
||||
const {
|
||||
resource_registry,
|
||||
parameter_defaults
|
||||
} = yaml.safeLoad(response, {
|
||||
filename: environmentPath,
|
||||
json: true
|
||||
});
|
||||
const { resource_registry, parameter_defaults } = yaml.safeLoad(
|
||||
response,
|
||||
{
|
||||
filename: environmentPath,
|
||||
json: true
|
||||
}
|
||||
);
|
||||
dispatch(
|
||||
this.fetchEnvironmentSuccess({
|
||||
file: environmentPath,
|
||||
|
|
|
@ -34,9 +34,10 @@ export default {
|
|||
navigator.userLanguage;
|
||||
// If the locale contains the country but we can't find
|
||||
// messages for it then we only use the country part:
|
||||
language = locale.match(/^[A-Za-z]+-[A-Za-z]+$/) && !MESSAGES[locale]
|
||||
? locale.split('-')[0]
|
||||
: locale;
|
||||
language =
|
||||
locale.match(/^[A-Za-z]+-[A-Za-z]+$/) && !MESSAGES[locale]
|
||||
? locale.split('-')[0]
|
||||
: locale;
|
||||
}
|
||||
dispatch(this.chooseLanguage(language));
|
||||
};
|
||||
|
|
|
@ -143,8 +143,9 @@ export default {
|
|||
dispatch(this.requestPlan());
|
||||
return dispatch(SwiftApiService.getContainer(planName))
|
||||
.then(response => {
|
||||
const planFiles = normalize(response, arrayOf(planFileSchema))
|
||||
.entities.planFiles || {};
|
||||
const planFiles =
|
||||
normalize(response, arrayOf(planFileSchema)).entities.planFiles ||
|
||||
{};
|
||||
dispatch(this.receivePlan(planName, planFiles));
|
||||
})
|
||||
.catch(error => {
|
||||
|
|
|
@ -34,8 +34,8 @@ export default {
|
|||
})
|
||||
)
|
||||
.then(response => {
|
||||
const roles = normalize(response, arrayOf(roleSchema)).entities
|
||||
.roles || {};
|
||||
const roles =
|
||||
normalize(response, arrayOf(roleSchema)).entities.roles || {};
|
||||
dispatch(this.fetchRolesSuccess(roles));
|
||||
})
|
||||
.catch(error => {
|
||||
|
|
|
@ -46,8 +46,9 @@ export default {
|
|||
dispatch(this.fetchStacksPending());
|
||||
return dispatch(HeatApiService.getStacks())
|
||||
.then(response => {
|
||||
const stacks = normalize(response.stacks, arrayOf(stackSchema))
|
||||
.entities.stacks || {};
|
||||
const stacks =
|
||||
normalize(response.stacks, arrayOf(stackSchema)).entities.stacks ||
|
||||
{};
|
||||
dispatch(this.fetchStacksSuccess(stacks));
|
||||
})
|
||||
.catch(error => {
|
||||
|
@ -81,8 +82,9 @@ export default {
|
|||
dispatch(this.fetchResourcesPending());
|
||||
dispatch(HeatApiService.getResources(stackName, stackId))
|
||||
.then(({ resources }) => {
|
||||
const res = normalize(resources, arrayOf(stackResourceSchema))
|
||||
.entities.stackResources || {};
|
||||
const res =
|
||||
normalize(resources, arrayOf(stackResourceSchema)).entities
|
||||
.stackResources || {};
|
||||
dispatch(this.fetchResourcesSuccess(res));
|
||||
})
|
||||
.catch(error => {
|
||||
|
|
|
@ -32,8 +32,9 @@ export default {
|
|||
MistralApiService.runAction(MistralConstants.VALIDATIONS_LIST)
|
||||
)
|
||||
.then(response => {
|
||||
const validations = normalize(response, arrayOf(validationSchema))
|
||||
.entities.validations || {};
|
||||
const validations =
|
||||
normalize(response, arrayOf(validationSchema)).entities
|
||||
.validations || {};
|
||||
dispatch(this.fetchValidationsSuccess(validations));
|
||||
})
|
||||
.catch(error => {
|
||||
|
|
|
@ -18,11 +18,8 @@ import { normalize, arrayOf } from 'normalizr';
|
|||
|
||||
import { handleErrors } from './ErrorActions';
|
||||
import MistralApiService from '../services/MistralApiService';
|
||||
import WorkflowExecutionsConstants
|
||||
from '../constants/WorkflowExecutionsConstants';
|
||||
import {
|
||||
workflowExecutionSchema
|
||||
} from '../normalizrSchemas/workflowExecutions';
|
||||
import WorkflowExecutionsConstants from '../constants/WorkflowExecutionsConstants';
|
||||
import { workflowExecutionSchema } from '../normalizrSchemas/workflowExecutions';
|
||||
|
||||
export default {
|
||||
fetchWorkflowExecutions() {
|
||||
|
@ -30,10 +27,9 @@ export default {
|
|||
dispatch(this.fetchWorkflowExecutionsPending());
|
||||
return dispatch(MistralApiService.getWorkflowExecutions())
|
||||
.then(response => {
|
||||
const executions = normalize(
|
||||
response,
|
||||
arrayOf(workflowExecutionSchema)
|
||||
).entities.executions || {};
|
||||
const executions =
|
||||
normalize(response, arrayOf(workflowExecutionSchema)).entities
|
||||
.executions || {};
|
||||
dispatch(this.fetchWorkflowExecutionsSuccess(executions));
|
||||
})
|
||||
.catch(error => {
|
||||
|
|
|
@ -60,9 +60,11 @@ class AuthenticatedContent extends React.Component {
|
|||
<Route path="/nodes" component={Nodes} />
|
||||
<Route path="/plans/manage" component={Plans} />
|
||||
<Route path="/plans/:planName" component={DeploymentPlan} />
|
||||
{currentPlanName
|
||||
? <Redirect from="/" to={`/plans/${currentPlanName}`} />
|
||||
: <Redirect from="/" to="/plans/manage" />}
|
||||
{currentPlanName ? (
|
||||
<Redirect from="/" to={`/plans/${currentPlanName}`} />
|
||||
) : (
|
||||
<Redirect from="/" to="/plans/manage" />
|
||||
)}
|
||||
</Switch>
|
||||
</MainContent>
|
||||
</GlobalLoader>
|
||||
|
|
|
@ -65,11 +65,11 @@ class NavBar extends React.Component {
|
|||
_renderLanguageDropdown() {
|
||||
// Only include the I18nDropdown if there's more than one
|
||||
// language to choose from.
|
||||
return this.props.languages.size > 1
|
||||
? <li>
|
||||
<I18nDropdown />
|
||||
</li>
|
||||
: null;
|
||||
return this.props.languages.size > 1 ? (
|
||||
<li>
|
||||
<I18nDropdown />
|
||||
</li>
|
||||
) : null;
|
||||
}
|
||||
|
||||
_renderHelpDropdown() {
|
||||
|
|
|
@ -52,7 +52,8 @@ const messages = defineMessages({
|
|||
},
|
||||
downloadLogsMessage: {
|
||||
id: 'DebugScreen.downloadLogsMessage',
|
||||
defaultMessage: 'The file you requested is ready. Please click the button below to ' +
|
||||
defaultMessage:
|
||||
'The file you requested is ready. Please click the button below to ' +
|
||||
'download the export. You might need to right-click the button and choose ' +
|
||||
'"Save link as...".'
|
||||
},
|
||||
|
@ -102,19 +103,21 @@ class DebugScreen extends React.Component {
|
|||
return;
|
||||
}
|
||||
|
||||
return this.props.logsUrl
|
||||
? <div>
|
||||
<div>
|
||||
<FormattedMessage {...messages.downloadLogsMessage} />
|
||||
</div>
|
||||
<br />
|
||||
<a href={this.props.logsUrl} className="btn btn-success">
|
||||
<FormattedMessage {...messages.downloadLogs} />
|
||||
</a>
|
||||
return this.props.logsUrl ? (
|
||||
<div>
|
||||
<div>
|
||||
<FormattedMessage {...messages.downloadLogsMessage} />
|
||||
</div>
|
||||
: <div>
|
||||
<FormattedMessage {...messages.downloadError} />
|
||||
</div>;
|
||||
<br />
|
||||
<a href={this.props.logsUrl} className="btn btn-success">
|
||||
<FormattedMessage {...messages.downloadLogs} />
|
||||
</a>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<FormattedMessage {...messages.downloadError} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -50,7 +50,8 @@ const messages = defineMessages({
|
|||
},
|
||||
validationsWarningMessage: {
|
||||
id: 'DeploymentConfirmation.validationsWarningMessage',
|
||||
defaultMessage: 'It is highly recommended that you resolve all validation issues before ' +
|
||||
defaultMessage:
|
||||
'It is highly recommended that you resolve all validation issues before ' +
|
||||
'continuing.'
|
||||
}
|
||||
});
|
||||
|
@ -78,8 +79,9 @@ class DeploymentConfirmation extends React.Component {
|
|||
)}
|
||||
>
|
||||
<p>
|
||||
<strong><FormattedMessage {...messages.summary} /></strong>
|
||||
{' '}
|
||||
<strong>
|
||||
<FormattedMessage {...messages.summary} />
|
||||
</strong>{' '}
|
||||
{environmentSummary}
|
||||
</p>
|
||||
<ValidationsWarning
|
||||
|
@ -144,8 +146,7 @@ export const DeployButton = injectIntl(
|
|||
loaded={!isRequestingPlanDeploy}
|
||||
content={intl.formatMessage(messages.requestingDeploymentLoader)}
|
||||
>
|
||||
<span className="fa fa-cloud-upload" />
|
||||
{' '}
|
||||
<span className="fa fa-cloud-upload" />{' '}
|
||||
<FormattedMessage {...messages.deployButton} />
|
||||
</InlineLoader>
|
||||
</button>
|
||||
|
|
|
@ -21,9 +21,7 @@ import { ModalHeader, ModalTitle, ModalFooter } from 'react-bootstrap';
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
allPreDeploymentValidationsSuccessful
|
||||
} from '../../selectors/validations';
|
||||
import { allPreDeploymentValidationsSuccessful } from '../../selectors/validations';
|
||||
import DeploymentConfirmation from './DeploymentConfirmation';
|
||||
import DeploymentProgress from './DeploymentProgress';
|
||||
import DeploymentSuccess from './DeploymentSuccess';
|
||||
|
@ -33,9 +31,7 @@ import {
|
|||
getCurrentStack,
|
||||
getCurrentStackDeploymentProgress
|
||||
} from '../../selectors/stacks';
|
||||
import {
|
||||
getEnvironmentConfigurationSummary
|
||||
} from '../../selectors/environmentConfiguration';
|
||||
import { getEnvironmentConfigurationSummary } from '../../selectors/environmentConfiguration';
|
||||
import { Loader } from '../ui/Loader';
|
||||
import {
|
||||
CloseModalButton,
|
||||
|
|
|
@ -46,7 +46,9 @@ class DeploymentFailure extends React.Component {
|
|||
<InlineNotification type="error" title={status}>
|
||||
<p>{this.props.stack.stack_status_reason}</p>
|
||||
</InlineNotification>
|
||||
<h2><FormattedMessage {...messages.resources} /></h2>
|
||||
<h2>
|
||||
<FormattedMessage {...messages.resources} />
|
||||
</h2>
|
||||
<div className="flex-column">
|
||||
<StackResourcesTable
|
||||
isFetchingResources={!this.props.stackResourcesLoaded}
|
||||
|
|
|
@ -41,13 +41,13 @@ export default class DeploymentProgress extends React.Component {
|
|||
}
|
||||
|
||||
renderProgressBar() {
|
||||
return this.props.stack.stack_status === stackStates.CREATE_IN_PROGRESS
|
||||
? <ProgressBar
|
||||
value={this.props.deploymentProgress}
|
||||
label={this.props.deploymentProgress + '%'}
|
||||
labelPosition="topRight"
|
||||
/>
|
||||
: null;
|
||||
return this.props.stack.stack_status === stackStates.CREATE_IN_PROGRESS ? (
|
||||
<ProgressBar
|
||||
value={this.props.deploymentProgress}
|
||||
label={this.props.deploymentProgress + '%'}
|
||||
labelPosition="topRight"
|
||||
/>
|
||||
) : null;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -65,7 +65,9 @@ export default class DeploymentProgress extends React.Component {
|
|||
</div>
|
||||
{this.renderProgressBar()}
|
||||
</div>
|
||||
<h2><FormattedMessage {...messages.resources} /></h2>
|
||||
<h2>
|
||||
<FormattedMessage {...messages.resources} />
|
||||
</h2>
|
||||
<div className="flex-column">
|
||||
<StackResourcesTable
|
||||
isFetchingResources={!this.props.stackResourcesLoaded}
|
||||
|
|
|
@ -52,15 +52,23 @@ const OvercloudInfo = ({ intl, overcloudInfo }) => {
|
|||
|
||||
return (
|
||||
<div>
|
||||
<h4><FormattedMessage {...messages.overcloudInformationHeader} /></h4>
|
||||
<h4>
|
||||
<FormattedMessage {...messages.overcloudInformationHeader} />
|
||||
</h4>
|
||||
<Loader
|
||||
loaded={!!(ip && password)}
|
||||
content={intl.formatMessage(messages.loadingOvercloudInformation)}
|
||||
>
|
||||
<ul className="list">
|
||||
<li><FormattedMessage {...messages.overcloudIpAddress} /> {ip}</li>
|
||||
<li><FormattedMessage {...messages.username} /> admin</li>
|
||||
<li><FormattedMessage {...messages.password} /> {password}</li>
|
||||
<li>
|
||||
<FormattedMessage {...messages.overcloudIpAddress} /> {ip}
|
||||
</li>
|
||||
<li>
|
||||
<FormattedMessage {...messages.username} /> admin
|
||||
</li>
|
||||
<li>
|
||||
<FormattedMessage {...messages.password} /> {password}
|
||||
</li>
|
||||
</ul>
|
||||
</Loader>
|
||||
<br />
|
||||
|
|
|
@ -37,17 +37,14 @@ import {
|
|||
getNodeCountParametersByRole,
|
||||
getTotalAssignedNodesCount
|
||||
} from '../../selectors/nodesAssignment';
|
||||
import {
|
||||
getEnvironmentConfigurationSummary
|
||||
} from '../../selectors/environmentConfiguration';
|
||||
import { getEnvironmentConfigurationSummary } from '../../selectors/environmentConfiguration';
|
||||
import { getCurrentPlan } from '../../selectors/plans';
|
||||
import { getRoles } from '../../selectors/roles';
|
||||
import ConfigurePlanStep from './ConfigurePlanStep';
|
||||
import CurrentPlanActions from '../../actions/CurrentPlanActions';
|
||||
import { DeploymentPlanStep } from './DeploymentPlanStep';
|
||||
import DeployStep from './DeployStep';
|
||||
import EnvironmentConfigurationActions
|
||||
from '../../actions/EnvironmentConfigurationActions';
|
||||
import EnvironmentConfigurationActions from '../../actions/EnvironmentConfigurationActions';
|
||||
import HardwareStep from './HardwareStep';
|
||||
import NodesActions from '../../actions/NodesActions';
|
||||
import NotificationActions from '../../actions/NotificationActions';
|
||||
|
@ -83,7 +80,8 @@ const messages = defineMessages({
|
|||
},
|
||||
hardwareStepTooltip: {
|
||||
id: 'CurrentPlan.hardwareStepTooltip',
|
||||
defaultMessage: 'This step registers and introspects your nodes. Registration involves ' +
|
||||
defaultMessage:
|
||||
'This step registers and introspects your nodes. Registration involves ' +
|
||||
'defining the power management details of each node so that you so that the director can ' +
|
||||
'control them during the introspection and provisioning stages. After registration, you ' +
|
||||
'introspect the nodes, which identifies the hardware each node uses and builds a profile of ' +
|
||||
|
@ -92,13 +90,15 @@ const messages = defineMessages({
|
|||
},
|
||||
configurePlanStepTooltip: {
|
||||
id: 'CurrentPlan.configurePlanStepTooltip',
|
||||
defaultMessage: "This step allows you edit specific settings for the overcloud's network, " +
|
||||
defaultMessage:
|
||||
"This step allows you edit specific settings for the overcloud's network, " +
|
||||
'storage, and other certified plugins. Use this step to define your network isolation ' +
|
||||
'configuration and your backend storage settings.'
|
||||
},
|
||||
configureRolesStepTooltip: {
|
||||
id: 'CurrentPlan.configureRolesStepTooltip',
|
||||
defaultMessage: 'This step assigns and removes nodes from roles in your overcloud. On each ' +
|
||||
defaultMessage:
|
||||
'This step assigns and removes nodes from roles in your overcloud. On each ' +
|
||||
"role's selection dialog, you can tag available nodes into the role or untag nodes already " +
|
||||
'assigned to the role. Click "Assign Nodes" for a particular role to open the selection ' +
|
||||
'dialog and start assigning nodes. ' +
|
||||
|
@ -108,7 +108,8 @@ const messages = defineMessages({
|
|||
},
|
||||
deployStepTooltip: {
|
||||
id: 'CurrentPlan.deploymentStepTooltip',
|
||||
defaultMessage: 'This step performs the deployment of the overcloud. Once the deployment ' +
|
||||
defaultMessage:
|
||||
'This step performs the deployment of the overcloud. Once the deployment ' +
|
||||
'begins, the director tracks the progress and provides a report of each completed, running, ' +
|
||||
'or failed step. When the deployment completes, the director displays the current overcloud ' +
|
||||
'status and login details, which you use to interact with your overcloud. Click "Deploy" to ' +
|
||||
|
@ -329,8 +330,8 @@ export function mapStateToProps(state, props) {
|
|||
currentStackDeploymentProgress: getCurrentStackDeploymentProgress(state),
|
||||
environmentConfigurationLoaded: state.environmentConfiguration.loaded,
|
||||
environmentConfigurationSummary: getEnvironmentConfigurationSummary(state),
|
||||
isFetchingEnvironmentConfiguration: state.environmentConfiguration
|
||||
.isFetching,
|
||||
isFetchingEnvironmentConfiguration:
|
||||
state.environmentConfiguration.isFetching,
|
||||
isFetchingNodes: state.nodes.get('isFetching'),
|
||||
isFetchingParameters: state.parameters.isFetching,
|
||||
isFetchingRoles: state.roles.get('isFetching'),
|
||||
|
|
|
@ -66,8 +66,7 @@ export const DeployStep = ({
|
|||
loaded={!currentPlan.isRequestingPlanDeploy}
|
||||
content={intl.formatMessage(messages.requestingDeploy)}
|
||||
>
|
||||
<span className="fa fa-cloud-upload" />
|
||||
{' '}
|
||||
<span className="fa fa-cloud-upload" />{' '}
|
||||
<FormattedMessage {...messages.validateAndDeploy} />
|
||||
</InlineLoader>
|
||||
</Link>
|
||||
|
|
|
@ -21,8 +21,7 @@ import PropTypes from 'prop-types';
|
|||
import React from 'react';
|
||||
|
||||
import { checkRunningDeployment } from '../utils/checkRunningDeploymentHOC';
|
||||
import EnvironmentConfiguration
|
||||
from '../environment_configuration/EnvironmentConfiguration';
|
||||
import EnvironmentConfiguration from '../environment_configuration/EnvironmentConfiguration';
|
||||
import NavTab from '../ui/NavTab';
|
||||
import { CloseModalXButton, RoutedModal } from '../ui/Modals';
|
||||
import Parameters from '../parameters/Parameters';
|
||||
|
|
|
@ -54,8 +54,7 @@ class DeploymentFailure extends React.Component {
|
|||
<div>
|
||||
<InlineNotification type="error" title={status}>
|
||||
<p>
|
||||
{stack.stack_status_reason}
|
||||
{' '}
|
||||
{stack.stack_status_reason}{' '}
|
||||
<Link to={`/plans/${currentPlanName}/deployment-detail`}>
|
||||
<FormattedMessage {...messages.moreDetails} />
|
||||
</Link>
|
||||
|
|
|
@ -22,11 +22,11 @@ export const DeploymentPlanStep = ({ children, disabled, title, tooltip }) => {
|
|||
<li className={disabled ? 'disabled' : null}>
|
||||
<h3>
|
||||
<span>{title}</span>
|
||||
{tooltip
|
||||
? <span data-tooltip={tooltip} className="tooltip-right">
|
||||
<span className="pficon pficon-info" />
|
||||
</span>
|
||||
: null}
|
||||
{tooltip ? (
|
||||
<span data-tooltip={tooltip} className="tooltip-right">
|
||||
<span className="pficon pficon-info" />
|
||||
</span>
|
||||
) : null}
|
||||
</h3>
|
||||
{children}
|
||||
</li>
|
||||
|
|
|
@ -49,13 +49,13 @@ const messages = defineMessages({
|
|||
|
||||
class DeploymentProgress extends React.Component {
|
||||
renderProgressBar() {
|
||||
return this.props.stack.stack_status === stackStates.CREATE_IN_PROGRESS
|
||||
? <ProgressBar
|
||||
value={this.props.deploymentProgress}
|
||||
label={this.props.deploymentProgress + '%'}
|
||||
labelPosition="topRight"
|
||||
/>
|
||||
: null;
|
||||
return this.props.stack.stack_status === stackStates.CREATE_IN_PROGRESS ? (
|
||||
<ProgressBar
|
||||
value={this.props.deploymentProgress}
|
||||
label={this.props.deploymentProgress + '%'}
|
||||
labelPosition="topRight"
|
||||
/>
|
||||
) : null;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -73,8 +73,9 @@ class DeploymentProgress extends React.Component {
|
|||
</strong>
|
||||
);
|
||||
|
||||
const deleteButton = stack.stack_status !== stackStates.DELETE_IN_PROGRESS
|
||||
? <DeleteStackButton
|
||||
const deleteButton =
|
||||
stack.stack_status !== stackStates.DELETE_IN_PROGRESS ? (
|
||||
<DeleteStackButton
|
||||
content={formatMessage(messages.cancelDeployment)}
|
||||
buttonIconClass="fa fa-ban"
|
||||
deleteStack={deleteStack}
|
||||
|
@ -83,12 +84,14 @@ class DeploymentProgress extends React.Component {
|
|||
loaderContent={formatMessage(messages.requestingDeletion)}
|
||||
stack={stack}
|
||||
/>
|
||||
: null;
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
<span><FormattedMessage {...messages.deploymentInProgress} /> </span>
|
||||
<span>
|
||||
<FormattedMessage {...messages.deploymentInProgress} />{' '}
|
||||
</span>
|
||||
<Link to={`/plans/${currentPlanName}/deployment-detail`}>
|
||||
<FormattedMessage {...messages.viewInformation} />
|
||||
</Link>
|
||||
|
|
|
@ -41,7 +41,8 @@ const messages = defineMessages({
|
|||
availableNodesCount: {
|
||||
id: 'RoleCard.availableNodesCount',
|
||||
defaultMessage: 'of {count, number}',
|
||||
description: 'Used to display available nodes to assign, e.g. 1 of 2 Nodes Assigned'
|
||||
description:
|
||||
'Used to display available nodes to assign, e.g. 1 of 2 Nodes Assigned'
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -80,21 +81,23 @@ const RoleCard = ({
|
|||
<div className="card-pf-body">
|
||||
<div className="card-pf-utilization-details">
|
||||
<div className="node-picker-cell">
|
||||
{assignedNodesCountParameter
|
||||
? <Field
|
||||
component={NodePickerInput}
|
||||
increment={1}
|
||||
validate={validations}
|
||||
name={assignedNodesCountParameter.name}
|
||||
max={availableNodesCount}
|
||||
/>
|
||||
: <NodePickerInput
|
||||
increment={1}
|
||||
input={{ value: '-' }}
|
||||
meta={{ submitting: true }}
|
||||
max={availableNodesCount}
|
||||
min={0}
|
||||
/>}
|
||||
{assignedNodesCountParameter ? (
|
||||
<Field
|
||||
component={NodePickerInput}
|
||||
increment={1}
|
||||
validate={validations}
|
||||
name={assignedNodesCountParameter.name}
|
||||
max={availableNodesCount}
|
||||
/>
|
||||
) : (
|
||||
<NodePickerInput
|
||||
increment={1}
|
||||
input={{ value: '-' }}
|
||||
meta={{ submitting: true }}
|
||||
max={availableNodesCount}
|
||||
min={0}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<span className="card-pf-utilization-card-details-description">
|
||||
<span className="card-pf-utilization-card-details-line-1">
|
||||
|
|
|
@ -23,8 +23,7 @@ import PropTypes from 'prop-types';
|
|||
import React from 'react';
|
||||
|
||||
import { CloseModalButton } from '../ui/Modals';
|
||||
import EnvironmentConfigurationActions
|
||||
from '../../actions/EnvironmentConfigurationActions';
|
||||
import EnvironmentConfigurationActions from '../../actions/EnvironmentConfigurationActions';
|
||||
import EnvironmentConfigurationTopic from './EnvironmentConfigurationTopic';
|
||||
import { getCurrentPlanName } from '../../selectors/plans';
|
||||
import ModalFormErrorList from '../ui/forms/ModalFormErrorList';
|
||||
|
@ -208,9 +207,7 @@ class EnvironmentConfiguration extends React.Component {
|
|||
</ul>
|
||||
</div>
|
||||
<div className="col-sm-8">
|
||||
<div className="tab-content">
|
||||
{topics}
|
||||
</div>
|
||||
<div className="tab-content">{topics}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -293,10 +290,10 @@ export default injectIntl(
|
|||
);
|
||||
|
||||
/**
|
||||
* requiresEnvironments validation
|
||||
* Invalidates input if it is selected and environment it requires is not.
|
||||
* example: validations="requiredEnvironments:['some_environment.yaml']"
|
||||
*/
|
||||
* requiresEnvironments validation
|
||||
* Invalidates input if it is selected and environment it requires is not.
|
||||
* example: validations="requiredEnvironments:['some_environment.yaml']"
|
||||
*/
|
||||
Formsy.addValidationRule('requiredEnvironments', function(
|
||||
values,
|
||||
value,
|
||||
|
|
|
@ -40,7 +40,11 @@ export default class EnvironmentConfigurationTopic extends React.Component {
|
|||
const { description } = this.props;
|
||||
return (
|
||||
<fieldset className="environment-topic">
|
||||
{description && <p><i>{description}</i></p>}
|
||||
{description && (
|
||||
<p>
|
||||
<i>{description}</i>
|
||||
</p>
|
||||
)}
|
||||
{environmentGroups}
|
||||
</fieldset>
|
||||
);
|
||||
|
|
|
@ -139,7 +139,8 @@ class EnvironmentGroupHeading extends React.Component {
|
|||
if (this.props.title) {
|
||||
return (
|
||||
<h4>
|
||||
{this.props.title}<br />
|
||||
{this.props.title}
|
||||
<br />
|
||||
<small>{this.props.description}</small>
|
||||
</h4>
|
||||
);
|
||||
|
|
|
@ -40,15 +40,15 @@ class I18nDropdown extends React.Component {
|
|||
return languages
|
||||
.map((langName, langKey) => {
|
||||
const active = currentLanguage === langKey;
|
||||
return MESSAGES[langKey] || langKey === 'en'
|
||||
? <DropdownItem
|
||||
key={`lang-${langKey}`}
|
||||
active={active}
|
||||
onClick={this.props.chooseLanguage.bind(this, langKey)}
|
||||
>
|
||||
{langName}
|
||||
</DropdownItem>
|
||||
: null;
|
||||
return MESSAGES[langKey] || langKey === 'en' ? (
|
||||
<DropdownItem
|
||||
key={`lang-${langKey}`}
|
||||
active={active}
|
||||
onClick={this.props.chooseLanguage.bind(this, langKey)}
|
||||
>
|
||||
{langName}
|
||||
</DropdownItem>
|
||||
) : null;
|
||||
})
|
||||
.toList();
|
||||
}
|
||||
|
|
|
@ -65,7 +65,8 @@ const messages = defineMessages({
|
|||
},
|
||||
description: {
|
||||
id: 'Login.description',
|
||||
defaultMessage: 'This tool will walk you through the process of configuring and ' +
|
||||
defaultMessage:
|
||||
'This tool will walk you through the process of configuring and ' +
|
||||
'deploying an OpenStack environment.'
|
||||
}
|
||||
});
|
||||
|
@ -183,7 +184,9 @@ class Login extends React.Component {
|
|||
</div>
|
||||
<div className="col-sm-5 col-md-6 col-lg-7 details">
|
||||
<p>
|
||||
<strong><FormattedMessage {...messages.welcome} /></strong>
|
||||
<strong>
|
||||
<FormattedMessage {...messages.welcome} />
|
||||
</strong>
|
||||
<br />
|
||||
<FormattedMessage {...messages.description} />
|
||||
</p>
|
||||
|
|
|
@ -89,23 +89,37 @@ const NodeDrive = ({ drive }) => {
|
|||
<Row>
|
||||
<Col sm={11}>
|
||||
<dl className="dl-horizontal">
|
||||
<dt><FormattedMessage {...messages.model} /></dt>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.model} />
|
||||
</dt>
|
||||
<dd>{drive.model || <FormattedMessage {...messages.na} />}</dd>
|
||||
<dt><FormattedMessage {...messages.serial} /></dt>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.serial} />
|
||||
</dt>
|
||||
<dd>{drive.serial || <FormattedMessage {...messages.na} />}</dd>
|
||||
<dt><FormattedMessage {...messages.vendor} /></dt>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.vendor} />
|
||||
</dt>
|
||||
<dd>{drive.vendor || <FormattedMessage {...messages.na} />}</dd>
|
||||
<dt><FormattedMessage {...messages.wwn} /></dt>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.wwn} />
|
||||
</dt>
|
||||
<dd>{drive.wwn || <FormattedMessage {...messages.na} />}</dd>
|
||||
<dt><FormattedMessage {...messages.wwnVendorExtension} /></dt>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.wwnVendorExtension} />
|
||||
</dt>
|
||||
<dd>
|
||||
{drive.wwn_vendor_extension ||
|
||||
<FormattedMessage {...messages.na} />}
|
||||
{drive.wwn_vendor_extension || (
|
||||
<FormattedMessage {...messages.na} />
|
||||
)}
|
||||
</dd>
|
||||
<dt><FormattedMessage {...messages.wwnWithExtension} /></dt>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.wwnWithExtension} />
|
||||
</dt>
|
||||
<dd>
|
||||
{drive.wwn_with_extension ||
|
||||
<FormattedMessage {...messages.na} />}
|
||||
{drive.wwn_with_extension || (
|
||||
<FormattedMessage {...messages.na} />
|
||||
)}
|
||||
</dd>
|
||||
</dl>
|
||||
</Col>
|
||||
|
|
|
@ -67,15 +67,17 @@ class Nodes extends React.Component {
|
|||
}
|
||||
|
||||
renderContentView() {
|
||||
return this.props.contentView === 'table'
|
||||
? <NodesTableView />
|
||||
: <NodesListForm>
|
||||
<NodesListView
|
||||
fetchNodeIntrospectionData={this.props.fetchNodeIntrospectionData}
|
||||
nodes={this.props.nodes}
|
||||
nodesInProgress={this.props.nodesInProgress}
|
||||
/>
|
||||
</NodesListForm>;
|
||||
return this.props.contentView === 'table' ? (
|
||||
<NodesTableView />
|
||||
) : (
|
||||
<NodesListForm>
|
||||
<NodesListView
|
||||
fetchNodeIntrospectionData={this.props.fetchNodeIntrospectionData}
|
||||
nodes={this.props.nodes}
|
||||
nodesInProgress={this.props.nodesInProgress}
|
||||
/>
|
||||
</NodesListForm>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -107,7 +109,9 @@ class Nodes extends React.Component {
|
|||
<FormattedMessage {...messages.registerNodes} />
|
||||
</Link>
|
||||
</div>
|
||||
<h1><FormattedMessage {...messages.nodes} /></h1>
|
||||
<h1>
|
||||
<FormattedMessage {...messages.nodes} />
|
||||
</h1>
|
||||
</div>
|
||||
<Loader
|
||||
loaded={this.props.nodesLoaded}
|
||||
|
|
|
@ -103,26 +103,29 @@ class NodeExtendedInfo extends React.Component {
|
|||
if (node.getIn(['introspectionData', 'interfaces']).isEmpty()) {
|
||||
return (
|
||||
<dl>
|
||||
<dt><FormattedMessage {...messages.macAddresses} /></dt>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.macAddresses} />
|
||||
</dt>
|
||||
{node.get('macs').map(mac => <dd key={mac}>{mac}</dd>)}
|
||||
</dl>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<dl>
|
||||
<dt><FormattedMessage {...messages.interfaces} /></dt>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.interfaces} />
|
||||
</dt>
|
||||
<dd>
|
||||
{node
|
||||
.getIn(['introspectionData', 'interfaces'])
|
||||
.map((ifc, k) => {
|
||||
return (
|
||||
<div key={k}>
|
||||
{k}
|
||||
{' '} - {' '}
|
||||
{k} -{' '}
|
||||
<span title={intl.formatMessage(messages.macAddress)}>
|
||||
{ifc.get('mac')}
|
||||
</span>
|
||||
{' '} | {' '}
|
||||
</span>{' '}
|
||||
|{' '}
|
||||
<span title={intl.formatMessage(messages.ipAddress)}>
|
||||
{ifc.get('ip')}
|
||||
</span>
|
||||
|
@ -140,58 +143,71 @@ class NodeExtendedInfo extends React.Component {
|
|||
renderBios() {
|
||||
const bios = this.props.node.getIn(['introspectionData', 'bios']);
|
||||
return (
|
||||
!bios.isEmpty() &&
|
||||
<div>
|
||||
<dt><FormattedMessage {...messages.bios} /></dt>
|
||||
<dd className="NodeExtendedInfo__bios">
|
||||
{bios
|
||||
.map((i, k) => <span key={k} title={startCase(k)}>{i} </span>)
|
||||
.toList()}
|
||||
</dd>
|
||||
</div>
|
||||
!bios.isEmpty() && (
|
||||
<div>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.bios} />
|
||||
</dt>
|
||||
<dd className="NodeExtendedInfo__bios">
|
||||
{bios
|
||||
.map((i, k) => (
|
||||
<span key={k} title={startCase(k)}>
|
||||
{i}{' '}
|
||||
</span>
|
||||
))
|
||||
.toList()}
|
||||
</dd>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
renderRootDisk() {
|
||||
const rootDisk = this.props.node.getIn(['introspectionData', 'rootDisk']);
|
||||
return (
|
||||
rootDisk &&
|
||||
<div>
|
||||
<dt><FormattedMessage {...messages.rootDisk} /></dt>
|
||||
<dd className="NodeExtendedInfo__rootDisk">{rootDisk}</dd>
|
||||
</div>
|
||||
rootDisk && (
|
||||
<div>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.rootDisk} />
|
||||
</dt>
|
||||
<dd className="NodeExtendedInfo__rootDisk">{rootDisk}</dd>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
renderProduct() {
|
||||
const product = this.props.node.getIn(['introspectionData', 'product']);
|
||||
return (
|
||||
!product.isEmpty() &&
|
||||
<div>
|
||||
<dt><FormattedMessage {...messages.product} /></dt>
|
||||
<dd>
|
||||
<span
|
||||
className="NodeExtendedInfo__productName"
|
||||
title={this.props.intl.formatMessage(messages.productName)}
|
||||
>
|
||||
{product.get('name')}
|
||||
</span>
|
||||
{' '} - {' '}
|
||||
<span
|
||||
className="NodeExtendedInfo__productVendor"
|
||||
title={this.props.intl.formatMessage(messages.productVendor)}
|
||||
>
|
||||
{product.get('vendor')}
|
||||
</span>
|
||||
{' '} | {' '}
|
||||
<span
|
||||
className="NodeExtendedInfo__productVersion"
|
||||
title={this.props.intl.formatMessage(messages.productVersion)}
|
||||
>
|
||||
{product.get('version')}
|
||||
</span>
|
||||
</dd>
|
||||
</div>
|
||||
!product.isEmpty() && (
|
||||
<div>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.product} />
|
||||
</dt>
|
||||
<dd>
|
||||
<span
|
||||
className="NodeExtendedInfo__productName"
|
||||
title={this.props.intl.formatMessage(messages.productName)}
|
||||
>
|
||||
{product.get('name')}
|
||||
</span>{' '}
|
||||
-{' '}
|
||||
<span
|
||||
className="NodeExtendedInfo__productVendor"
|
||||
title={this.props.intl.formatMessage(messages.productVendor)}
|
||||
>
|
||||
{product.get('vendor')}
|
||||
</span>{' '}
|
||||
|{' '}
|
||||
<span
|
||||
className="NodeExtendedInfo__productVersion"
|
||||
title={this.props.intl.formatMessage(messages.productVersion)}
|
||||
>
|
||||
{product.get('version')}
|
||||
</span>
|
||||
</dd>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -201,13 +217,14 @@ class NodeExtendedInfo extends React.Component {
|
|||
'kernelVersion'
|
||||
]);
|
||||
return (
|
||||
kernelVersion &&
|
||||
<div>
|
||||
<dt><FormattedMessage {...messages.kernel} /></dt>
|
||||
<dd className="NodeExtendedInfo__kernelVersion">
|
||||
{kernelVersion}
|
||||
</dd>
|
||||
</div>
|
||||
kernelVersion && (
|
||||
<div>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.kernel} />
|
||||
</dt>
|
||||
<dd className="NodeExtendedInfo__kernelVersion">{kernelVersion}</dd>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -217,15 +234,21 @@ class NodeExtendedInfo extends React.Component {
|
|||
<Row className="NodeExtendedInfo__extendedInfoRow">
|
||||
<Col lg={4} md={6}>
|
||||
<dl className="dl-horizontal dl-horizontal-condensed">
|
||||
<dt><FormattedMessage {...messages.uuid} /></dt>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.uuid} />
|
||||
</dt>
|
||||
<dd className="NodeExtendedInfo__uuid">{node.get('uuid')}</dd>
|
||||
<dt><FormattedMessage {...messages.registered} /></dt>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.registered} />
|
||||
</dt>
|
||||
<dd className="NodeExtendedInfo__registered">
|
||||
<FormattedDate value={node.get('created_at')} />
|
||||
|
||||
<FormattedTime value={node.get('created_at')} />
|
||||
</dd>
|
||||
<dt><FormattedMessage {...messages.architecture} /></dt>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.architecture} />
|
||||
</dt>
|
||||
<dd className="NodeExtendedInfo__architecture">
|
||||
{node.getIn(['properties', 'cpu_arch'])}
|
||||
</dd>
|
||||
|
@ -237,10 +260,10 @@ class NodeExtendedInfo extends React.Component {
|
|||
</Col>
|
||||
<Col lg={4} md={6}>
|
||||
<dl className="dl-horizontal dl-horizontal-condensed">
|
||||
<dt><FormattedMessage {...messages.driver} /></dt>
|
||||
<dd className="NodeExtendedInfo__driver">
|
||||
{node.get('driver')}
|
||||
</dd>
|
||||
<dt>
|
||||
<FormattedMessage {...messages.driver} />
|
||||
</dt>
|
||||
<dd className="NodeExtendedInfo__driver">{node.get('driver')}</dd>
|
||||
{node
|
||||
.get('driver_info')
|
||||
.map((dInfo, key) => (
|
||||
|
|
|
@ -75,12 +75,13 @@ export const NodeListItem = ({
|
|||
/>
|
||||
}
|
||||
actions={
|
||||
node.getIn(['introspectionStatus', 'state']) === 'finished' &&
|
||||
node.getIn(['introspectionStatus', 'state']) === 'finished' && (
|
||||
<DropdownKebab id={`${node.get('uuid')}Actions`} pullRight>
|
||||
<MenuItemLink to={`/nodes/${node.get('uuid')}/drives`}>
|
||||
<FormattedMessage {...messages.manageDrives} />
|
||||
</MenuItemLink>
|
||||
</DropdownKebab>
|
||||
)
|
||||
}
|
||||
leftContent={
|
||||
<ListViewIcon
|
||||
|
@ -137,9 +138,7 @@ export const NodeListItem = ({
|
|||
</ListViewInfoItem>,
|
||||
<ListViewInfoItem key="memory" className="NodeListItem__memorySize">
|
||||
<span className="pficon pficon-memory" />
|
||||
<strong>
|
||||
{node.getIn(['properties', 'memory_mb'], '-')}
|
||||
</strong>
|
||||
<strong>{node.getIn(['properties', 'memory_mb'], '-')}</strong>
|
||||
|
||||
<FormattedMessage {...messages.ram} />
|
||||
</ListViewInfoItem>,
|
||||
|
|
|
@ -85,16 +85,17 @@ export const NodeProvisionState = ({
|
|||
...rest
|
||||
}) => (
|
||||
<span {...rest}>
|
||||
<strong><FormattedMessage {...messages.provisionState} /></strong>
|
||||
{targetProvisionState
|
||||
? <span>
|
||||
{provisionState}
|
||||
{' '}
|
||||
<span className="fa fa-long-arrow-right" />
|
||||
{' '}
|
||||
{targetProvisionState}
|
||||
</span>
|
||||
: provisionState}
|
||||
<strong>
|
||||
<FormattedMessage {...messages.provisionState} />
|
||||
</strong>
|
||||
{targetProvisionState ? (
|
||||
<span>
|
||||
{provisionState} <span className="fa fa-long-arrow-right" />{' '}
|
||||
{targetProvisionState}
|
||||
</span>
|
||||
) : (
|
||||
provisionState
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
NodeProvisionState.propTypes = {
|
||||
|
@ -107,7 +108,9 @@ export const NodeIntrospectionStatus = ({
|
|||
...rest
|
||||
}) => (
|
||||
<span title={error} {...rest}>
|
||||
<strong><FormattedMessage {...messages.introspectionState} /></strong>
|
||||
<strong>
|
||||
<FormattedMessage {...messages.introspectionState} />
|
||||
</strong>
|
||||
{state}
|
||||
</span>
|
||||
);
|
||||
|
|
|
@ -32,7 +32,8 @@ const messages = defineMessages({
|
|||
},
|
||||
operationInProgress: {
|
||||
id: 'NodesListForm.operationInProgressValidationMessage',
|
||||
defaultMessage: 'There is an operation in progress on some of the selected Nodes'
|
||||
defaultMessage:
|
||||
'There is an operation in progress on some of the selected Nodes'
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -303,11 +303,7 @@ export default injectIntl(NodesTable);
|
|||
|
||||
export const NodesTableMaintenanceCell = props => {
|
||||
const value = _.result(props.data[props.rowIndex], props.field).toString();
|
||||
return (
|
||||
<DataTableCell {...props}>
|
||||
{value}
|
||||
</DataTableCell>
|
||||
);
|
||||
return <DataTableCell {...props}>{value}</DataTableCell>;
|
||||
};
|
||||
NodesTableMaintenanceCell.propTypes = {
|
||||
data: PropTypes.array.isRequired,
|
||||
|
@ -317,11 +313,7 @@ NodesTableMaintenanceCell.propTypes = {
|
|||
|
||||
export const NodesTableMacsCell = props => {
|
||||
const value = _.result(props.data[props.rowIndex], props.field).join(', ');
|
||||
return (
|
||||
<DataTableCell {...props}>
|
||||
{value}
|
||||
</DataTableCell>
|
||||
);
|
||||
return <DataTableCell {...props}>{value}</DataTableCell>;
|
||||
};
|
||||
NodesTableMacsCell.propTypes = {
|
||||
data: PropTypes.array.isRequired,
|
||||
|
|
|
@ -47,7 +47,8 @@ const messages = defineMessages({
|
|||
provideNodes: {
|
||||
id: 'NodesTableView.provideNodes',
|
||||
defaultMessage: 'Provide Nodes',
|
||||
description: '"Providing" the nodes changes the provisioning state to "available" so that ' +
|
||||
description:
|
||||
'"Providing" the nodes changes the provisioning state to "available" so that ' +
|
||||
'they can be used in a deployment.'
|
||||
},
|
||||
deleteNodes: {
|
||||
|
@ -238,7 +239,8 @@ class NodesTableView extends React.Component {
|
|||
availableProfiles={this.props.availableProfiles.toArray()}
|
||||
onProfileSelected={this.onTagNodesSubmit.bind(this)}
|
||||
onCancel={() =>
|
||||
this.setState({ showTagNodesModal: false, submitParameters: {} })}
|
||||
this.setState({ showTagNodesModal: false, submitParameters: {} })
|
||||
}
|
||||
show={this.state.showTagNodesModal}
|
||||
/>
|
||||
</Formsy.Form>
|
||||
|
|
|
@ -60,7 +60,8 @@ const messages = defineMessages({
|
|||
},
|
||||
nonFilteredToolbarResults: {
|
||||
id: 'NodesToolbar.nonFilteredToolbarResults',
|
||||
defaultMessage: '{totalCount, number} {totalCount, plural, one {Node} other {Nodes}}'
|
||||
defaultMessage:
|
||||
'{totalCount, number} {totalCount, plural, one {Node} other {Nodes}}'
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -89,7 +90,8 @@ class NodesToolbar extends React.Component {
|
|||
id="NodesToolbar_toolbarFiltersForm"
|
||||
form="nodesToolbarFilter"
|
||||
formatSelectValue={value =>
|
||||
intl.formatMessage(nodeColumnMessages[value])}
|
||||
intl.formatMessage(nodeColumnMessages[value])
|
||||
}
|
||||
initialValues={{ filterBy: 'name' }}
|
||||
onSubmit={addActiveFilter}
|
||||
options={{
|
||||
|
|
|
@ -36,7 +36,8 @@ const messages = defineMessages({
|
|||
},
|
||||
disabledButtonsWarning: {
|
||||
id: 'NodesToolbarActions.disabledButtonsWarning',
|
||||
defaultMessage: 'You need to select Nodes first, or there is an operation already in ' +
|
||||
defaultMessage:
|
||||
'You need to select Nodes first, or there is an operation already in ' +
|
||||
'progress on some of the selected Nodes.'
|
||||
},
|
||||
introspectNodes: {
|
||||
|
@ -50,13 +51,15 @@ const messages = defineMessages({
|
|||
provideNodes: {
|
||||
id: 'NodesToolbarActions.provideNodes',
|
||||
defaultMessage: 'Provide Nodes',
|
||||
description: '"Providing" the nodes changes the provisioning state to "available" so that ' +
|
||||
description:
|
||||
'"Providing" the nodes changes the provisioning state to "available" so that ' +
|
||||
'they can be used in a deployment.'
|
||||
},
|
||||
manageNodes: {
|
||||
id: 'NodesToolbarActions.manageNodes',
|
||||
defaultMessage: 'Manage Nodes',
|
||||
description: '"Managing" the nodes changes the provisioning state to "manageable" so that ' +
|
||||
description:
|
||||
'"Managing" the nodes changes the provisioning state to "manageable" so that ' +
|
||||
'they can be introspected.'
|
||||
},
|
||||
deleteNodes: {
|
||||
|
@ -98,68 +101,64 @@ class NodesToolbarActions extends React.Component {
|
|||
// TODO(jtomasek): include proper error message from the form accessed via getFormSyncErrors
|
||||
// selector once the 'error' is available via selector
|
||||
// https://github.com/erikras/redux-form/issues/2872
|
||||
(
|
||||
<FormGroup
|
||||
title={
|
||||
disabled ? intl.formatMessage(messages.disabledButtonsWarning) : ''
|
||||
}
|
||||
<FormGroup
|
||||
title={
|
||||
disabled ? intl.formatMessage(messages.disabledButtonsWarning) : ''
|
||||
}
|
||||
>
|
||||
<Button
|
||||
id="NodesToolbarActions__introspectNodesAction"
|
||||
disabled={this.props.disabled}
|
||||
onClick={this.submitForm.bind(this, 'introspect')}
|
||||
>
|
||||
<Button
|
||||
id="NodesToolbarActions__introspectNodesAction"
|
||||
<FormattedMessage {...messages.introspectNodes} />
|
||||
</Button>
|
||||
<Button
|
||||
id="NodesToolbarActions__provideNodesAction"
|
||||
disabled={this.props.disabled}
|
||||
onClick={this.submitForm.bind(this, 'provide')}
|
||||
>
|
||||
<FormattedMessage {...messages.provideNodes} />
|
||||
</Button>
|
||||
<DropdownKebab id="NodesToolbarActions__nodesActionsKebab" pullRight>
|
||||
<MenuItem
|
||||
id="NodesToolbarActions__manageNodesAction"
|
||||
disabled={this.props.disabled}
|
||||
onClick={this.submitForm.bind(this, 'introspect')}
|
||||
onSelect={this.submitForm.bind(this, 'manage')}
|
||||
>
|
||||
<FormattedMessage {...messages.introspectNodes} />
|
||||
</Button>
|
||||
<Button
|
||||
id="NodesToolbarActions__provideNodesAction"
|
||||
<FormattedMessage {...messages.manageNodes} />
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
id="NodesToolbarActions__tagNodesAction"
|
||||
disabled={this.props.disabled}
|
||||
onClick={this.submitForm.bind(this, 'provide')}
|
||||
onSelect={() => this.setState({ showTagNodesModal: true })}
|
||||
>
|
||||
<FormattedMessage {...messages.provideNodes} />
|
||||
</Button>
|
||||
<DropdownKebab id="NodesToolbarActions__nodesActionsKebab" pullRight>
|
||||
<MenuItem
|
||||
id="NodesToolbarActions__manageNodesAction"
|
||||
disabled={this.props.disabled}
|
||||
onSelect={this.submitForm.bind(this, 'manage')}
|
||||
>
|
||||
<FormattedMessage {...messages.manageNodes} />
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
id="NodesToolbarActions__tagNodesAction"
|
||||
disabled={this.props.disabled}
|
||||
onSelect={() => this.setState({ showTagNodesModal: true })}
|
||||
>
|
||||
<FormattedMessage {...messages.tagNodes} />
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
id="NodesToolbarActions__deleteNodesAction"
|
||||
className="bg-danger"
|
||||
disabled={this.props.disabled}
|
||||
onSelect={() => this.setState({ showDeleteModal: true })}
|
||||
>
|
||||
<FormattedMessage {...messages.deleteNodes} />
|
||||
</MenuItem>
|
||||
</DropdownKebab>
|
||||
<ConfirmationModal
|
||||
show={this.state.showDeleteModal}
|
||||
title={this.props.intl.formatMessage(
|
||||
messages.deleteNodesModalTitle
|
||||
)}
|
||||
question={this.props.intl.formatMessage(
|
||||
messages.deleteNodesModalMessage
|
||||
)}
|
||||
onConfirm={() => this.deleteNodes('delete')}
|
||||
onCancel={() => this.setState({ showDeleteModal: false })}
|
||||
/>
|
||||
<TagNodesModal
|
||||
onProfileSelected={this.tagNodes.bind(this)}
|
||||
onCancel={() => this.setState({ showTagNodesModal: false })}
|
||||
show={this.state.showTagNodesModal}
|
||||
/>
|
||||
</FormGroup>
|
||||
)
|
||||
<FormattedMessage {...messages.tagNodes} />
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
id="NodesToolbarActions__deleteNodesAction"
|
||||
className="bg-danger"
|
||||
disabled={this.props.disabled}
|
||||
onSelect={() => this.setState({ showDeleteModal: true })}
|
||||
>
|
||||
<FormattedMessage {...messages.deleteNodes} />
|
||||
</MenuItem>
|
||||
</DropdownKebab>
|
||||
<ConfirmationModal
|
||||
show={this.state.showDeleteModal}
|
||||
title={this.props.intl.formatMessage(messages.deleteNodesModalTitle)}
|
||||
question={this.props.intl.formatMessage(
|
||||
messages.deleteNodesModalMessage
|
||||
)}
|
||||
onConfirm={() => this.deleteNodes('delete')}
|
||||
onCancel={() => this.setState({ showDeleteModal: false })}
|
||||
/>
|
||||
<TagNodesModal
|
||||
onProfileSelected={this.tagNodes.bind(this)}
|
||||
onCancel={() => this.setState({ showTagNodesModal: false })}
|
||||
show={this.state.showTagNodesModal}
|
||||
/>
|
||||
</FormGroup>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,8 +38,7 @@ const NodeTab = ({
|
|||
}) => (
|
||||
<Tab isActive={isActive}>
|
||||
<a className="link" onClick={selectNode}>
|
||||
<span className={cx('pficon', { 'pficon-error-circle-o': invalid })} />
|
||||
{' '}
|
||||
<span className={cx('pficon', { 'pficon-error-circle-o': invalid })} />{' '}
|
||||
{node.name ||
|
||||
(node.pm_addr &&
|
||||
node.pm_addr + (node.pm_port ? `:${node.pm_port}` : '')) ||
|
||||
|
|
|
@ -35,7 +35,8 @@ const messages = defineMessages({
|
|||
},
|
||||
nodeNameRegexp: {
|
||||
id: 'RegisterNodeForm.nodeNameRegexp',
|
||||
defaultMessage: 'Name may only consist of RFC3986 unreserved characters: alphanumeric, hyphen (-),' +
|
||||
defaultMessage:
|
||||
'Name may only consist of RFC3986 unreserved characters: alphanumeric, hyphen (-),' +
|
||||
' period (.), underscore (_) and tilde (~) characters.'
|
||||
},
|
||||
nodeNameMaxLength: {
|
||||
|
@ -92,7 +93,8 @@ const messages = defineMessages({
|
|||
},
|
||||
macAddressesDescription: {
|
||||
id: 'RegisterNodeForm.macAddressesDescription',
|
||||
defaultMessage: 'If you are specifying multiple MAC Addresses, please enter a comma separated list. (e.g. aa:bb:cc:dd:ee:ff,12:34:56:78:90:xx,do:re:mi:fa:so:ra)'
|
||||
defaultMessage:
|
||||
'If you are specifying multiple MAC Addresses, please enter a comma separated list. (e.g. aa:bb:cc:dd:ee:ff,12:34:56:78:90:xx,do:re:mi:fa:so:ra)'
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -114,7 +116,9 @@ const RegisterNodeFields = ({
|
|||
}) => {
|
||||
return (
|
||||
<div>
|
||||
<h4><FormattedMessage {...messages.nodeDetail} /></h4>
|
||||
<h4>
|
||||
<FormattedMessage {...messages.nodeDetail} />
|
||||
</h4>
|
||||
<Fieldset legend={formatMessage(messages.general)}>
|
||||
<Field
|
||||
name={`${node}.name`}
|
||||
|
|
|
@ -203,8 +203,7 @@ class RegisterNodesDialog extends React.Component {
|
|||
<div className="col-sm-4 col-lg-3 sidebar-pf sidebar-pf-left">
|
||||
<div className="nav-stacked-actions">
|
||||
<Button onClick={e => this.addNode()}>
|
||||
<span className="fa fa-plus" />
|
||||
{' '}
|
||||
<span className="fa fa-plus" />{' '}
|
||||
<FormattedMessage {...messages.addNew} />
|
||||
</Button>
|
||||
<FormattedMessage {...messages.or} />
|
||||
|
@ -268,9 +267,11 @@ function mapStateToProps(state) {
|
|||
syncErrors: getFormSyncErrors('registerNodesForm')(state),
|
||||
invalid: isInvalid('registerNodesForm')(state),
|
||||
pristine: isPristine('registerNodesForm')(state),
|
||||
nodesToRegister: (getFormValues('registerNodesForm')(state) || {
|
||||
nodes: []
|
||||
}).nodes,
|
||||
nodesToRegister: (
|
||||
getFormValues('registerNodesForm')(state) || {
|
||||
nodes: []
|
||||
}
|
||||
).nodes,
|
||||
submitting: isSubmitting('registerNodesForm')(state)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -66,22 +66,23 @@ const RegisterNodesForm = ({
|
|||
selectedNodeIndex
|
||||
}) => (
|
||||
<Form onSubmit={handleSubmit} horizontal>
|
||||
{error &&
|
||||
<InlineNotification>
|
||||
{error}
|
||||
</InlineNotification>}
|
||||
{selectedNodeIndex !== -1
|
||||
? <FieldArray
|
||||
name="nodes"
|
||||
component={RegisterNodesTabPanes}
|
||||
selectedNodeIndex={selectedNodeIndex}
|
||||
/>
|
||||
: <BlankSlate
|
||||
iconClass="fa fa-cubes"
|
||||
title={formatMessage(messages.noNodesToRegister)}
|
||||
>
|
||||
<p><FormattedMessage {...messages.addANodeManually} /></p>
|
||||
</BlankSlate>}
|
||||
{error && <InlineNotification>{error}</InlineNotification>}
|
||||
{selectedNodeIndex !== -1 ? (
|
||||
<FieldArray
|
||||
name="nodes"
|
||||
component={RegisterNodesTabPanes}
|
||||
selectedNodeIndex={selectedNodeIndex}
|
||||
/>
|
||||
) : (
|
||||
<BlankSlate
|
||||
iconClass="fa fa-cubes"
|
||||
title={formatMessage(messages.noNodesToRegister)}
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage {...messages.addANodeManually} />
|
||||
</p>
|
||||
</BlankSlate>
|
||||
)}
|
||||
</Form>
|
||||
);
|
||||
RegisterNodesForm.propTypes = {
|
||||
|
|
|
@ -34,7 +34,8 @@ const messages = defineMessages({
|
|||
noRolesInfo: {
|
||||
id: 'TagNodesForm.noRolesInfo',
|
||||
defaultMessage: '{link} to select profiles which match available Roles',
|
||||
description: 'A second part of noRolesInfo message - rest of the text after link'
|
||||
description:
|
||||
'A second part of noRolesInfo message - rest of the text after link'
|
||||
},
|
||||
confirm: {
|
||||
id: 'TagNodesForm.confirm',
|
||||
|
@ -104,7 +105,9 @@ class TagNodesForm extends React.Component {
|
|||
return this.props.profiles
|
||||
.map((profile, index) => <option key={index}>{profile}</option>)
|
||||
.concat([
|
||||
<option key="spacer1" value="spacer" disabled>──────────</option>,
|
||||
<option key="spacer1" value="spacer" disabled>
|
||||
──────────
|
||||
</option>,
|
||||
<option key="noProfile" value="">
|
||||
{this.props.intl.formatMessage(messages.noProfileOption)}
|
||||
</option>,
|
||||
|
@ -126,7 +129,7 @@ class TagNodesForm extends React.Component {
|
|||
onInvalid={this.disableButton.bind(this)}
|
||||
>
|
||||
<div className="modal-body">
|
||||
{roles.isEmpty() &&
|
||||
{roles.isEmpty() && (
|
||||
<InlineNotification type="info">
|
||||
<FormattedMessage
|
||||
{...messages.noRolesInfo}
|
||||
|
@ -138,7 +141,8 @@ class TagNodesForm extends React.Component {
|
|||
)
|
||||
}}
|
||||
/>
|
||||
</InlineNotification>}
|
||||
</InlineNotification>
|
||||
)}
|
||||
<fieldset>
|
||||
<HorizontalSelect
|
||||
name="profile"
|
||||
|
@ -149,22 +153,22 @@ class TagNodesForm extends React.Component {
|
|||
>
|
||||
{this.renderOptions()}
|
||||
</HorizontalSelect>
|
||||
{this.state.showCustomInput
|
||||
? <HorizontalInput
|
||||
name="customProfile"
|
||||
title={formatMessage(messages.customProfileLabel)}
|
||||
type="text"
|
||||
inputColumnClasses="col-sm-7"
|
||||
labelColumnClasses="col-sm-3"
|
||||
value=""
|
||||
validations={{ matchRegexp: /^[0-9a-z]+(-[0-9a-z]+)*$/ }}
|
||||
validationError={formatMessage(
|
||||
messages.customProfileErrorMessage
|
||||
)}
|
||||
description={formatMessage(messages.customProfileDescription)}
|
||||
required
|
||||
/>
|
||||
: null}
|
||||
{this.state.showCustomInput ? (
|
||||
<HorizontalInput
|
||||
name="customProfile"
|
||||
title={formatMessage(messages.customProfileLabel)}
|
||||
type="text"
|
||||
inputColumnClasses="col-sm-7"
|
||||
labelColumnClasses="col-sm-3"
|
||||
value=""
|
||||
validations={{ matchRegexp: /^[0-9a-z]+(-[0-9a-z]+)*$/ }}
|
||||
validationError={formatMessage(
|
||||
messages.customProfileErrorMessage
|
||||
)}
|
||||
description={formatMessage(messages.customProfileDescription)}
|
||||
required
|
||||
/>
|
||||
) : null}
|
||||
</fieldset>
|
||||
</div>
|
||||
<div className="modal-footer">
|
||||
|
|
|
@ -54,8 +54,7 @@ class TagNodesModal extends React.Component {
|
|||
<ModalHeader>
|
||||
<CloseModalXButton />
|
||||
<ModalTitle>
|
||||
<span className="fa fa-tag" />
|
||||
{' '}
|
||||
<span className="fa fa-tag" />{' '}
|
||||
<FormattedMessage {...messages.title} />
|
||||
</ModalTitle>
|
||||
</ModalHeader>
|
||||
|
|
|
@ -58,11 +58,7 @@ export default class Notification extends React.Component {
|
|||
|
||||
renderMessage(message) {
|
||||
if (typeof message === 'object') {
|
||||
return (
|
||||
<ul>
|
||||
{message.map((msg, i) => <li key={i}>{msg}</li>)}
|
||||
</ul>
|
||||
);
|
||||
return <ul>{message.map((msg, i) => <li key={i}>{msg}</li>)}</ul>;
|
||||
} else {
|
||||
return <p>{message}</p>;
|
||||
}
|
||||
|
@ -90,16 +86,18 @@ export default class Notification extends React.Component {
|
|||
<div className="clearfix">
|
||||
<div className={classes} role="alert">
|
||||
<span className={iconClass} aria-hidden="true" />
|
||||
{this.props.dismissable
|
||||
? <button
|
||||
type="button"
|
||||
className="close"
|
||||
aria-label="Close"
|
||||
onClick={this.props.removeNotification}
|
||||
>
|
||||
<span className="pficon pficon-close" aria-hidden="true" />
|
||||
</button>
|
||||
: false}
|
||||
{this.props.dismissable ? (
|
||||
<button
|
||||
type="button"
|
||||
className="close"
|
||||
aria-label="Close"
|
||||
onClick={this.props.removeNotification}
|
||||
>
|
||||
<span className="pficon pficon-close" aria-hidden="true" />
|
||||
</button>
|
||||
) : (
|
||||
false
|
||||
)}
|
||||
<strong>{this.props.title}</strong>
|
||||
{this.renderMessage(this.props.message)}
|
||||
</div>
|
||||
|
|
|
@ -52,7 +52,8 @@ class NotificationsToaster extends React.Component {
|
|||
timeoutable={notification.type !== 'error'}
|
||||
timerPaused={this.state.isHovered}
|
||||
removeNotification={() =>
|
||||
this.props.removeNotification(notification.id)}
|
||||
this.props.removeNotification(notification.id)
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -19,8 +19,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
||||
import EnvironmentConfigurationActions
|
||||
from '../../actions/EnvironmentConfigurationActions';
|
||||
import EnvironmentConfigurationActions from '../../actions/EnvironmentConfigurationActions';
|
||||
import { getCurrentPlanName } from '../../selectors/plans';
|
||||
import { getEnvironmentParameters } from '../../selectors/parameters';
|
||||
import { getEnvironment } from '../../selectors/environmentConfiguration';
|
||||
|
@ -44,13 +43,15 @@ class EnvironmentParameters extends React.Component {
|
|||
loaded={!isFetchingEnvironment}
|
||||
content="Fetching Parameters..."
|
||||
>
|
||||
{environmentError
|
||||
? <fieldset>
|
||||
<InlineNotification title={environmentError.title} type="error">
|
||||
{environmentError.message}
|
||||
</InlineNotification>
|
||||
</fieldset>
|
||||
: <ParameterInputList parameters={parameters.toList()} />}
|
||||
{environmentError ? (
|
||||
<fieldset>
|
||||
<InlineNotification title={environmentError.title} type="error">
|
||||
{environmentError.message}
|
||||
</InlineNotification>
|
||||
</fieldset>
|
||||
) : (
|
||||
<ParameterInputList parameters={parameters.toList()} />
|
||||
)}
|
||||
</Loader>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -35,8 +35,8 @@ const messages = defineMessages({
|
|||
|
||||
class ParameterInput extends React.Component {
|
||||
/**
|
||||
* Process the parameter, generate relevant input
|
||||
*/
|
||||
* Process the parameter, generate relevant input
|
||||
*/
|
||||
render() {
|
||||
const { name, label, description, defaultValue, value, type } = this.props;
|
||||
if (value) {
|
||||
|
|
|
@ -25,7 +25,8 @@ import ParameterInput from './ParameterInput';
|
|||
const messages = defineMessages({
|
||||
noParameters: {
|
||||
id: 'ParameterInputList.noParameters',
|
||||
defaultMessage: 'There are currently no parameters to configure in this section.'
|
||||
defaultMessage:
|
||||
'There are currently no parameters to configure in this section.'
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -58,11 +59,7 @@ class ParameterInputList extends React.Component {
|
|||
</fieldset>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<fieldset>
|
||||
{parameters}
|
||||
</fieldset>
|
||||
);
|
||||
return <fieldset>{parameters}</fieldset>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,14 +24,11 @@ import PropTypes from 'prop-types';
|
|||
import React from 'react';
|
||||
|
||||
import { CloseModalButton } from '../ui/Modals';
|
||||
import EnvironmentConfigurationActions
|
||||
from '../../actions/EnvironmentConfigurationActions';
|
||||
import EnvironmentConfigurationActions from '../../actions/EnvironmentConfigurationActions';
|
||||
import EnvironmentParameters from './EnvironmentParameters';
|
||||
import { getCurrentPlanName } from '../../selectors/plans';
|
||||
import { getRootParameters } from '../../selectors/parameters';
|
||||
import {
|
||||
getEnabledEnvironments
|
||||
} from '../../selectors/environmentConfiguration';
|
||||
import { getEnabledEnvironments } from '../../selectors/environmentConfiguration';
|
||||
import { Loader } from '../ui/Loader';
|
||||
import ModalFormErrorList from '../ui/forms/ModalFormErrorList';
|
||||
import ParametersActions from '../../actions/ParametersActions';
|
||||
|
@ -92,9 +89,9 @@ class Parameters extends React.Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* Filter out non updated parameters, so only parameters which have been actually changed
|
||||
* get sent to updateparameters
|
||||
*/
|
||||
* Filter out non updated parameters, so only parameters which have been actually changed
|
||||
* get sent to updateparameters
|
||||
*/
|
||||
_filterFormData(formData) {
|
||||
return fromJS(formData)
|
||||
.filterNot((value, key) => {
|
||||
|
@ -104,9 +101,9 @@ class Parameters extends React.Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
* 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
|
||||
*/
|
||||
_jsonParseFormData(formData) {
|
||||
return mapValues(formData, value => {
|
||||
try {
|
||||
|
@ -212,7 +209,6 @@ class Parameters extends React.Component {
|
|||
onValid={this.enableButton.bind(this)}
|
||||
onInvalid={this.disableButton.bind(this)}
|
||||
>
|
||||
|
||||
<div className="container-fluid">
|
||||
<div className="row row-eq-height">
|
||||
<div className="col-sm-4 sidebar-pf sidebar-pf-left">
|
||||
|
@ -240,9 +236,7 @@ class Parameters extends React.Component {
|
|||
loaded={this.props.parametersLoaded}
|
||||
>
|
||||
<ModalFormErrorList errors={this.props.formErrors.toJS()} />
|
||||
<div className="tab-content">
|
||||
{this.renderTabPanes()}
|
||||
</div>
|
||||
<div className="tab-content">{this.renderTabPanes()}</div>
|
||||
</Loader>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -100,60 +100,60 @@ class EditPlan extends React.Component {
|
|||
render() {
|
||||
const { plan } = this.props;
|
||||
|
||||
return plan
|
||||
? <RoutedModal bsSize="lg" redirectPath="/plans/manage">
|
||||
<Formsy.Form
|
||||
ref="EditPlanForm"
|
||||
role="form"
|
||||
className="form-horizontal"
|
||||
onChange={this.onPlanFilesChange.bind(this)}
|
||||
onValidSubmit={this.onFormSubmit.bind(this)}
|
||||
onValid={this.onFormValid.bind(this)}
|
||||
onInvalid={this.onFormInvalid.bind(this)}
|
||||
return plan ? (
|
||||
<RoutedModal bsSize="lg" redirectPath="/plans/manage">
|
||||
<Formsy.Form
|
||||
ref="EditPlanForm"
|
||||
role="form"
|
||||
className="form-horizontal"
|
||||
onChange={this.onPlanFilesChange.bind(this)}
|
||||
onValidSubmit={this.onFormSubmit.bind(this)}
|
||||
onValid={this.onFormValid.bind(this)}
|
||||
onInvalid={this.onFormInvalid.bind(this)}
|
||||
>
|
||||
<ModalHeader>
|
||||
<CloseModalXButton />
|
||||
<ModalTitle>
|
||||
<FormattedMessage
|
||||
{...messages.updatePlanNameFiles}
|
||||
values={{ planName: plan.name }}
|
||||
/>
|
||||
</ModalTitle>
|
||||
</ModalHeader>
|
||||
<Loader
|
||||
loaded={!this.props.isTransitioningPlan}
|
||||
size="lg"
|
||||
height={60}
|
||||
content={this.props.intl.formatMessage(messages.updatingPlanLoader)}
|
||||
>
|
||||
<ModalHeader>
|
||||
<CloseModalXButton />
|
||||
<ModalTitle>
|
||||
<FormattedMessage
|
||||
{...messages.updatePlanNameFiles}
|
||||
values={{ planName: plan.name }}
|
||||
/>
|
||||
</ModalTitle>
|
||||
</ModalHeader>
|
||||
<Loader
|
||||
loaded={!this.props.isTransitioningPlan}
|
||||
size="lg"
|
||||
height={60}
|
||||
content={this.props.intl.formatMessage(
|
||||
messages.updatingPlanLoader
|
||||
)}
|
||||
<ModalFormErrorList errors={this.props.planFormErrors.toJS()} />
|
||||
<div className="modal-body">
|
||||
<PlanEditFormTabs
|
||||
selectedFiles={this.state.selectedFiles}
|
||||
planName={plan.name}
|
||||
planFiles={plan.files}
|
||||
setUploadType={this.setUploadType.bind(this)}
|
||||
uploadType={this.state.uploadType}
|
||||
/>
|
||||
</div>
|
||||
</Loader>
|
||||
<ModalFooter>
|
||||
<button
|
||||
disabled={!this.state.canSubmit}
|
||||
className="btn btn-primary"
|
||||
type="submit"
|
||||
>
|
||||
<ModalFormErrorList errors={this.props.planFormErrors.toJS()} />
|
||||
<div className="modal-body">
|
||||
<PlanEditFormTabs
|
||||
selectedFiles={this.state.selectedFiles}
|
||||
planName={plan.name}
|
||||
planFiles={plan.files}
|
||||
setUploadType={this.setUploadType.bind(this)}
|
||||
uploadType={this.state.uploadType}
|
||||
/>
|
||||
</div>
|
||||
</Loader>
|
||||
<ModalFooter>
|
||||
<button
|
||||
disabled={!this.state.canSubmit}
|
||||
className="btn btn-primary"
|
||||
type="submit"
|
||||
>
|
||||
<FormattedMessage {...messages.uploadAndUpdate} />
|
||||
</button>
|
||||
<CloseModalButton>
|
||||
<FormattedMessage {...messages.cancel} />
|
||||
</CloseModalButton>
|
||||
</ModalFooter>
|
||||
</Formsy.Form>
|
||||
</RoutedModal>
|
||||
: <Redirect to="/plans" />;
|
||||
<FormattedMessage {...messages.uploadAndUpdate} />
|
||||
</button>
|
||||
<CloseModalButton>
|
||||
<FormattedMessage {...messages.cancel} />
|
||||
</CloseModalButton>
|
||||
</ModalFooter>
|
||||
</Formsy.Form>
|
||||
</RoutedModal>
|
||||
) : (
|
||||
<Redirect to="/plans" />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,8 @@ const messages = defineMessages({
|
|||
},
|
||||
downloadPlanExportMessage: {
|
||||
id: 'ExportPlan.downloadMessage',
|
||||
defaultMessage: 'The plan export you requested is ready. Please click the button below to ' +
|
||||
defaultMessage:
|
||||
'The plan export you requested is ready. Please click the button below to ' +
|
||||
'download the export. You might need to right-click the button and choose ' +
|
||||
'"Save link as...".'
|
||||
},
|
||||
|
@ -94,21 +95,20 @@ class ExportPlan extends React.Component {
|
|||
messages.exportingPlanLoader
|
||||
)}
|
||||
>
|
||||
{this.props.planExportUrl
|
||||
? <div>
|
||||
<p>
|
||||
<FormattedMessage {...messages.downloadPlanExportMessage} />
|
||||
</p>
|
||||
<a
|
||||
href={this.props.planExportUrl}
|
||||
className="btn btn-success"
|
||||
>
|
||||
<FormattedMessage {...messages.downloadPlanExport} />
|
||||
</a>
|
||||
</div>
|
||||
: <div>
|
||||
<FormattedMessage {...messages.exportError} />
|
||||
</div>}
|
||||
{this.props.planExportUrl ? (
|
||||
<div>
|
||||
<p>
|
||||
<FormattedMessage {...messages.downloadPlanExportMessage} />
|
||||
</p>
|
||||
<a href={this.props.planExportUrl} className="btn btn-success">
|
||||
<FormattedMessage {...messages.downloadPlanExport} />
|
||||
</a>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<FormattedMessage {...messages.exportError} />
|
||||
</div>
|
||||
)}
|
||||
</Loader>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
|
|
|
@ -91,9 +91,7 @@ export default class FileList extends React.Component {
|
|||
</h4>
|
||||
</div>
|
||||
<table className="table upload-files">
|
||||
<tbody>
|
||||
{files}
|
||||
</tbody>
|
||||
<tbody>{files}</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -25,7 +25,8 @@ const messages = defineMessages({
|
|||
},
|
||||
noPlansAvailableMessage: {
|
||||
id: 'NoPlans.noPlansAvailableMessage',
|
||||
defaultMessage: 'There are no Deployment Plans available. Please create one first.'
|
||||
defaultMessage:
|
||||
'There are no Deployment Plans available. Please create one first.'
|
||||
},
|
||||
importPlan: {
|
||||
id: 'NoPlans.importPlan',
|
||||
|
@ -40,12 +41,15 @@ export default class NoPlans extends React.Component {
|
|||
<div className="blank-slate-pf-icon">
|
||||
<span className="fa fa-ban" />
|
||||
</div>
|
||||
<h1><FormattedMessage {...messages.noPlansAvailable} /></h1>
|
||||
<p><FormattedMessage {...messages.noPlansAvailableMessage} /></p>
|
||||
<h1>
|
||||
<FormattedMessage {...messages.noPlansAvailable} />
|
||||
</h1>
|
||||
<p>
|
||||
<FormattedMessage {...messages.noPlansAvailableMessage} />
|
||||
</p>
|
||||
<div className="blank-slate-pf-main-action">
|
||||
<Link to="/plans/manage/new" className="btn btn-lg btn-primary">
|
||||
<span className="fa fa-plus" />
|
||||
{' '}
|
||||
<span className="fa fa-plus" />{' '}
|
||||
<FormattedMessage {...messages.importPlan} />
|
||||
</Link>
|
||||
</div>
|
||||
|
|
|
@ -50,7 +50,8 @@ const messages = defineMessages({
|
|||
},
|
||||
badExtension: {
|
||||
id: 'PlanEditFormTabs.badExtension',
|
||||
defaultMessage: 'Invalid type: plan file must be a tar archive (.tar.gz or .tgz)'
|
||||
defaultMessage:
|
||||
'Invalid type: plan file must be a tar archive (.tar.gz or .tgz)'
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -89,9 +90,8 @@ export default class PlanEditFormTabs extends React.Component {
|
|||
</Tab>
|
||||
<Tab isActive={this.isActiveTab('planFiles')}>
|
||||
<a className="link" onClick={() => this.setActiveTab('planFiles')}>
|
||||
<FormattedMessage {...messages.files} /> <span className="badge">
|
||||
{this.getFileCount.bind(this)()}
|
||||
</span>
|
||||
<FormattedMessage {...messages.files} />{' '}
|
||||
<span className="badge">{this.getFileCount.bind(this)()}</span>
|
||||
</a>
|
||||
</Tab>
|
||||
</ul>
|
||||
|
|
|
@ -104,27 +104,33 @@ class PlanFileInput extends React.Component {
|
|||
if (!errorMessage && this.state.unreadableFile) {
|
||||
errorMessage = `${this.state.unreadableFile} could not be read.`;
|
||||
}
|
||||
return errorMessage
|
||||
? <span className="help-block">{errorMessage}</span>
|
||||
: false;
|
||||
return errorMessage ? (
|
||||
<span className="help-block">{errorMessage}</span>
|
||||
) : (
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
renderDescription() {
|
||||
let description = this.props.description;
|
||||
return description
|
||||
? <small className="help-block">{description}</small>
|
||||
: false;
|
||||
return description ? (
|
||||
<small className="help-block">{description}</small>
|
||||
) : (
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
renderProgress() {
|
||||
return this.state.progress > 0
|
||||
? <div className="progress active help-block">
|
||||
<div
|
||||
className="progress-bar"
|
||||
style={{ width: `${this.state.progress}%` }}
|
||||
/>
|
||||
</div>
|
||||
: false;
|
||||
return this.state.progress > 0 ? (
|
||||
<div className="progress active help-block">
|
||||
<div
|
||||
className="progress-bar"
|
||||
style={{ width: `${this.state.progress}%` }}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -58,7 +58,8 @@ const messages = defineMessages({
|
|||
},
|
||||
badExtension: {
|
||||
id: 'PlanFormTabs.badExtension',
|
||||
defaultMessage: 'Invalid type: plan file must be a tar archive (.tar.gz or .tgz)'
|
||||
defaultMessage:
|
||||
'Invalid type: plan file must be a tar archive (.tar.gz or .tgz)'
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -89,9 +90,8 @@ export default class PlanFormTabs extends React.Component {
|
|||
</Tab>
|
||||
<Tab isActive={this.isActiveTab('planFiles')}>
|
||||
<a className="link" onClick={() => this.setActiveTab('planFiles')}>
|
||||
<FormattedMessage {...messages.files} /> <span className="badge">
|
||||
{this.props.selectedFiles.length}
|
||||
</span>
|
||||
<FormattedMessage {...messages.files} />{' '}
|
||||
<span className="badge">{this.props.selectedFiles.length}</span>
|
||||
</a>
|
||||
</Tab>
|
||||
</ul>
|
||||
|
|
|
@ -46,8 +46,7 @@ export default class PlanUploadTypeRadios extends React.Component {
|
|||
value="tarball"
|
||||
onChange={this.props.setUploadType}
|
||||
defaultChecked
|
||||
/>
|
||||
{' '}
|
||||
/>{' '}
|
||||
<FormattedMessage {...messages.tarArchive} />
|
||||
</label>
|
||||
<label className="radio-inline" htmlFor="checkbox-folder">
|
||||
|
@ -58,8 +57,7 @@ export default class PlanUploadTypeRadios extends React.Component {
|
|||
name="uploadType"
|
||||
onChange={this.props.setUploadType}
|
||||
value="folder"
|
||||
/>
|
||||
{' '}
|
||||
/>{' '}
|
||||
<FormattedMessage {...messages.localFolder} />
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -79,16 +79,18 @@ class PlansList extends React.Component {
|
|||
</Link>
|
||||
</div>
|
||||
</PageHeader>
|
||||
{this.props.plans.isEmpty()
|
||||
? <NoPlans />
|
||||
: <div className="panel panel-default">
|
||||
<div className="cards-pf">
|
||||
<div className="row row-cards-pf">
|
||||
<ImportPlanCard />
|
||||
{this.renderCards()}
|
||||
</div>
|
||||
{this.props.plans.isEmpty() ? (
|
||||
<NoPlans />
|
||||
) : (
|
||||
<div className="panel panel-default">
|
||||
<div className="cards-pf">
|
||||
<div className="row row-cards-pf">
|
||||
<ImportPlanCard />
|
||||
{this.renderCards()}
|
||||
</div>
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -63,10 +63,11 @@ const PlanActions = ({ planName, stack }) => {
|
|||
<MenuItemLink to={`/plans/manage/${planName}/export`}>
|
||||
<FormattedMessage {...messages.export} />
|
||||
</MenuItemLink>
|
||||
{!stack &&
|
||||
{!stack && (
|
||||
<MenuItemLink to={`/plans/manage/${planName}/delete`}>
|
||||
<FormattedMessage {...messages.delete} />
|
||||
</MenuItemLink>}
|
||||
</MenuItemLink>
|
||||
)}
|
||||
</DropdownKebab>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -96,15 +96,10 @@ class PlanCard extends React.Component {
|
|||
return (
|
||||
<ul className="list-unstyled">
|
||||
<li>
|
||||
<strong>Status:</strong>
|
||||
{' '}
|
||||
{this.renderStackIcon(stack)}
|
||||
{' '}
|
||||
<strong>Status:</strong> {this.renderStackIcon(stack)}{' '}
|
||||
{this.getDeploymentStatus(stack)}
|
||||
</li>
|
||||
<li>
|
||||
{modified}
|
||||
</li>
|
||||
<li>{modified}</li>
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
@ -143,13 +138,10 @@ class PlanCard extends React.Component {
|
|||
{plan.name}
|
||||
<PlanActions planName={plan.name} stack={stack} />
|
||||
</h2>
|
||||
{plan.description &&
|
||||
<div className="card-pf-body">
|
||||
{plan.description}
|
||||
</div>}
|
||||
<div className="card-pf-footer">
|
||||
{this.renderStackInfo()}
|
||||
</div>
|
||||
{plan.description && (
|
||||
<div className="card-pf-body">{plan.description}</div>
|
||||
)}
|
||||
<div className="card-pf-footer">{this.renderStackInfo()}</div>
|
||||
</OverlayLoader>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -100,9 +100,9 @@ class RoleDetail extends React.Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* Filter out non updated parameters, so only parameters which have been actually changed
|
||||
* get sent to updateparameters
|
||||
*/
|
||||
* Filter out non updated parameters, so only parameters which have been actually changed
|
||||
* get sent to updateparameters
|
||||
*/
|
||||
_filterFormData(formData) {
|
||||
return fromJS(formData)
|
||||
.filterNot((value, key) => {
|
||||
|
@ -112,9 +112,9 @@ class RoleDetail extends React.Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
* 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
|
||||
*/
|
||||
_jsonParseFormData(formData) {
|
||||
return mapValues(formData, value => {
|
||||
try {
|
||||
|
@ -154,17 +154,23 @@ class RoleDetail extends React.Component {
|
|||
return (
|
||||
<ul className="nav nav-tabs">
|
||||
<NavTab
|
||||
to={`/plans/${currentPlanName}/roles/${urlParams.roleName}/parameters`}
|
||||
to={`/plans/${currentPlanName}/roles/${
|
||||
urlParams.roleName
|
||||
}/parameters`}
|
||||
>
|
||||
<FormattedMessage {...messages.parameters} />
|
||||
</NavTab>
|
||||
<NavTab
|
||||
to={`/plans/${currentPlanName}/roles/${urlParams.roleName}/services`}
|
||||
to={`/plans/${currentPlanName}/roles/${
|
||||
urlParams.roleName
|
||||
}/services`}
|
||||
>
|
||||
<FormattedMessage {...messages.services} />
|
||||
</NavTab>
|
||||
<NavTab
|
||||
to={`/plans/${currentPlanName}/roles/${urlParams.roleName}/network-configuration`}
|
||||
to={`/plans/${currentPlanName}/roles/${
|
||||
urlParams.roleName
|
||||
}/network-configuration`}
|
||||
>
|
||||
<FormattedMessage {...messages.networkConfiguration} />
|
||||
</NavTab>
|
||||
|
@ -226,24 +232,26 @@ class RoleDetail extends React.Component {
|
|||
/>
|
||||
<Redirect
|
||||
from="/plans/:planName/roles/:roleName"
|
||||
to={`/plans/${currentPlanName}/roles/${urlParams.roleName}/parameters`}
|
||||
to={`/plans/${currentPlanName}/roles/${
|
||||
urlParams.roleName
|
||||
}/parameters`}
|
||||
/>
|
||||
</Switch>
|
||||
</Loader>
|
||||
{dataLoaded
|
||||
? <ModalFooter>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={!this.state.canSubmit}
|
||||
className="btn btn-primary"
|
||||
>
|
||||
<FormattedMessage {...messages.saveChanges} />
|
||||
</button>
|
||||
<CloseModalButton>
|
||||
<FormattedMessage {...messages.cancel} />
|
||||
</CloseModalButton>
|
||||
</ModalFooter>
|
||||
: null}
|
||||
{dataLoaded ? (
|
||||
<ModalFooter>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={!this.state.canSubmit}
|
||||
className="btn btn-primary"
|
||||
>
|
||||
<FormattedMessage {...messages.saveChanges} />
|
||||
</button>
|
||||
<CloseModalButton>
|
||||
<FormattedMessage {...messages.cancel} />
|
||||
</CloseModalButton>
|
||||
</ModalFooter>
|
||||
) : null}
|
||||
</Formsy.Form>
|
||||
</RoutedModalPanel>
|
||||
);
|
||||
|
|
|
@ -29,7 +29,8 @@ import Tab from '../ui/Tab';
|
|||
const messages = defineMessages({
|
||||
noParameters: {
|
||||
id: 'RoleServices.noParameters',
|
||||
defaultMessage: 'There are currently no parameters to configure in this section.'
|
||||
defaultMessage:
|
||||
'There are currently no parameters to configure in this section.'
|
||||
},
|
||||
selectService: {
|
||||
id: 'RoleServices.selectService',
|
||||
|
|
|
@ -31,7 +31,11 @@ export default class ConfirmationModal extends React.Component {
|
|||
renderTitle() {
|
||||
const iconClass = this.props.iconClass;
|
||||
if (iconClass) {
|
||||
return <span><span className={iconClass} /> {this.props.title}</span>;
|
||||
return (
|
||||
<span>
|
||||
<span className={iconClass} /> {this.props.title}
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
return <span>{this.props.title}</span>;
|
||||
}
|
||||
|
@ -51,9 +55,7 @@ export default class ConfirmationModal extends React.Component {
|
|||
<Modal bsSize="sm" show={show} onHide={onCancel}>
|
||||
<ModalHeader>
|
||||
<CloseModalXButton />
|
||||
<ModalTitle>
|
||||
{this.renderTitle()}
|
||||
</ModalTitle>
|
||||
<ModalTitle>{this.renderTitle()}</ModalTitle>
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<p>{question}</p>
|
||||
|
|
|
@ -81,9 +81,7 @@ class ModalPanel extends React.Component {
|
|||
className={cx('modal-panel', modalPanelClassName)}
|
||||
style={style}
|
||||
>
|
||||
<div className="row flex-container">
|
||||
{children}
|
||||
</div>
|
||||
<div className="row flex-container">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -32,11 +32,7 @@ export default class TabPane extends React.Component {
|
|||
active: this.props.isActive
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={classes}>
|
||||
{this.renderChildren()}
|
||||
</div>
|
||||
);
|
||||
return <div className={classes}>{this.renderChildren()}</div>;
|
||||
}
|
||||
}
|
||||
TabPane.propTypes = {
|
||||
|
|
|
@ -27,9 +27,7 @@ export const ActiveFiltersList = ({
|
|||
return (
|
||||
<span className="toolbar-pf-active-filters">
|
||||
<p>{label} </p>
|
||||
<ul className="list-inline">
|
||||
{children}
|
||||
</ul>
|
||||
<ul className="list-inline">{children}</ul>
|
||||
<p>
|
||||
<a className="link" onClick={() => handleClearAll()}>
|
||||
{clearAllLabel}
|
||||
|
|
|
@ -94,9 +94,11 @@ export const SelectAllButton = selectAll(
|
|||
onClick={() => toggleSelectAll()}
|
||||
disabled={disabled}
|
||||
>
|
||||
{shouldSelectAll
|
||||
? <FormattedMessage {...messages.selectAll} />
|
||||
: <FormattedMessage {...messages.deselectAll} />}
|
||||
{shouldSelectAll ? (
|
||||
<FormattedMessage {...messages.selectAll} />
|
||||
) : (
|
||||
<FormattedMessage {...messages.deselectAll} />
|
||||
)}
|
||||
</Button>
|
||||
)
|
||||
);
|
||||
|
|
|
@ -30,7 +30,9 @@ class ToolbarFiltersForm extends React.Component {
|
|||
renderFilterByOptions() {
|
||||
const { options } = this.props;
|
||||
return Object.keys(options).map(k => (
|
||||
<MenuItem key={k} eventKey={k}>{options[k]}</MenuItem>
|
||||
<MenuItem key={k} eventKey={k}>
|
||||
{options[k]}
|
||||
</MenuItem>
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -52,20 +54,22 @@ class ToolbarFiltersForm extends React.Component {
|
|||
return (
|
||||
<form id={id} onSubmit={handleSubmit(this.submit.bind(this))}>
|
||||
<FormGroup className="toolbar-pf-filter">
|
||||
{options
|
||||
? <InputGroup>
|
||||
<InputGroup.Button>
|
||||
<Field
|
||||
name="filterBy"
|
||||
component={DropdownSelect}
|
||||
format={formatSelectValue}
|
||||
>
|
||||
{this.renderFilterByOptions()}
|
||||
</Field>
|
||||
</InputGroup.Button>
|
||||
{this.renderFilterStringField()}
|
||||
</InputGroup>
|
||||
: this.renderFilterStringField()}
|
||||
{options ? (
|
||||
<InputGroup>
|
||||
<InputGroup.Button>
|
||||
<Field
|
||||
name="filterBy"
|
||||
component={DropdownSelect}
|
||||
format={formatSelectValue}
|
||||
>
|
||||
{this.renderFilterByOptions()}
|
||||
</Field>
|
||||
</InputGroup.Button>
|
||||
{this.renderFilterStringField()}
|
||||
</InputGroup>
|
||||
) : (
|
||||
this.renderFilterStringField()
|
||||
)}
|
||||
</FormGroup>
|
||||
</form>
|
||||
);
|
||||
|
|
|
@ -21,18 +21,14 @@ export const Toolbar = ({ children, tableView }) => {
|
|||
if (tableView) {
|
||||
return (
|
||||
<div className="toolbar-pf row table-view-pf-toolbar">
|
||||
<div className="col-sm-12">
|
||||
{children}
|
||||
</div>
|
||||
<div className="col-sm-12">{children}</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="container-fluid">
|
||||
<div className="toolbar-pf row">
|
||||
<div className="col-sm-12">
|
||||
{children}
|
||||
</div>
|
||||
<div className="col-sm-12">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -47,9 +43,7 @@ Toolbar.defaultProps = {
|
|||
};
|
||||
|
||||
export const ToolbarActions = ({ children }) => (
|
||||
<div className="toolbar-pf-actions">
|
||||
{children}
|
||||
</div>
|
||||
<div className="toolbar-pf-actions">{children}</div>
|
||||
);
|
||||
ToolbarActions.propTypes = {
|
||||
children: PropTypes.node
|
||||
|
@ -57,9 +51,7 @@ ToolbarActions.propTypes = {
|
|||
|
||||
export const ToolbarResults = ({ children }) => (
|
||||
<div className="toolbar-pf-results row">
|
||||
<div className="col-sm-12">
|
||||
{children}
|
||||
</div>
|
||||
<div className="col-sm-12">{children}</div>
|
||||
</div>
|
||||
);
|
||||
ToolbarResults.propTypes = {
|
||||
|
|
|
@ -29,9 +29,7 @@ export const ActionCard = ({ children, className, onClick, ...rest }) => (
|
|||
{...rest}
|
||||
>
|
||||
<div className="card-pf-body">
|
||||
<p className="text-center">
|
||||
{children}
|
||||
</p>
|
||||
<p className="text-center">{children}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -76,12 +76,12 @@ export default class Dropdown extends React.Component {
|
|||
{items}
|
||||
</ul>
|
||||
</div>
|
||||
{this.state.isOpen
|
||||
? <div
|
||||
onClick={this.toggleDropdown.bind(this)}
|
||||
className="modal-backdrop fade"
|
||||
/>
|
||||
: null}
|
||||
{this.state.isOpen ? (
|
||||
<div
|
||||
onClick={this.toggleDropdown.bind(this)}
|
||||
className="modal-backdrop fade"
|
||||
/>
|
||||
) : null}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -28,9 +28,7 @@ const DropdownKebab = ({ children, id, pullRight }) => {
|
|||
>
|
||||
<span className="fa fa-ellipsis-v" />
|
||||
</Dropdown.Toggle>
|
||||
<Dropdown.Menu>
|
||||
{children}
|
||||
</Dropdown.Menu>
|
||||
<Dropdown.Menu>{children}</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -32,9 +32,7 @@ export default class FormErrorList extends React.Component {
|
|||
return (
|
||||
<div>
|
||||
<strong>{`${errors.length} Errors Found:`}</strong>
|
||||
<ul>
|
||||
{errorList}
|
||||
</ul>
|
||||
<ul>{errorList}</ul>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -19,9 +19,9 @@ import React from 'react';
|
|||
|
||||
export default class InputDescription extends React.Component {
|
||||
render() {
|
||||
return this.props.description
|
||||
? <small className="help-block">{this.props.description}</small>
|
||||
: null;
|
||||
return this.props.description ? (
|
||||
<small className="help-block">{this.props.description}</small>
|
||||
) : null;
|
||||
}
|
||||
}
|
||||
InputDescription.propTypes = {
|
||||
|
|
|
@ -20,9 +20,9 @@ import React from 'react';
|
|||
export default class InputDescription extends React.Component {
|
||||
render() {
|
||||
const errorMessage = this.props.getErrorMessage();
|
||||
return errorMessage
|
||||
? <span className="help-block">{errorMessage}</span>
|
||||
: null;
|
||||
return errorMessage ? (
|
||||
<span className="help-block">{errorMessage}</span>
|
||||
) : null;
|
||||
}
|
||||
}
|
||||
InputDescription.propTypes = {
|
||||
|
|
|
@ -38,7 +38,7 @@ InputDescription.propTypes = {
|
|||
export const InputMessage = ({ fieldMeta: { touched, error, warning } }) =>
|
||||
touched
|
||||
? (error ? <HelpBlock>{error}</HelpBlock> : null) ||
|
||||
(warning ? <HelpBlock>{warning}</HelpBlock> : null)
|
||||
(warning ? <HelpBlock>{warning}</HelpBlock> : null)
|
||||
: null;
|
||||
|
||||
InputMessage.propTypes = {
|
||||
|
|
|
@ -120,9 +120,7 @@ class DataTable extends React.Component {
|
|||
role="grid"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
{headers}
|
||||
</tr>
|
||||
<tr>{headers}</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows.length > 0 ? rows : this.props.noRowsRenderer()}
|
||||
|
|
|
@ -22,15 +22,11 @@ import TableCheckBox from '../forms/TableCheckBox';
|
|||
import { InlineLoader } from '../Loader';
|
||||
|
||||
/**
|
||||
* Default table header cell class
|
||||
*/
|
||||
* Default table header cell class
|
||||
*/
|
||||
export class DataTableHeaderCell extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<th {...this.props}>
|
||||
{this.props.children}
|
||||
</th>
|
||||
);
|
||||
return <th {...this.props}>{this.props.children}</th>;
|
||||
}
|
||||
}
|
||||
DataTableHeaderCell.propTypes = {
|
||||
|
@ -38,15 +34,11 @@ DataTableHeaderCell.propTypes = {
|
|||
};
|
||||
|
||||
/**
|
||||
* Default table cell class
|
||||
*/
|
||||
* Default table cell class
|
||||
*/
|
||||
export class DataTableCell extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<td>
|
||||
{this.props.children}
|
||||
</td>
|
||||
);
|
||||
return <td>{this.props.children}</td>;
|
||||
}
|
||||
}
|
||||
DataTableCell.propTypes = {
|
||||
|
@ -54,19 +46,15 @@ DataTableCell.propTypes = {
|
|||
};
|
||||
|
||||
/**
|
||||
* Table cell class able to render value from data set passed to columns
|
||||
*/
|
||||
* Table cell class able to render value from data set passed to columns
|
||||
*/
|
||||
export class DataTableDataFieldCell extends React.Component {
|
||||
render() {
|
||||
let value = _.result(
|
||||
this.props.data[this.props.rowIndex],
|
||||
this.props.field
|
||||
);
|
||||
return (
|
||||
<DataTableCell {...this.props}>
|
||||
{value}
|
||||
</DataTableCell>
|
||||
);
|
||||
return <DataTableCell {...this.props}>{value}</DataTableCell>;
|
||||
}
|
||||
}
|
||||
DataTableDataFieldCell.propTypes = {
|
||||
|
@ -79,11 +67,7 @@ export const DataTableDateFieldCell = props => {
|
|||
//TODO(jtomasek): Update this component to parse date and format it using React Intl's
|
||||
// FormatedDate
|
||||
const value = _.result(props.data[props.rowIndex], props.field);
|
||||
return (
|
||||
<DataTableCell {...props}>
|
||||
{value}
|
||||
</DataTableCell>
|
||||
);
|
||||
return <DataTableCell {...props}>{value}</DataTableCell>;
|
||||
};
|
||||
DataTableDateFieldCell.propTypes = {
|
||||
data: PropTypes.array.isRequired,
|
||||
|
|
|
@ -29,16 +29,20 @@ export const checkRunningDeployment = WrappedComponent => {
|
|||
if (this.props.currentStackDeploymentInProgress) {
|
||||
this.props.notify({
|
||||
title: 'Not allowed',
|
||||
message: `A deployment for the plan ${this.props.currentPlanName} is already in progress.`,
|
||||
message: `A deployment for the plan ${
|
||||
this.props.currentPlanName
|
||||
} is already in progress.`,
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.props.currentStackDeploymentInProgress
|
||||
? <Redirect to={`/plans/${this.props.currentPlanName}`} />
|
||||
: <WrappedComponent {...this.props} />;
|
||||
return this.props.currentStackDeploymentInProgress ? (
|
||||
<Redirect to={`/plans/${this.props.currentPlanName}`} />
|
||||
) : (
|
||||
<WrappedComponent {...this.props} />
|
||||
);
|
||||
}
|
||||
}
|
||||
CheckRunningDeploymentHOC.propTypes = {
|
||||
|
|
|
@ -59,11 +59,10 @@ export default class Validation extends React.Component {
|
|||
this.props.addActiveFilter({
|
||||
filterBy: 'group',
|
||||
filterString: group
|
||||
})}
|
||||
})
|
||||
}
|
||||
>
|
||||
<small>
|
||||
{group}
|
||||
</small>
|
||||
<small>{group}</small>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -92,7 +92,11 @@ class ValidationDetail extends React.Component {
|
|||
if (lastResult && !includes(['running', 'paused'], this.props.status)) {
|
||||
return (
|
||||
<div>
|
||||
<p><strong><FormattedMessage {...messages.output} /></strong></p>
|
||||
<p>
|
||||
<strong>
|
||||
<FormattedMessage {...messages.output} />
|
||||
</strong>
|
||||
</p>
|
||||
<pre>
|
||||
{lastResult.output.get('stdout', lastResult.output.get('result'))}
|
||||
</pre>
|
||||
|
@ -128,19 +132,22 @@ class ValidationDetail extends React.Component {
|
|||
<h3>{this.props.name}</h3>
|
||||
</div>
|
||||
<p>
|
||||
<strong><FormattedMessage {...messages.description} /></strong>
|
||||
{' '}
|
||||
<strong>
|
||||
<FormattedMessage {...messages.description} />
|
||||
</strong>{' '}
|
||||
<br />
|
||||
{this.props.description}
|
||||
</p>
|
||||
<p>
|
||||
<strong><FormattedMessage {...messages.groups} /></strong>
|
||||
{' '}
|
||||
<strong>
|
||||
<FormattedMessage {...messages.groups} />
|
||||
</strong>{' '}
|
||||
{this.renderValidationGroups()}
|
||||
</p>
|
||||
<p>
|
||||
<strong><FormattedMessage {...messages.status} /></strong>
|
||||
{' '}
|
||||
<strong>
|
||||
<FormattedMessage {...messages.status} />
|
||||
</strong>{' '}
|
||||
{this.props.status}
|
||||
</p>
|
||||
{this.renderValidationOutput()}
|
||||
|
|
|
@ -111,7 +111,9 @@ class ValidationsList extends React.Component {
|
|||
iconClass="pficon pficon-flag"
|
||||
title={this.props.intl.formatMessage(messages.noValidations)}
|
||||
>
|
||||
<p><FormattedMessage {...messages.noValidationsMessage} /></p>
|
||||
<p>
|
||||
<FormattedMessage {...messages.noValidationsMessage} />
|
||||
</p>
|
||||
</BlankSlate>
|
||||
);
|
||||
} else {
|
||||
|
@ -170,8 +172,10 @@ class ValidationsList extends React.Component {
|
|||
<div className="actions pull-right">
|
||||
<InlineLoader
|
||||
loaded={
|
||||
!(this.props.validationsLoaded &&
|
||||
this.props.isFetchingValidations)
|
||||
!(
|
||||
this.props.validationsLoaded &&
|
||||
this.props.isFetchingValidations
|
||||
)
|
||||
}
|
||||
component="small"
|
||||
content={formatMessage(messages.loadingValidations)}
|
||||
|
@ -180,8 +184,7 @@ class ValidationsList extends React.Component {
|
|||
className="link refresh"
|
||||
onClick={this.refreshValidations.bind(this)}
|
||||
>
|
||||
<span className="pficon pficon-refresh" />
|
||||
{' '}
|
||||
<span className="pficon pficon-refresh" />{' '}
|
||||
<FormattedMessage {...messages.refresh} />
|
||||
</a>
|
||||
</InlineLoader>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue