Support translations for deployment task statuses

* Graph levels also support translations.
* Node name button text can be selected in history table view.

Closes-Bug: #1621877

Change-Id: If2657edad3987edd76205453e71e9765fc4f1f6c
This commit is contained in:
Julia Aranovich 2016-09-09 17:08:28 +03:00
parent aa171b9944
commit bb8bebd99c
5 changed files with 94 additions and 32 deletions

View File

@ -3461,9 +3461,9 @@ input[type=range] {
padding-right: 0;
}
}
div.error.status span:last-child {
.font-semibold;
.text-danger;
.status {
&.error span:last-child {.text-danger;}
&.ready span:last-child {.text-success;}
}
}
}
@ -5362,6 +5362,7 @@ input[type=range] {
}
.dry-run-label {
margin-left: 10px;
text-transform: uppercase;
}
}
@ -5400,12 +5401,19 @@ input[type=range] {
padding: 0;
border: 0;
max-width: 100%;
&.btn-node-info {
user-select: text;
}
> div {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.status {
&.error {.text-danger;}
&.ready {.text-success;}
}
}
.alert {
margin-bottom: 0;
@ -5469,6 +5477,10 @@ input[type=range] {
display: inline-block;
.break-word;
}
.status {
&.error {.text-danger;}
&.ready {.text-success;}
}
}
}
}

View File

@ -346,7 +346,7 @@
"time_end": "Finished",
"status": "Status",
"message": "Message",
"dry_run": "DRY RUN"
"dry_run": "dry run"
},
"transaction_statuses": {
"ready": "Ready",
@ -368,7 +368,12 @@
"filter_tooltip": "Filter Workflows",
"filter_by_graph_type": "Type",
"filter_by_graph_level": "Level",
"no_graphs_matched_filters": "No workflows matched applied filters."
"no_graphs_matched_filters": "No workflows matched applied filters.",
"graph_levels": {
"release": "Release",
"cluster": "Environment",
"plugin": "Plugin __pluginName__"
}
},
"deployment_history": {
"master_node": "Master node",
@ -393,7 +398,14 @@
"minutes": "__minutes__ minutes",
"minutes_and_seconds": "__minutes__ min __seconds__ sec",
"hours": "__hours__ hr __minutes__ min",
"export_csv": "Export CSV"
"export_csv": "Export CSV",
"task_statuses": {
"ready": "Ready",
"error": "Error",
"skipped": "Skipped",
"pending": "Pending",
"running": "Running"
}
},
"nodes_tab": {
"roles": "Roles",

View File

@ -65,7 +65,13 @@ var DeploymentHistory = React.createClass({
label: i18n(ns + 'filter_by_status'),
values: [],
options: _.map(DEPLOYMENT_TASK_STATUSES,
(status) => ({name: status, title: status})
(status) => ({
name: status,
title: i18n(
'cluster_page.deployment_history.task_statuses.' + status,
{defaultValue: status}
)
})
)
}
],
@ -408,18 +414,28 @@ var DeploymentHistoryTask = React.createClass({
>
<div>
{_.without(DEPLOYMENT_TASK_ATTRIBUTES, 'node_id')
.map((attr) => !_.isNull(task.get(attr)) && (
<div key={attr} className={utils.classNames('row', attr, taskStatus)}>
<span className='col-xs-3'>
{i18n('dialog.deployment_task_details.task.' + attr)}
</span>
<span className='col-xs-9'>
{attr === 'time_start' || attr === 'time_end' ?
formatTimestamp(parseISO8601Date(task.get(attr))) : task.get(attr)
}
</span>
</div>
))
.map((attr) => {
if (_.isNull(task.get(attr))) return null;
return (
<div key={attr} className={utils.classNames('row', attr, taskStatus)}>
<span className='col-xs-3'>
{i18n('dialog.deployment_task_details.task.' + attr)}
</span>
<span className='col-xs-9'>
{attr === 'time_start' || attr === 'time_end' ?
formatTimestamp(parseISO8601Date(task.get(attr)))
: attr === 'status' ?
i18n(
'cluster_page.deployment_history.task_statuses.' + taskStatus,
{defaultValue: taskStatus}
)
:
task.get(attr)
}
</span>
</div>
);
})
}
</div>
</Popover>
@ -446,7 +462,7 @@ function renderNodeName(nodeId, isClickable = true) {
if (isClickable) {
return (
<button
className='btn btn-link'
className='btn btn-link btn-node-info'
onClick={() => ShowNodeInfoDialog.show({
node,
cluster: this.props.cluster,
@ -606,10 +622,17 @@ var DeploymentHistoryTable = React.createClass({
body={_.map(deploymentTasks,
(task) => DEPLOYMENT_TASK_ATTRIBUTES
.map((attr) => {
var taskStatus = task.get('status');
if (attr === 'time_start' || attr === 'time_end') {
return task.get(attr) ? formatTimestamp(parseISO8601Date(task.get(attr))) : '-';
} else if (attr === 'node_id') {
return renderNodeName.call(this, task.get('node_id'));
} else if (attr === 'status') {
return (
<span className={utils.classNames('status', taskStatus)}>
{i18n(ns + 'task_statuses.' + taskStatus, {defaultValue: taskStatus})}
</span>
);
} else {
return task.get(attr);
}

View File

@ -58,13 +58,18 @@ var WorkflowsTab = React.createClass({
name: 'graph_type',
label: i18n(ns + 'filter_by_graph_type'),
values: [],
options: () => _.uniq(this.props.cluster.get('deploymentGraphs').invokeMap('getType')),
options: _.map(
_.uniq(this.props.cluster.get('deploymentGraphs').invokeMap('getType')),
(type) => ({name: type, title: type})
),
addOptionsFilter: true
}, {
name: 'graph_level',
label: i18n(ns + 'filter_by_graph_level'),
values: [],
options: () => DEPLOYMENT_GRAPH_LEVELS
options: _.map(DEPLOYMENT_GRAPH_LEVELS,
(level) => ({name: level, title: i18n(ns + 'graph_levels.' + level)})
)
}
],
areFiltersVisible: false,
@ -184,9 +189,6 @@ var WorkflowsTab = React.createClass({
onChange={_.partial(this.changeFilter, filter.name)}
isOpen={openFilter === filter.name}
toggle={_.partial(this.toggleFilter, filter.name)}
options={
_.map(filter.options(), (value) => ({name: value, title: value}))
}
/>
)}
</div>
@ -197,10 +199,13 @@ var WorkflowsTab = React.createClass({
<div className='active-filters row' onClick={this.toggleFilters}>
<strong className='col-xs-1'>{i18n(ns + 'filter_by')}</strong>
<div className='col-xs-11'>
{_.map(filters, ({name, label, values}) => {
{_.map(filters, ({name, label, values, options}) => {
if (!values.length) return null;
return <div key={name}>
<strong>{label + ':'}</strong> <span>{values.join(', ')}</span>
<strong>{label + ':'}</strong> <span>{
_.map(values, (value) => _.find(options, {name: value}).title)
.join(', ')
}</span>
</div>;
})}
</div>
@ -269,9 +274,10 @@ var WorkflowsTab = React.createClass({
return <tr key={graph.id}>
<td>{graph.get('name') || '-'}</td>
<td className='level'>
{level}
&nbsp;
{level === 'plugin' && <span>({graphLevelModel.get('title')})</span>}
{i18n(
ns + 'graph_levels.' + level,
{pluginName: level === 'plugin' && graphLevelModel.get('title')}
)}
</td>
<td>
{level === 'cluster' &&

View File

@ -2383,16 +2383,25 @@ export var DeploymentTaskDetailsDialog = React.createClass({
<div>
{_.map(attributes, (attr) => {
if (_.isNull(task.get(attr))) return null;
var taskStatus = task.get('status');
return (
<div key={attr} className='row'>
<strong className='col-xs-3'>
{i18n('dialog.deployment_task_details.task.' + attr, {defaultValue: attr})}
</strong>
<span className='col-xs-9'>
<span className={utils.classNames('col-xs-9', attr, taskStatus)}>
{attr === 'node_id' ? nodeName :
this.renderTaskAttribute(
attr === 'time_start' || attr === 'time_end' ?
utils.formatTimestamp(utils.parseISO8601Date(task.get(attr))) : task.get(attr)
utils.formatTimestamp(utils.parseISO8601Date(task.get(attr)))
:
attr === 'status' ?
i18n(
'cluster_page.deployment_history.task_statuses.' + taskStatus,
{defaultValue: taskStatus}
)
:
task.get(attr)
)
}
</span>