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:
Honza Pokorny 2018-01-16 09:23:27 -04:00 committed by Jiri Tomasek
parent 9941b07efb
commit 27dfe42f5e
111 changed files with 10114 additions and 1342 deletions

2
.gitignore vendored
View File

@ -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

9761
npm-shrinkwrap.json generated

File diff suppressed because it is too large Load Diff

View File

@ -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",

View File

@ -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
}

View File

@ -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)

View File

@ -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(),

View File

@ -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

View File

@ -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'

View File

@ -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');
});
});
});

View File

@ -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;

View File

@ -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];

View File

@ -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];

View File

@ -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');

View File

@ -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' },

View File

@ -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'
}
}
}

View File

@ -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(() => {

View File

@ -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';

View File

@ -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', () => {

View File

@ -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,

View File

@ -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));
};

View File

@ -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 => {

View File

@ -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 => {

View File

@ -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 => {

View File

@ -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 => {

View File

@ -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 => {

View File

@ -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>

View File

@ -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() {

View File

@ -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() {

View File

@ -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>

View File

@ -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,

View File

@ -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}

View File

@ -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}

View File

@ -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 />

View File

@ -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'),

View File

@ -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>

View File

@ -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';

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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">

View File

@ -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,

View File

@ -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>
);

View File

@ -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>
);

View File

@ -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();
}

View File

@ -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>

View File

@ -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>

View File

@ -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}

View File

@ -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')} />
&nbsp;
<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) => (

View File

@ -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>
&nbsp;
<FormattedMessage {...messages.ram} />
</ListViewInfoItem>,

View File

@ -85,16 +85,17 @@ export const NodeProvisionState = ({
...rest
}) => (
<span {...rest}>
<strong><FormattedMessage {...messages.provisionState} /></strong>&nbsp;
{targetProvisionState
? <span>
{provisionState}
{' '}
<span className="fa fa-long-arrow-right" />
{' '}
{targetProvisionState}
</span>
: provisionState}
<strong>
<FormattedMessage {...messages.provisionState} />
</strong>&nbsp;
{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>&nbsp;
<strong>
<FormattedMessage {...messages.introspectionState} />
</strong>&nbsp;
{state}
</span>
);

View File

@ -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'
}
});

View File

@ -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,

View File

@ -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>

View File

@ -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={{

View File

@ -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>
);
}
}

View File

@ -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}` : '')) ||

View File

@ -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`}

View File

@ -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>
&nbsp; <FormattedMessage {...messages.or} /> &nbsp;
@ -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)
};
}

View File

@ -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 = {

View File

@ -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">

View File

@ -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>

View File

@ -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>

View File

@ -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)
}
/>
);
});

View File

@ -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>
);
}

View File

@ -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) {

View File

@ -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>;
}
}
}

View File

@ -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>

View File

@ -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" />
);
}
}

View File

@ -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>

View File

@ -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>
);

View File

@ -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>

View File

@ -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>

View File

@ -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() {

View File

@ -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>

View File

@ -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>

View File

@ -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>
);
}

View File

@ -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>
);

View File

@ -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>

View File

@ -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>
);

View File

@ -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',

View File

@ -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>

View File

@ -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>

View File

@ -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 = {

View File

@ -27,9 +27,7 @@ export const ActiveFiltersList = ({
return (
<span className="toolbar-pf-active-filters">
<p>{label}&nbsp;</p>
<ul className="list-inline">
{children}
</ul>
<ul className="list-inline">{children}</ul>
<p>
<a className="link" onClick={() => handleClearAll()}>
{clearAllLabel}

View File

@ -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>
)
);

View File

@ -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>
);

View File

@ -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 = {

View File

@ -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>
);

View File

@ -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>
);
}

View File

@ -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>
);
};

View File

@ -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 {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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()}

View File

@ -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,

View File

@ -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 = {

View File

@ -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>
);

View File

@ -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()}

View File

@ -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