diff options
author | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-09-25 14:38:35 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2017-09-26 23:49:38 +0200 |
commit | 00e284b921a3803b23fd10a74188c40e45e1f39a (patch) | |
tree | 7218723b1e147e1b7c0fd1f1db79c850bdfe7edf /server/sonar-web/src/main/js/apps/system | |
parent | 051aa4a1defb22c593d368c26438575c12f0fe7a (diff) | |
download | sonarqube-00e284b921a3803b23fd10a74188c40e45e1f39a.tar.gz sonarqube-00e284b921a3803b23fd10a74188c40e45e1f39a.zip |
SONAR-9802 Apply UI feedback
* Add tooltips on health status
* Replace boolean icons with black check and close icons
* Move log level warning next to the title of the card
* Hide Plugins section
* Retrieve correctly log levels when sections are missing.
* Display State fields as Health status
* Update IT
Diffstat (limited to 'server/sonar-web/src/main/js/apps/system')
11 files changed, 102 insertions, 35 deletions
diff --git a/server/sonar-web/src/main/js/apps/system/__tests__/utils-test.ts b/server/sonar-web/src/main/js/apps/system/__tests__/utils-test.ts index b1e915f0370..98cea1804e5 100644 --- a/server/sonar-web/src/main/js/apps/system/__tests__/utils-test.ts +++ b/server/sonar-web/src/main/js/apps/system/__tests__/utils-test.ts @@ -67,4 +67,20 @@ describe('getSystemLogsLevel', () => { } as ClusterSysInfo) ).toBe('DEBUG'); }); + + it('should not fail if the log informations are not there yet', () => { + expect( + u.getSystemLogsLevel({ + System: { 'High Availability': true }, + 'Application Nodes': [{ Name: 'App 1' }, { Name: 'App 2' }] + } as ClusterSysInfo) + ).toBe('INFO'); + expect( + u.getSystemLogsLevel({ + System: { 'High Availability': true }, + 'Application Nodes': [{ 'Compute Engine Logging': {} }, { Name: 'App 2' }] + } as ClusterSysInfo) + ).toBe('INFO'); + expect(u.getSystemLogsLevel({ System: {} } as SysInfo)).toBe('INFO'); + }); }); diff --git a/server/sonar-web/src/main/js/apps/system/components/info-items/HealthCard.tsx b/server/sonar-web/src/main/js/apps/system/components/info-items/HealthCard.tsx index ff49fc75a83..ec8372f5802 100644 --- a/server/sonar-web/src/main/js/apps/system/components/info-items/HealthCard.tsx +++ b/server/sonar-web/src/main/js/apps/system/components/info-items/HealthCard.tsx @@ -65,19 +65,20 @@ export default class HealthCard extends React.PureComponent<Props, State> { <OpenCloseIcon className="little-spacer-right" open={open} /> {this.props.name} </span> + {showLogLevelWarning && ( + <span className="alert alert-danger spacer-left"> + {translate('system.log_level.warning.short')} + </span> + )} {health && ( <HealthItem biggerHealth={this.props.biggerHealth} - className="pull-right spacer-left" + className="pull-right" health={health} healthCauses={this.props.healthCauses} + name={this.props.name} /> )} - {showLogLevelWarning && ( - <span className="pull-right alert alert-danger"> - {translate('system.log_level.warning.short')} - </span> - )} </div> {open && ( <div diff --git a/server/sonar-web/src/main/js/apps/system/components/info-items/HealthItem.tsx b/server/sonar-web/src/main/js/apps/system/components/info-items/HealthItem.tsx index 2edc10805e0..933aa13b01a 100644 --- a/server/sonar-web/src/main/js/apps/system/components/info-items/HealthItem.tsx +++ b/server/sonar-web/src/main/js/apps/system/components/info-items/HealthItem.tsx @@ -21,24 +21,38 @@ import * as React from 'react'; import * as classNames from 'classnames'; import HealthCauseItem from './HealthCauseItem'; import StatusIndicator from '../../../../components/common/StatusIndicator'; +import Tooltip from '../../../../components/controls/Tooltip'; import { HealthType } from '../../../../api/system'; +import { translateWithParameters } from '../../../../helpers/l10n'; interface Props { biggerHealth?: boolean; + name?: string; className?: string; health: HealthType; healthCauses?: string[]; } -export default function HealthItem({ biggerHealth, className, health, healthCauses }: Props) { +export default function HealthItem({ biggerHealth, className, name, health, healthCauses }: Props) { const hasHealthCauses = healthCauses && healthCauses.length > 0 && health !== HealthType.GREEN; + const statusIndicator = ( + <StatusIndicator color={health.toLowerCase()} size={biggerHealth ? 'big' : undefined} /> + ); return ( <div className={classNames('system-info-health-info', className)}> {hasHealthCauses && healthCauses!.map((cause, idx) => ( <HealthCauseItem key={idx} className="spacer-right" health={health} healthCause={cause} /> ))} - <StatusIndicator color={health.toLowerCase()} size={biggerHealth ? 'big' : undefined} /> + {name ? ( + <Tooltip + overlay={translateWithParameters('system.current_health_of_x', name)} + placement="left"> + <span>{statusIndicator}</span> + </Tooltip> + ) : ( + statusIndicator + )} </div> ); } diff --git a/server/sonar-web/src/main/js/apps/system/components/info-items/SysInfoItem.tsx b/server/sonar-web/src/main/js/apps/system/components/info-items/SysInfoItem.tsx index 12876d75940..bd1751ec61e 100644 --- a/server/sonar-web/src/main/js/apps/system/components/info-items/SysInfoItem.tsx +++ b/server/sonar-web/src/main/js/apps/system/components/info-items/SysInfoItem.tsx @@ -19,6 +19,8 @@ */ import * as React from 'react'; import { map } from 'lodash'; +import CheckIcon from '../../../../components/icons-components/CheckIcon'; +import CloseIcon from '../../../../components/icons-components/CloseIcon'; import HealthItem from './HealthItem'; import { HealthType, SysValue, SysValueObject } from '../../../../api/system'; import { HEALTH_FIELD } from '../../utils'; @@ -29,7 +31,7 @@ interface Props { } export default function SysInfoItem({ name, value }: Props): JSX.Element { - if (name === HEALTH_FIELD) { + if (name === HEALTH_FIELD || name === 'State') { return <HealthItem className="no-margin" health={value as HealthType} />; } if (value instanceof Array) { @@ -47,9 +49,9 @@ export default function SysInfoItem({ name, value }: Props): JSX.Element { function BooleanItem({ value }: { value: boolean }) { if (value) { - return <i className="icon-check" />; + return <CheckIcon />; } else { - return <i className="icon-delete" />; + return <CloseIcon />; } } diff --git a/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/HealthItem-test.tsx b/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/HealthItem-test.tsx index 7f21d999a4e..5476278f613 100644 --- a/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/HealthItem-test.tsx +++ b/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/HealthItem-test.tsx @@ -24,7 +24,9 @@ import { HealthType } from '../../../../../api/system'; it('should render correctly', () => { expect( - shallow(<HealthItem biggerHealth={true} health={HealthType.RED} healthCauses={['foo']} />) + shallow( + <HealthItem biggerHealth={true} name="Foo" health={HealthType.RED} healthCauses={['foo']} /> + ) ).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/SysInfoItem-test.tsx b/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/SysInfoItem-test.tsx index 2761a2ddbf9..acbf8d43ab9 100644 --- a/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/SysInfoItem-test.tsx +++ b/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/SysInfoItem-test.tsx @@ -51,10 +51,10 @@ it('should render object correctly', () => { it('should render `true`', () => { const wrapper = mount(<SysInfoItem name="test" value={true} />); - expect(wrapper.find('.icon-check')).toHaveLength(1); + expect(wrapper.find('CheckIcon')).toHaveLength(1); }); it('should render `false`', () => { const wrapper = mount(<SysInfoItem name="test" value={false} />); - expect(wrapper.find('.icon-delete')).toHaveLength(1); + expect(wrapper.find('CloseIcon')).toHaveLength(1); }); diff --git a/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/__snapshots__/HealthCard-test.tsx.snap b/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/__snapshots__/HealthCard-test.tsx.snap index 6c054721b70..77afaf39ea2 100644 --- a/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/__snapshots__/HealthCard-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/__snapshots__/HealthCard-test.tsx.snap @@ -2,7 +2,7 @@ exports[`should display the log level alert 1`] = ` <span - className="pull-right alert alert-danger" + className="alert alert-danger spacer-left" > system.log_level.warning.short </span> @@ -27,13 +27,14 @@ exports[`should display the sysinfo detail 1`] = ` </span> <HealthItem biggerHealth={true} - className="pull-right spacer-left" + className="pull-right" health="RED" healthCauses={ Array [ "foo", ] } + name="Foobar" /> </div> <div @@ -63,13 +64,14 @@ exports[`should render correctly 1`] = ` </span> <HealthItem biggerHealth={false} - className="pull-right spacer-left" + className="pull-right" health="RED" healthCauses={ Array [ "foo", ] } + name="Foobar" /> </div> </li> @@ -94,13 +96,14 @@ exports[`should show a main section and multiple sub sections 1`] = ` </span> <HealthItem biggerHealth={false} - className="pull-right spacer-left" + className="pull-right" health="RED" healthCauses={ Array [ "foo", ] } + name="Foobar" /> </div> <div diff --git a/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/__snapshots__/HealthItem-test.tsx.snap b/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/__snapshots__/HealthItem-test.tsx.snap index eafb250bdd1..81f4aa9ba6a 100644 --- a/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/__snapshots__/HealthItem-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/__snapshots__/HealthItem-test.tsx.snap @@ -29,10 +29,17 @@ exports[`should render correctly 1`] = ` health="RED" healthCause="foo" /> - <StatusIndicator - color="red" - size="big" - /> + <Tooltip + overlay="system.current_health_of_x.Foo" + placement="left" + > + <span> + <StatusIndicator + color="red" + size="big" + /> + </span> + </Tooltip> </div> `; diff --git a/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/__snapshots__/SysInfoItem-test.tsx.snap b/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/__snapshots__/SysInfoItem-test.tsx.snap index a1ff67c3506..b02b9854bdf 100644 --- a/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/__snapshots__/SysInfoItem-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/__snapshots__/SysInfoItem-test.tsx.snap @@ -117,9 +117,24 @@ Array [ <BooleanItem value={true} > - <i - className="icon-check" - /> + <CheckIcon> + <svg + height={16} + viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + > + <path + d="M14.92 4.804q0 0.357-0.25 0.607l-7.679 7.679q-0.25 0.25-0.607 0.25t-0.607-0.25l-4.446-4.446q-0.25-0.25-0.25-0.607t0.25-0.607l1.214-1.214q0.25-0.25 0.607-0.25t0.607 0.25l2.625 2.634 5.857-5.866q0.25-0.25 0.607-0.25t0.607 0.25l1.214 1.214q0.25 0.25 0.25 0.607z" + style={ + Object { + "fill": "currentColor", + } + } + /> + ; + </svg> + </CheckIcon> </BooleanItem> </SysInfoItem> </td> diff --git a/server/sonar-web/src/main/js/apps/system/styles.css b/server/sonar-web/src/main/js/apps/system/styles.css index f34dc3fa394..e9b58438149 100644 --- a/server/sonar-web/src/main/js/apps/system/styles.css +++ b/server/sonar-web/src/main/js/apps/system/styles.css @@ -22,7 +22,9 @@ } .system-info-health-card .boxed-group-header > .alert { - margin-top: -6px; + display: inline-block; + margin-bottom: -3px; + margin-top: -3px; } .system-info-health-card .boxed-group-inner { diff --git a/server/sonar-web/src/main/js/apps/system/utils.ts b/server/sonar-web/src/main/js/apps/system/utils.ts index 5d98c9e74f8..5514ae4e705 100644 --- a/server/sonar-web/src/main/js/apps/system/utils.ts +++ b/server/sonar-web/src/main/js/apps/system/utils.ts @@ -42,9 +42,11 @@ export const LOGS_LEVELS = ['INFO', 'DEBUG', 'TRACE']; export const HA_FIELD = 'High Availability'; export const HEALTH_FIELD = 'Health'; export const HEALTHCAUSES_FIELD = 'Health Causes'; +export const PLUGINS_FIELD = 'Plugins'; +export const SETTINGS_FIELD = 'Settings'; export function ignoreInfoFields(sysInfoObject: SysValueObject): SysValueObject { - return omit(sysInfoObject, [HEALTH_FIELD, HEALTHCAUSES_FIELD, 'Name', 'Settings']); + return omit(sysInfoObject, [HEALTH_FIELD, HEALTHCAUSES_FIELD, 'Name', SETTINGS_FIELD]); } export function getHealth(sysInfoObject: SysValueObject): HealthType { @@ -55,18 +57,21 @@ export function getHealthCauses(sysInfoObject: SysValueObject): string[] { return sysInfoObject[HEALTHCAUSES_FIELD] as string[]; } -export function getLogsLevel(sysInfoObject: SysValueObject): string { - if (sysInfoObject['Web Logging']) { +export function getLogsLevel(sysInfoObject?: SysValueObject): string { + if (!sysInfoObject) { + return LOGS_LEVELS[0]; + } + if (sysInfoObject['Web Logging'] || sysInfoObject['Compute Engine Logging']) { return sortBy( [ - (sysInfoObject as NodeInfo)['Compute Engine Logging']['Logs Level'], - (sysInfoObject as NodeInfo)['Web Logging']['Logs Level'] + getLogsLevel((sysInfoObject as NodeInfo)['Web Logging']), + getLogsLevel((sysInfoObject as NodeInfo)['Compute Engine Logging']) ], logLevel => LOGS_LEVELS.indexOf(logLevel) )[1]; } if (sysInfoObject['System']) { - return (sysInfoObject as SysInfo)['System']['Logs Level']; + return getLogsLevel((sysInfoObject as SysInfo)['System']); } return (sysInfoObject['Logs Level'] || LOGS_LEVELS[0]) as string; } @@ -110,9 +115,9 @@ export function getClusterMainCardSection(sysInfoData: ClusterSysInfo): SysValue ...sysInfoData['System'], ...omit(sysInfoData, [ 'Application Nodes', - 'Plugins', + PLUGINS_FIELD, 'Search Nodes', - 'Settings', + SETTINGS_FIELD, 'Statistics', 'System' ]) @@ -126,7 +131,7 @@ export function getStandaloneMainSections(sysInfoData: SysInfo): SysValueObject sysInfoData, (value, key) => value == null || - ['Plugins', 'Settings', 'Statistics', 'System'].includes(key) || + [PLUGINS_FIELD, SETTINGS_FIELD, 'Statistics', 'System'].includes(key) || key.startsWith('Compute Engine') || key.startsWith('Search') || key.startsWith('Web') |