From 00e284b921a3803b23fd10a74188c40e45e1f39a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gr=C3=A9goire=20Aubert?= Date: Mon, 25 Sep 2017 14:38:35 +0200 Subject: [PATCH] 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 --- .../js/apps/system/__tests__/utils-test.ts | 16 ++++++++ .../components/info-items/HealthCard.tsx | 13 +++--- .../components/info-items/HealthItem.tsx | 18 +++++++- .../components/info-items/SysInfoItem.tsx | 8 ++-- .../info-items/__tests__/HealthItem-test.tsx | 4 +- .../info-items/__tests__/SysInfoItem-test.tsx | 4 +- .../__snapshots__/HealthCard-test.tsx.snap | 11 +++-- .../__snapshots__/HealthItem-test.tsx.snap | 15 +++++-- .../__snapshots__/SysInfoItem-test.tsx.snap | 21 ++++++++-- .../src/main/js/apps/system/styles.css | 4 +- .../src/main/js/apps/system/utils.ts | 23 +++++++---- .../components/icons-components/CheckIcon.tsx | 41 +++++++++++++++++++ .../{CloseIcon.js => CloseIcon.tsx} | 13 +++--- .../js/components/icons-components/icons.js | 2 + .../resources/org/sonar/l10n/core.properties | 1 + 15 files changed, 152 insertions(+), 42 deletions(-) create mode 100644 server/sonar-web/src/main/js/components/icons-components/CheckIcon.tsx rename server/sonar-web/src/main/js/components/icons-components/{CloseIcon.js => CloseIcon.tsx} (88%) 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 { {this.props.name} + {showLogLevelWarning && ( + + {translate('system.log_level.warning.short')} + + )} {health && ( )} - {showLogLevelWarning && ( - - {translate('system.log_level.warning.short')} - - )} {open && (
0 && health !== HealthType.GREEN; + const statusIndicator = ( + + ); return (
{hasHealthCauses && healthCauses!.map((cause, idx) => ( ))} - + {name ? ( + + {statusIndicator} + + ) : ( + statusIndicator + )}
); } 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 ; } 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 ; + return ; } else { - return ; + return ; } } 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() + shallow( + + ) ).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(); - expect(wrapper.find('.icon-check')).toHaveLength(1); + expect(wrapper.find('CheckIcon')).toHaveLength(1); }); it('should render `false`', () => { const wrapper = mount(); - 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`] = ` system.log_level.warning.short @@ -27,13 +27,14 @@ exports[`should display the sysinfo detail 1`] = `
@@ -94,13 +96,14 @@ exports[`should show a main section and multiple sub sections 1`] = `
- + + + + +
`; 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 [ - + + + + ; + + 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') diff --git a/server/sonar-web/src/main/js/components/icons-components/CheckIcon.tsx b/server/sonar-web/src/main/js/components/icons-components/CheckIcon.tsx new file mode 100644 index 00000000000..487fac702cf --- /dev/null +++ b/server/sonar-web/src/main/js/components/icons-components/CheckIcon.tsx @@ -0,0 +1,41 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; + +interface Props { + className?: string; + size?: number; +} + +export default function CheckIcon({ className, size = 16 }: Props) { + return ( + + ; + + ); +} diff --git a/server/sonar-web/src/main/js/components/icons-components/CloseIcon.js b/server/sonar-web/src/main/js/components/icons-components/CloseIcon.tsx similarity index 88% rename from server/sonar-web/src/main/js/components/icons-components/CloseIcon.js rename to server/sonar-web/src/main/js/components/icons-components/CloseIcon.tsx index 7fb48b8b3f2..5ab53930909 100644 --- a/server/sonar-web/src/main/js/components/icons-components/CloseIcon.js +++ b/server/sonar-web/src/main/js/components/icons-components/CloseIcon.tsx @@ -17,15 +17,14 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -// @flow -import React from 'react'; +import * as React from 'react'; -/*:: -type Props = { className?: string, size?: number }; -*/ +interface Props { + className?: string; + size?: number; +} -export default function CloseIcon({ className, size = 16 } /*: Props */) { - /* eslint-disable max-len */ +export default function CloseIcon({ className, size = 16 }: Props) { return (