aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/system
diff options
context:
space:
mode:
authorWouter Admiraal <wouter.admiraal@sonarsource.com>2019-05-07 13:01:01 +0200
committerSonarTech <sonartech@sonarsource.com>2019-05-09 20:21:09 +0200
commit2f02c40ef393c1cd20adc69d53409d31fc739ef8 (patch)
tree0c8852c557db9a29ebfb2e2e7177ab22ca05eaa6 /server/sonar-web/src/main/js/apps/system
parent3831ff61b755d3e419d46d2491afd8b037bc5089 (diff)
downloadsonarqube-2f02c40ef393c1cd20adc69d53409d31fc739ef8.tar.gz
sonarqube-2f02c40ef393c1cd20adc69d53409d31fc739ef8.zip
SONAR-11938 Remove Server ID and Version from system information
Diffstat (limited to 'server/sonar-web/src/main/js/apps/system')
-rw-r--r--server/sonar-web/src/main/js/apps/system/__tests__/utils-test.ts229
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/App.tsx33
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/ClusterSysInfos.tsx9
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/PageHeader.tsx51
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/StandaloneSysInfos.tsx3
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/__tests__/ClusterSysInfos-test.tsx114
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/__tests__/PageHeader-test.tsx45
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/__tests__/StandaloneSysInfos-test.tsx17
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/ClusterSysInfos-test.tsx.snap25
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/PageHeader-test.tsx.snap67
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/StandaloneSysInfos-test.tsx.snap59
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/info-items/HealthCard.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/info-items/HealthCauseItem.tsx5
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/info-items/HealthItem.tsx5
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/info-items/Section.tsx3
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/info-items/SysInfoItem.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/HealthCard-test.tsx3
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/HealthCauseItem-test.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/HealthItem-test.tsx15
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeForm.tsx3
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeIntermediate.tsx3
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeItem.tsx3
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeNotif.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/system/styles.css7
-rw-r--r--server/sonar-web/src/main/js/apps/system/utils.ts202
25 files changed, 622 insertions, 308 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 d94d51599ec..22247758f54 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
@@ -17,8 +17,9 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+/* eslint-disable sonarjs/no-duplicate-string */
import * as u from '../utils';
-import { ClusterSysInfo, SysInfo, SystemUpgrade } from '../../../api/system';
+import { mockClusterSysInfo, mockStandaloneSysInfo } from '../../../helpers/testMocks';
describe('parseQuery', () => {
it('should correctly parse the expand array', () => {
@@ -44,44 +45,30 @@ describe('groupSections', () => {
});
describe('getSystemLogsLevel', () => {
- it('should correctly return log level for standalone mode', () => {
- expect(u.getSystemLogsLevel({ System: { 'Logs Level': 'FOO' } } as SysInfo)).toBe('FOO');
- expect(u.getSystemLogsLevel({} as SysInfo)).toBe('INFO');
- expect(u.getSystemLogsLevel()).toBe('INFO');
+ it('should correctly return the worst log level for standalone mode', () => {
+ expect(u.getSystemLogsLevel(mockStandaloneSysInfo())).toBe('DEBUG');
});
it('should return the worst log level for cluster mode', () => {
- expect(
- u.getSystemLogsLevel({
- System: { 'High Availability': true },
- 'Application Nodes': [
- {
- 'Compute Engine Logging': { 'Logs Level': 'DEBUG' },
- 'Web Logging': { 'Logs Level': 'INFO' }
- },
- {
- 'Compute Engine Logging': { 'Logs Level': 'INFO' },
- 'Web Logging': { 'Logs Level': 'INFO' }
- }
- ]
- } as ClusterSysInfo)
- ).toBe('DEBUG');
+ expect(u.getSystemLogsLevel(mockClusterSysInfo())).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)
+ u.getSystemLogsLevel(
+ mockClusterSysInfo({
+ 'Application Nodes': [{ Name: 'App 1' }, { Name: 'App 2' }]
+ })
+ )
).toBe('INFO');
expect(
- u.getSystemLogsLevel({
- System: { 'High Availability': true },
- 'Application Nodes': [{ 'Compute Engine Logging': {} }, { Name: 'App 2' }]
- } as any)
+ u.getSystemLogsLevel(
+ mockClusterSysInfo({
+ 'Application Nodes': [{ 'Compute Engine Logging': {} }, { Name: 'App 2' }]
+ })
+ )
).toBe('INFO');
- expect(u.getSystemLogsLevel({ System: {} } as SysInfo)).toBe('INFO');
+ expect(u.getSystemLogsLevel({} as T.SysInfoStandalone)).toBe('INFO');
});
});
@@ -93,7 +80,7 @@ describe('sortUpgrades', () => {
{ version: '5.10' },
{ version: '5.1' },
{ version: '5.4' }
- ] as SystemUpgrade[])
+ ] as T.SystemUpgrade[])
).toEqual([{ version: '5.10' }, { version: '5.4.2' }, { version: '5.4' }, { version: '5.1' }]);
expect(
u.sortUpgrades([
@@ -101,7 +88,7 @@ describe('sortUpgrades', () => {
{ version: '5.1.2' },
{ version: '6.0' },
{ version: '6.9' }
- ] as SystemUpgrade[])
+ ] as T.SystemUpgrade[])
).toEqual([{ version: '6.9' }, { version: '6.0' }, { version: '5.10' }, { version: '5.1.2' }]);
});
});
@@ -114,7 +101,7 @@ describe('groupUpgrades', () => {
{ version: '5.4.2' },
{ version: '5.4' },
{ version: '5.1' }
- ] as SystemUpgrade[])
+ ] as T.SystemUpgrade[])
).toEqual([
[{ version: '5.10' }, { version: '5.4.2' }, { version: '5.4' }, { version: '5.1' }]
]);
@@ -125,10 +112,186 @@ describe('groupUpgrades', () => {
{ version: '6.0' },
{ version: '5.10' },
{ version: '5.4.2' }
- ] as SystemUpgrade[])
+ ] as T.SystemUpgrade[])
).toEqual([
[{ version: '6.9' }, { version: '6.7' }, { version: '6.0' }],
[{ version: '5.10' }, { version: '5.4.2' }]
]);
});
});
+
+describe('isCluster', () => {
+ it('should return the correct information', () => {
+ expect(u.isCluster(mockClusterSysInfo())).toBe(true);
+ expect(u.isCluster(mockStandaloneSysInfo())).toBe(false);
+ });
+});
+
+describe('isLogInfoBlock', () => {
+ it('should return the correct information', () => {
+ expect(u.isLogInfoBlock(mockStandaloneSysInfo().System)).toBe(false);
+ expect(u.isLogInfoBlock(mockStandaloneSysInfo()['Web Logging'])).toBe(true);
+ });
+});
+
+describe('hasLoggingInfo', () => {
+ it('should return the correct information', () => {
+ expect(u.hasLoggingInfo(mockStandaloneSysInfo())).toBe(true);
+ expect(u.hasLoggingInfo(mockClusterSysInfo()['Application Nodes'][0])).toBe(true);
+ expect(u.hasLoggingInfo(mockClusterSysInfo())).toBe(false);
+ });
+});
+
+describe('getStandaloneSecondarySections', () => {
+ it('should return the correct information', () => {
+ expect(Object.keys(u.getStandaloneSecondarySections(mockStandaloneSysInfo()))).toEqual(
+ expect.arrayContaining(['Compute Engine', 'Search Engine', 'Web'])
+ );
+ expect(Object.keys(u.getStandaloneSecondarySections(mockClusterSysInfo()))).toEqual(
+ expect.arrayContaining(['Compute Engine', 'Search Engine', 'Web'])
+ );
+ });
+});
+
+describe('getStandaloneMainSections', () => {
+ it('should return the correct information', () => {
+ expect(Object.keys(u.getStandaloneMainSections(mockStandaloneSysInfo()))).toEqual(
+ expect.arrayContaining([
+ 'Server ID',
+ 'High Availability',
+ 'Health',
+ 'Health Causes',
+ 'Database'
+ ])
+ );
+ });
+});
+
+describe('getClusterMainCardSection', () => {
+ it('should return the correct information', () => {
+ expect(Object.keys(u.getClusterMainCardSection(mockClusterSysInfo()))).toEqual(
+ expect.arrayContaining([
+ 'Server ID',
+ 'High Availability',
+ 'Lines of Code',
+ 'Health',
+ 'Health Causes',
+ 'Database',
+ 'Compute Engine Tasks',
+ 'Search State',
+ 'Search Indexes'
+ ])
+ );
+ });
+});
+
+describe('getSearchNodes', () => {
+ it('should return the correct information', () => {
+ expect(
+ u.getSearchNodes(
+ mockClusterSysInfo({
+ 'Search Nodes': [{ Name: 'searchnode1' }]
+ })
+ )
+ ).toEqual([{ Name: 'searchnode1' }]);
+ });
+});
+
+describe('getAppNodes', () => {
+ it('should return the correct information', () => {
+ expect(
+ u.getAppNodes(
+ mockClusterSysInfo({
+ 'Application Nodes': [{ Name: 'appnode1' }]
+ })
+ )
+ ).toEqual([{ Name: 'appnode1' }]);
+ });
+});
+
+describe('getNodeName', () => {
+ it('should return the correct information', () => {
+ expect(u.getNodeName({ Name: 'Foo' })).toEqual('Foo');
+ });
+});
+
+describe('getHealthCauses', () => {
+ it('should return the correct information', () => {
+ expect(u.getHealthCauses({ 'Health Causes': ['Foo'] } as T.SysInfoBase)).toEqual(['Foo']);
+ });
+});
+
+describe('getHealth', () => {
+ it('should return the correct information', () => {
+ expect(u.getHealth({ Health: 'GREEN' } as T.SysInfoBase)).toEqual('GREEN');
+ });
+});
+
+describe('getLogsLevel', () => {
+ it('should return the correct information, if available', () => {
+ expect(u.getLogsLevel({ 'Compute Engine Logging': { 'Logs Level': 'TRACE' } })).toEqual(
+ 'TRACE'
+ );
+ });
+
+ it('should return the worst level', () => {
+ expect(
+ u.getLogsLevel({
+ 'Web Logging': { 'Logs Level': 'DEBUG' },
+ 'Compute Engine Logging': { 'Logs Level': 'TRACE' }
+ })
+ ).toEqual('TRACE');
+ });
+
+ it('should return the default level if no information is provided', () => {
+ expect(u.getLogsLevel()).toEqual('INFO');
+ });
+});
+
+describe('getServerId', () => {
+ it('should return the correct information, if available', () => {
+ expect(u.getServerId(mockStandaloneSysInfo({ System: { 'Server ID': 'foo-bar' } }))).toEqual(
+ 'foo-bar'
+ );
+ });
+
+ it('should return undefined if no information is available', () => {
+ expect(u.getServerId(mockStandaloneSysInfo({ System: {} }))).toBeUndefined();
+ });
+});
+
+describe('getVersion', () => {
+ it('should return the correct information, if available', () => {
+ expect(u.getVersion(mockStandaloneSysInfo({ System: { Version: '1.0' } }))).toEqual('1.0');
+ });
+
+ it('should return undefined if no information is available', () => {
+ expect(u.getVersion(mockStandaloneSysInfo({ System: {} }))).toBeUndefined();
+ });
+});
+
+describe('getClusterVersion', () => {
+ it('should return the correct information, if available', () => {
+ expect(
+ u.getClusterVersion(
+ mockClusterSysInfo({
+ 'Application Nodes': [{ System: { Version: '1.0' } }]
+ })
+ )
+ ).toEqual('1.0');
+ });
+
+ it('should return undefined if no information is available', () => {
+ expect(
+ u.getClusterVersion(mockClusterSysInfo({ 'Application Nodes': [{ System: {} }] }))
+ ).toBeUndefined();
+ expect(
+ u.getClusterVersion(
+ mockClusterSysInfo({
+ 'Application Nodes': [],
+ System: { Version: '1.0' }
+ })
+ )
+ ).toBeUndefined();
+ });
+});
diff --git a/server/sonar-web/src/main/js/apps/system/components/App.tsx b/server/sonar-web/src/main/js/apps/system/components/App.tsx
index b90b28493f3..07cec002e46 100644
--- a/server/sonar-web/src/main/js/apps/system/components/App.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/App.tsx
@@ -26,14 +26,16 @@ import StandaloneSysInfos from './StandaloneSysInfos';
import SystemUpgradeNotif from './system-upgrade/SystemUpgradeNotif';
import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
import { translate } from '../../../helpers/l10n';
-import { ClusterSysInfo, getSystemInfo, SysInfo } from '../../../api/system';
+import { getSystemInfo } from '../../../api/system';
import {
getServerId,
getSystemLogsLevel,
isCluster,
parseQuery,
Query,
- serializeQuery
+ serializeQuery,
+ getVersion,
+ getClusterVersion
} from '../utils';
import '../styles.css';
@@ -41,7 +43,7 @@ type Props = WithRouterProps;
interface State {
loading: boolean;
- sysInfoData?: SysInfo;
+ sysInfoData?: T.SysInfoCluster | T.SysInfoStandalone;
}
class App extends React.PureComponent<Props, State> {
@@ -60,7 +62,7 @@ class App extends React.PureComponent<Props, State> {
fetchSysInfo = () => {
this.setState({ loading: true });
getSystemInfo().then(
- (sysInfoData: SysInfo) => {
+ sysInfoData => {
if (this.mounted) {
this.setState({ loading: false, sysInfoData });
}
@@ -100,7 +102,7 @@ class App extends React.PureComponent<Props, State> {
return (
<ClusterSysInfos
expandedCards={query.expandedCards}
- sysInfoData={sysInfoData as ClusterSysInfo}
+ sysInfoData={sysInfoData}
toggleCard={this.toggleSysInfoCards}
/>
);
@@ -121,14 +123,19 @@ class App extends React.PureComponent<Props, State> {
<Suggestions suggestions="system_info" />
<Helmet title={translate('system_info.page')} />
<SystemUpgradeNotif />
- <PageHeader
- isCluster={isCluster(sysInfoData)}
- loading={loading}
- logLevel={getSystemLogsLevel(sysInfoData)}
- onLogLevelChange={this.fetchSysInfo}
- serverId={getServerId(sysInfoData)}
- showActions={sysInfoData !== undefined}
- />
+ {sysInfoData && (
+ <PageHeader
+ isCluster={isCluster(sysInfoData)}
+ loading={loading}
+ logLevel={getSystemLogsLevel(sysInfoData)}
+ onLogLevelChange={this.fetchSysInfo}
+ serverId={getServerId(sysInfoData)}
+ showActions={sysInfoData !== undefined}
+ version={
+ isCluster(sysInfoData) ? getClusterVersion(sysInfoData) : getVersion(sysInfoData)
+ }
+ />
+ )}
{this.renderSysInfo()}
</div>
);
diff --git a/server/sonar-web/src/main/js/apps/system/components/ClusterSysInfos.tsx b/server/sonar-web/src/main/js/apps/system/components/ClusterSysInfos.tsx
index 7231c753b25..2a86c77b1c3 100644
--- a/server/sonar-web/src/main/js/apps/system/components/ClusterSysInfos.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/ClusterSysInfos.tsx
@@ -21,7 +21,6 @@ import * as React from 'react';
import { sortBy } from 'lodash';
import HealthCard from './info-items/HealthCard';
import { translate } from '../../../helpers/l10n';
-import { ClusterSysInfo } from '../../../api/system';
import {
getAppNodes,
getHealth,
@@ -34,7 +33,7 @@ import {
interface Props {
expandedCards: string[];
- sysInfoData: ClusterSysInfo;
+ sysInfoData: T.SysInfoCluster;
toggleCard: (toggledCard: string) => void;
}
@@ -54,7 +53,7 @@ export default function ClusterSysInfos({ expandedCards, sysInfoData, toggleCard
<li className="note system-info-health-title">
{translate('system.application_nodes_title')}
</li>
- {sortBy(getAppNodes(sysInfoData), getNodeName).map(node => (
+ {sortBy(getAppNodes(sysInfoData), getNodeName).map((node: T.SysInfoAppNode) => (
<HealthCard
health={getHealth(node)}
healthCauses={getHealthCauses(node)}
@@ -66,10 +65,8 @@ export default function ClusterSysInfos({ expandedCards, sysInfoData, toggleCard
/>
))}
<li className="note system-info-health-title">{translate('system.search_nodes_title')}</li>
- {sortBy(getSearchNodes(sysInfoData), getNodeName).map(node => (
+ {sortBy(getSearchNodes(sysInfoData), getNodeName).map((node: T.SysInfoSearchNode) => (
<HealthCard
- health={getHealth(node)}
- healthCauses={getHealthCauses(node)}
key={getNodeName(node)}
name={getNodeName(node)}
onClick={toggleCard}
diff --git a/server/sonar-web/src/main/js/apps/system/components/PageHeader.tsx b/server/sonar-web/src/main/js/apps/system/components/PageHeader.tsx
index bc55969fc2a..3816eb2cb02 100644
--- a/server/sonar-web/src/main/js/apps/system/components/PageHeader.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/PageHeader.tsx
@@ -19,36 +19,71 @@
*/
import * as React from 'react';
import PageActions from './PageActions';
+import ClipboardButton from '../../../components/controls/ClipboardButton';
import { translate } from '../../../helpers/l10n';
+import { toShortNotSoISOString } from '../../../helpers/dates';
-interface Props {
+export interface Props {
isCluster: boolean;
loading: boolean;
logLevel: string;
onLogLevelChange: () => void;
serverId?: string;
showActions: boolean;
+ version?: string;
}
export default function PageHeader(props: Props) {
+ const { isCluster, loading, logLevel, serverId, showActions, version } = props;
return (
<header className="page-header">
<h1 className="page-title">{translate('system_info.page')}</h1>
- {props.showActions && (
+ {showActions && (
<PageActions
- canDownloadLogs={!props.isCluster}
- canRestart={!props.isCluster}
- cluster={props.isCluster}
- logLevel={props.logLevel}
+ canDownloadLogs={!isCluster}
+ canRestart={!isCluster}
+ cluster={isCluster}
+ logLevel={logLevel}
onLogLevelChange={props.onLogLevelChange}
- serverId={props.serverId}
+ serverId={serverId}
/>
)}
- {props.loading && (
+ {loading && (
<div className="page-actions">
<i className="spinner" />
</div>
)}
+ {serverId && version && (
+ <div className="system-info-copy-paste-id-info boxed-group display-flex-center">
+ <div className="flex-1">
+ <table className="width-100">
+ <tbody>
+ <tr>
+ <th>
+ <strong>{translate('system.server_id')}</strong>
+ </th>
+ <td>{serverId}</td>
+ </tr>
+ <tr>
+ <th>
+ <strong>{translate('system.version')}</strong>
+ </th>
+ <td>{version}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <ClipboardButton
+ className="flex-0"
+ copyValue={`SonarQube ID information
+Server ID: ${serverId}
+Version: ${version}
+Date: ${toShortNotSoISOString(Date.now())}
+`}
+ label={translate('system.copy_id_info')}
+ />
+ </div>
+ )}
</header>
);
}
diff --git a/server/sonar-web/src/main/js/apps/system/components/StandaloneSysInfos.tsx b/server/sonar-web/src/main/js/apps/system/components/StandaloneSysInfos.tsx
index e0ba16fe754..adb9db52ec5 100644
--- a/server/sonar-web/src/main/js/apps/system/components/StandaloneSysInfos.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/StandaloneSysInfos.tsx
@@ -20,7 +20,6 @@
import * as React from 'react';
import { map } from 'lodash';
import HealthCard from './info-items/HealthCard';
-import { SysInfo } from '../../../api/system';
import {
getHealth,
getHealthCauses,
@@ -31,7 +30,7 @@ import {
interface Props {
expandedCards: string[];
- sysInfoData: SysInfo;
+ sysInfoData: T.SysInfoStandalone;
toggleCard: (toggledCard: string) => void;
}
diff --git a/server/sonar-web/src/main/js/apps/system/components/__tests__/ClusterSysInfos-test.tsx b/server/sonar-web/src/main/js/apps/system/components/__tests__/ClusterSysInfos-test.tsx
index ed0b62b7dc3..395f5bf30ac 100644
--- a/server/sonar-web/src/main/js/apps/system/components/__tests__/ClusterSysInfos-test.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/__tests__/ClusterSysInfos-test.tsx
@@ -20,78 +20,74 @@
import * as React from 'react';
import { shallow } from 'enzyme';
import ClusterSysInfos from '../ClusterSysInfos';
-import { ClusterSysInfo, HealthType } from '../../../../api/system';
-
-const sysInfoData: ClusterSysInfo = {
- Health: HealthType.RED,
- 'Health Causes': ['Database down'],
- 'Application Nodes': [
- {
- Name: 'Bar',
- Health: HealthType.GREEN,
- 'Health Causes': [],
- 'Compute Engine Logging': { 'Logs Level': 'INFO' },
- 'Web Logging': { 'Logs Level': 'INFO' }
- }
- ],
- 'Search Nodes': [
- {
- Name: 'Baz',
- Health: HealthType.YELLOW,
- 'Health Causes': [],
- 'Compute Engine Logging': { 'Logs Level': 'INFO' },
- 'Web Logging': { 'Logs Level': 'INFO' }
- }
- ],
- System: {
- 'High Availability': true,
- 'Logs Level': 'INFO',
- 'Server ID': 'MyServerId'
- }
-};
+import { mockClusterSysInfo } from '../../../../helpers/testMocks';
it('should render correctly', () => {
expect(
- getWrapper({
- sysInfoData: {
- ...sysInfoData,
+ shallowRender(
+ mockClusterSysInfo({
+ sysInfoData: {
+ Health: 'RED',
+ 'Health Causes': ['Database down'],
+ 'Application Nodes': [
+ {
+ Name: 'Foo',
+ Health: 'GREEN',
+ 'Health Causes': [],
+ 'Compute Engine Logging': { 'Logs Level': 'INFO' },
+ 'Web Logging': { 'Logs Level': 'INFO' }
+ },
+ {
+ Name: 'Bar',
+ Health: 'RED',
+ 'Health Causes': [],
+ 'Compute Engine Logging': { 'Logs Level': 'INFO' },
+ 'Web Logging': { 'Logs Level': 'DEBUG' }
+ },
+ {
+ Name: 'Baz',
+ Health: 'YELLOW',
+ 'Health Causes': [],
+ 'Compute Engine Logging': { 'Logs Level': 'TRACE' },
+ 'Web Logging': { 'Logs Level': 'DEBUG' }
+ }
+ ]
+ }
+ })
+ ).find('HealthCard')
+ ).toHaveLength(4);
+});
+
+it('should support more than two nodes', () => {
+ expect(shallowRender()).toMatchSnapshot();
+});
+
+function shallowRender(props = {}) {
+ return shallow(
+ <ClusterSysInfos
+ expandedCards={['System', 'Foo']}
+ sysInfoData={mockClusterSysInfo({
+ Health: 'RED',
+ 'Health Causes': ['Database down'],
'Application Nodes': [
{
- Name: 'Foo',
- Health: HealthType.GREEN,
- 'Health Causes': [],
- 'Compute Engine Logging': { 'Logs Level': 'INFO' },
- 'Web Logging': { 'Logs Level': 'INFO' }
- },
- {
Name: 'Bar',
- Health: HealthType.RED,
+ Health: 'GREEN',
'Health Causes': [],
'Compute Engine Logging': { 'Logs Level': 'INFO' },
- 'Web Logging': { 'Logs Level': 'DEBUG' }
- },
+ 'Web Logging': { 'Logs Level': 'INFO' }
+ }
+ ],
+ 'Search Nodes': [
{
Name: 'Baz',
- Health: HealthType.YELLOW,
+ Health: 'YELLOW',
'Health Causes': [],
- 'Compute Engine Logging': { 'Logs Level': 'TRACE' },
- 'Web Logging': { 'Logs Level': 'DEBUG' }
+ 'Compute Engine Logging': { 'Logs Level': 'INFO' },
+ 'Web Logging': { 'Logs Level': 'INFO' }
}
]
- }
- }).find('HealthCard')
- ).toHaveLength(5);
-});
-
-it('should support more than two nodes', () => {
- expect(getWrapper()).toMatchSnapshot();
-});
-
-function getWrapper(props = {}) {
- return shallow(
- <ClusterSysInfos
- expandedCards={['System', 'Foo']}
- sysInfoData={sysInfoData}
+ })}
toggleCard={() => {}}
{...props}
/>
diff --git a/server/sonar-web/src/main/js/apps/system/components/__tests__/PageHeader-test.tsx b/server/sonar-web/src/main/js/apps/system/components/__tests__/PageHeader-test.tsx
index 0164cc044eb..382169ee3b9 100644
--- a/server/sonar-web/src/main/js/apps/system/components/__tests__/PageHeader-test.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/__tests__/PageHeader-test.tsx
@@ -19,32 +19,27 @@
*/
import * as React from 'react';
import { shallow } from 'enzyme';
-import PageHeader from '../PageHeader';
+import PageHeader, { Props } from '../PageHeader';
+
+jest.mock('../../../../helpers/dates', () => ({
+ toShortNotSoISOString: () => '2019-01-01'
+}));
it('should render correctly', () => {
- expect(
- shallow(
- <PageHeader
- isCluster={true}
- loading={false}
- logLevel="INFO"
- onLogLevelChange={() => {}}
- showActions={true}
- />
- )
- ).toMatchSnapshot();
+ expect(shallowRender()).toMatchSnapshot();
+ expect(shallowRender({ loading: true, showActions: false })).toMatchSnapshot();
+ expect(shallowRender({ serverId: 'foo-bar', version: '7.7.0.1234' })).toMatchSnapshot();
});
-it('should show a loading spinner and no actions', () => {
- expect(
- shallow(
- <PageHeader
- isCluster={true}
- loading={true}
- logLevel="INFO"
- onLogLevelChange={() => {}}
- showActions={false}
- />
- )
- ).toMatchSnapshot();
-});
+function shallowRender(props: Partial<Props> = {}) {
+ return shallow(
+ <PageHeader
+ isCluster={true}
+ loading={false}
+ logLevel="INFO"
+ onLogLevelChange={jest.fn()}
+ showActions={true}
+ {...props}
+ />
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/system/components/__tests__/StandaloneSysInfos-test.tsx b/server/sonar-web/src/main/js/apps/system/components/__tests__/StandaloneSysInfos-test.tsx
index 69a40917cb5..e7bec64929e 100644
--- a/server/sonar-web/src/main/js/apps/system/components/__tests__/StandaloneSysInfos-test.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/__tests__/StandaloneSysInfos-test.tsx
@@ -20,20 +20,7 @@
import * as React from 'react';
import { shallow } from 'enzyme';
import StandaloneSysInfos from '../StandaloneSysInfos';
-import { HealthType, SysInfo } from '../../../../api/system';
-
-const sysInfoData: SysInfo = {
- Health: HealthType.RED,
- 'Health Causes': ['Database down'],
- 'Web JVM': { 'Max Memory': '2Gb' },
- 'Compute Engine': { Pending: 4 },
- Search: { 'Number of Nodes': 1 },
- System: {
- 'High Availability': true,
- 'Logs Level': 'DEBUG',
- 'Server ID': 'MyServerId'
- }
-};
+import { mockStandaloneSysInfo } from '../../../../helpers/testMocks';
it('should render correctly', () => {
expect(getWrapper()).toMatchSnapshot();
@@ -43,7 +30,7 @@ function getWrapper(props = {}) {
return shallow(
<StandaloneSysInfos
expandedCards={['Compute Engine', 'Foo']}
- sysInfoData={sysInfoData}
+ sysInfoData={mockStandaloneSysInfo({ Health: 'RED', 'Health Causes': ['Database down'] })}
toggleCard={() => {}}
{...props}
/>
diff --git a/server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/ClusterSysInfos-test.tsx.snap b/server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/ClusterSysInfos-test.tsx.snap
index 580f6979534..a186f4110d3 100644
--- a/server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/ClusterSysInfos-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/ClusterSysInfos-test.tsx.snap
@@ -15,9 +15,28 @@ exports[`should support more than two nodes 1`] = `
open={true}
sysInfoData={
Object {
+ "Compute Engine Tasks": Object {
+ "Total In Progress": 0,
+ "Total Pending": 0,
+ },
+ "Database": Object {
+ "Database": "PostgreSQL",
+ "Database Version": "10.3",
+ "Driver": "PostgreSQL JDBC Driver",
+ "Driver Version": "42.2.5",
+ "URL": "jdbc:postgresql://localhost/sonar",
+ "Username": "sonar",
+ },
"High Availability": true,
- "Logs Level": "INFO",
- "Server ID": "MyServerId",
+ "Lines of Code": "989,880",
+ "Search Indexes": Object {
+ "Index components - Docs": 30445,
+ "Index components - Shards": 10,
+ },
+ "Search State": Object {
+ "Nodes": 3,
+ "State": "GREEN",
+ },
}
}
/>
@@ -50,8 +69,6 @@ exports[`should support more than two nodes 1`] = `
system.search_nodes_title
</li>
<HealthCard
- health="YELLOW"
- healthCauses={Array []}
key="Baz"
name="Baz"
onClick={[Function]}
diff --git a/server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/PageHeader-test.tsx.snap b/server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/PageHeader-test.tsx.snap
index 39f93da4322..84f459faba7 100644
--- a/server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/PageHeader-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/PageHeader-test.tsx.snap
@@ -14,12 +14,12 @@ exports[`should render correctly 1`] = `
canRestart={false}
cluster={true}
logLevel="INFO"
- onLogLevelChange={[Function]}
+ onLogLevelChange={[MockFunction]}
/>
</header>
`;
-exports[`should show a loading spinner and no actions 1`] = `
+exports[`should render correctly 2`] = `
<header
className="page-header"
>
@@ -37,3 +37,66 @@ exports[`should show a loading spinner and no actions 1`] = `
</div>
</header>
`;
+
+exports[`should render correctly 3`] = `
+<header
+ className="page-header"
+>
+ <h1
+ className="page-title"
+ >
+ system_info.page
+ </h1>
+ <PageActions
+ canDownloadLogs={false}
+ canRestart={false}
+ cluster={true}
+ logLevel="INFO"
+ onLogLevelChange={[MockFunction]}
+ serverId="foo-bar"
+ />
+ <div
+ className="system-info-copy-paste-id-info boxed-group display-flex-center"
+ >
+ <div
+ className="flex-1"
+ >
+ <table
+ className="width-100"
+ >
+ <tbody>
+ <tr>
+ <th>
+ <strong>
+ system.server_id
+ </strong>
+ </th>
+ <td>
+ foo-bar
+ </td>
+ </tr>
+ <tr>
+ <th>
+ <strong>
+ system.version
+ </strong>
+ </th>
+ <td>
+ 7.7.0.1234
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <ClipboardButton
+ className="flex-0"
+ copyValue="SonarQube ID information
+Server ID: foo-bar
+Version: 7.7.0.1234
+Date: 2019-01-01
+"
+ label="system.copy_id_info"
+ />
+ </div>
+</header>
+`;
diff --git a/server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/StandaloneSysInfos-test.tsx.snap b/server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/StandaloneSysInfos-test.tsx.snap
index b71406e8fba..0d5a69d87e1 100644
--- a/server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/StandaloneSysInfos-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/StandaloneSysInfos-test.tsx.snap
@@ -15,9 +15,15 @@ exports[`should render correctly 1`] = `
open={false}
sysInfoData={
Object {
- "High Availability": true,
- "Logs Level": "DEBUG",
- "Server ID": "MyServerId",
+ "Database": Object {
+ "Database": "PostgreSQL",
+ "Database Version": "10.3",
+ "Driver": "PostgreSQL JDBC Driver",
+ "Driver Version": "42.2.5",
+ "URL": "jdbc:postgresql://localhost/sonar",
+ "Username": "sonar",
+ },
+ "High Availability": false,
}
}
/>
@@ -28,8 +34,21 @@ exports[`should render correctly 1`] = `
open={false}
sysInfoData={
Object {
- "Web JVM": Object {
- "Max Memory": "2Gb",
+ "Web Database Connection": Object {
+ "Pool Active Connections": 0,
+ "Pool Max Connections": 60,
+ },
+ "Web JVM Properties": Object {
+ "file.encoding": "UTF-8",
+ "file.separator": "/",
+ },
+ "Web JVM State": Object {
+ "Free Memory (MB)": 111,
+ "Max Memory (MB)": 1024,
+ },
+ "Web Logging": Object {
+ "Logs Dir": "/logs",
+ "Logs Level": "INFO",
},
}
}
@@ -41,8 +60,25 @@ exports[`should render correctly 1`] = `
open={true}
sysInfoData={
Object {
- "Compute Engine": Object {
- "Pending": 4,
+ "Compute Engine Database Connection": Object {
+ "Pool Active Connections": 0,
+ "Pool Initial Size": 0,
+ },
+ "Compute Engine JVM Properties": Object {
+ "file.encoding": "UTF-8",
+ "file.separator": "/",
+ },
+ "Compute Engine JVM State": Object {
+ "Free Memory (MB)": 89,
+ "Max Memory (MB)": 1024,
+ },
+ "Compute Engine Logging": Object {
+ "Logs Dir": "/logs",
+ "Logs Level": "DEBUG",
+ },
+ "Compute Engine Tasks": Object {
+ "In Progress": 0,
+ "Pending": 0,
},
}
}
@@ -54,8 +90,13 @@ exports[`should render correctly 1`] = `
open={false}
sysInfoData={
Object {
- "Search": Object {
- "Number of Nodes": 1,
+ "Search Indexes": Object {
+ "Index components - Docs": 30445,
+ "Index components - Shards": 10,
+ },
+ "Search State": Object {
+ "Nodes": 3,
+ "State": "GREEN",
},
}
}
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 f6e21f1b189..95e3d72aef6 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
@@ -21,20 +21,19 @@ import * as React from 'react';
import { map } from 'lodash';
import HealthItem from './HealthItem';
import Section from './Section';
+import { Alert } from '../../../../components/ui/Alert';
import BoxedGroupAccordion from '../../../../components/controls/BoxedGroupAccordion';
-import { HealthType, SysValueObject } from '../../../../api/system';
import { LOGS_LEVELS, groupSections, getLogsLevel } from '../../utils';
import { translate } from '../../../../helpers/l10n';
-import { Alert } from '../../../../components/ui/Alert';
interface Props {
biggerHealth?: boolean;
- health?: HealthType;
+ health?: T.HealthType;
healthCauses?: string[];
onClick: (toggledCard: string) => void;
open: boolean;
name: string;
- sysInfoData: SysValueObject;
+ sysInfoData: T.SysInfoValueObject;
}
export default function HealthCard({
diff --git a/server/sonar-web/src/main/js/apps/system/components/info-items/HealthCauseItem.tsx b/server/sonar-web/src/main/js/apps/system/components/info-items/HealthCauseItem.tsx
index 04c416e1338..79ebc2e1ca4 100644
--- a/server/sonar-web/src/main/js/apps/system/components/info-items/HealthCauseItem.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/info-items/HealthCauseItem.tsx
@@ -19,12 +19,11 @@
*/
import * as React from 'react';
import * as classNames from 'classnames';
-import { HealthType } from '../../../../api/system';
import { Alert } from '../../../../components/ui/Alert';
interface Props {
className?: string;
- health: HealthType;
+ health: T.HealthType;
healthCause: string;
}
@@ -33,7 +32,7 @@ export default function HealthCauseItem({ className, health, healthCause }: Prop
<Alert
className={classNames('boxed-group-accordion-alert', className)}
display="inline"
- variant={health === HealthType.RED ? 'error' : 'warning'}>
+ variant={health === 'RED' ? 'error' : 'warning'}>
{healthCause}
</Alert>
);
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 1b71f37fce3..e5291e8c1be 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
@@ -22,19 +22,18 @@ 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;
+ health: T.HealthType;
healthCauses?: string[];
}
export default function HealthItem({ biggerHealth, className, name, health, healthCauses }: Props) {
- const hasHealthCauses = healthCauses && healthCauses.length > 0 && health !== HealthType.GREEN;
+ const hasHealthCauses = healthCauses && healthCauses.length > 0 && health !== 'GREEN';
const statusIndicator = (
<StatusIndicator color={health.toLowerCase()} size={biggerHealth ? 'big' : undefined} />
);
diff --git a/server/sonar-web/src/main/js/apps/system/components/info-items/Section.tsx b/server/sonar-web/src/main/js/apps/system/components/info-items/Section.tsx
index a40845a12a3..b548e94afa9 100644
--- a/server/sonar-web/src/main/js/apps/system/components/info-items/Section.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/info-items/Section.tsx
@@ -20,11 +20,10 @@
import * as React from 'react';
import { map } from 'lodash';
import SysInfoItem from './SysInfoItem';
-import { SysValueObject } from '../../../../api/system';
interface Props {
name?: string;
- items: SysValueObject;
+ items: T.SysInfoValueObject;
}
export default function Section({ name, items }: Props) {
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 3389df8bb61..fc004f88d99 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
@@ -22,17 +22,16 @@ import { map } from 'lodash';
import HealthItem from './HealthItem';
import AlertErrorIcon from '../../../../components/icons-components/AlertErrorIcon';
import AlertSuccessIcon from '../../../../components/icons-components/AlertSuccessIcon';
-import { HealthType, SysValue, SysValueObject } from '../../../../api/system';
-import { HEALTH_FIELD } from '../../utils';
+import { HEALTH_FIELD, STATE_FIELD } from '../../utils';
export interface Props {
name: string;
- value: SysValue;
+ value: T.SysInfoValue;
}
export default function SysInfoItem({ name, value }: Props): JSX.Element {
- if (name === HEALTH_FIELD || name === 'State') {
- return <HealthItem className="no-margin" health={value as HealthType} />;
+ if (name === HEALTH_FIELD || name === STATE_FIELD) {
+ return <HealthItem className="no-margin" health={value as T.HealthType} />;
}
if (value instanceof Array) {
return <code>{JSON.stringify(value)}</code>;
@@ -55,7 +54,7 @@ function BooleanItem({ value }: { value: boolean }) {
}
}
-function ObjectItem({ value }: { value: SysValueObject }) {
+function ObjectItem({ value }: { value: T.SysInfoValueObject }) {
return (
<table className="data">
<tbody>
diff --git a/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/HealthCard-test.tsx b/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/HealthCard-test.tsx
index c8eaa8d45ef..f96d0245c37 100644
--- a/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/HealthCard-test.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/HealthCard-test.tsx
@@ -20,7 +20,6 @@
import * as React from 'react';
import { shallow } from 'enzyme';
import HealthCard from '../HealthCard';
-import { HealthType } from '../../../../../api/system';
it('should render correctly', () => {
expect(getWrapper()).toMatchSnapshot();
@@ -48,7 +47,7 @@ function getWrapper(props = {}) {
return shallow(
<HealthCard
biggerHealth={false}
- health={HealthType.RED}
+ health="RED"
healthCauses={['foo']}
name="Foobar"
onClick={() => {}}
diff --git a/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/HealthCauseItem-test.tsx b/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/HealthCauseItem-test.tsx
index 1c415360938..52ca0760f4c 100644
--- a/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/HealthCauseItem-test.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/info-items/__tests__/HealthCauseItem-test.tsx
@@ -20,11 +20,8 @@
import * as React from 'react';
import { shallow } from 'enzyme';
import HealthCauseItem from '../HealthCauseItem';
-import { HealthType } from '../../../../../api/system';
it('should render correctly', () => {
- expect(shallow(<HealthCauseItem health={HealthType.RED} healthCause="foo" />)).toMatchSnapshot();
- expect(
- shallow(<HealthCauseItem health={HealthType.YELLOW} healthCause="foo" />)
- ).toMatchSnapshot();
+ expect(shallow(<HealthCauseItem health="RED" healthCause="foo" />)).toMatchSnapshot();
+ expect(shallow(<HealthCauseItem health="YELLOW" healthCause="foo" />)).toMatchSnapshot();
});
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 9857ee9b8f9..a17f1140b98 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
@@ -20,25 +20,18 @@
import * as React from 'react';
import { shallow } from 'enzyme';
import HealthItem from '../HealthItem';
-import { HealthType } from '../../../../../api/system';
it('should render correctly', () => {
expect(
- shallow(
- <HealthItem biggerHealth={true} health={HealthType.RED} healthCauses={['foo']} name="Foo" />
- )
+ shallow(<HealthItem biggerHealth={true} health="RED" healthCauses={['foo']} name="Foo" />)
).toMatchSnapshot();
});
it('should not render health causes', () => {
- expect(
- shallow(<HealthItem health={HealthType.GREEN} healthCauses={['foo']} />)
- ).toMatchSnapshot();
- expect(shallow(<HealthItem health={HealthType.YELLOW} healthCauses={[]} />)).toMatchSnapshot();
+ expect(shallow(<HealthItem health="GREEN" healthCauses={['foo']} />)).toMatchSnapshot();
+ expect(shallow(<HealthItem health="YELLOW" healthCauses={[]} />)).toMatchSnapshot();
});
it('should render multiple health causes', () => {
- expect(
- shallow(<HealthItem health={HealthType.YELLOW} healthCauses={['foo', 'bar']} />)
- ).toMatchSnapshot();
+ expect(shallow(<HealthItem health="YELLOW" healthCauses={['foo', 'bar']} />)).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeForm.tsx b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeForm.tsx
index 65712b193e7..9bc6c42f038 100644
--- a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeForm.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeForm.tsx
@@ -19,13 +19,12 @@
*/
import * as React from 'react';
import SystemUpgradeItem from './SystemUpgradeItem';
-import { SystemUpgrade } from '../../../../api/system';
import Modal from '../../../../components/controls/Modal';
import { translate } from '../../../../helpers/l10n';
import { ResetButtonLink } from '../../../../components/ui/buttons';
interface Props {
- systemUpgrades: SystemUpgrade[][];
+ systemUpgrades: T.SystemUpgrade[][];
onClose: () => void;
}
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeIntermediate.tsx b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeIntermediate.tsx
index cd49bba50d1..14c65114dbd 100644
--- a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeIntermediate.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeIntermediate.tsx
@@ -21,12 +21,11 @@ import * as React from 'react';
import DateFormatter from '../../../../components/intl/DateFormatter';
import DropdownIcon from '../../../../components/icons-components/DropdownIcon';
import { ButtonLink } from '../../../../components/ui/buttons';
-import { SystemUpgrade } from '../../../../api/system';
import { translate } from '../../../../helpers/l10n';
interface Props {
className?: string;
- upgrades: SystemUpgrade[];
+ upgrades: T.SystemUpgrade[];
}
interface State {
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeItem.tsx b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeItem.tsx
index 93e9e7b48e6..5881085f99d 100644
--- a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeItem.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeItem.tsx
@@ -21,12 +21,11 @@ import * as React from 'react';
import { FormattedMessage } from 'react-intl';
import SystemUpgradeIntermediate from './SystemUpgradeIntermediate';
import DateFormatter from '../../../../components/intl/DateFormatter';
-import { SystemUpgrade } from '../../../../api/system';
import { translate, translateWithParameters } from '../../../../helpers/l10n';
interface Props {
type?: string;
- systemUpgrades: SystemUpgrade[];
+ systemUpgrades: T.SystemUpgrade[];
}
export default function SystemUpgradeItem({ type, systemUpgrades }: Props) {
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeNotif.tsx b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeNotif.tsx
index 87677c1b39a..c4800cccafa 100644
--- a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeNotif.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeNotif.tsx
@@ -20,13 +20,13 @@
import * as React from 'react';
import SystemUpgradeForm from './SystemUpgradeForm';
import { sortUpgrades, groupUpgrades } from '../../utils';
-import { getSystemUpgrades, SystemUpgrade } from '../../../../api/system';
+import { getSystemUpgrades } from '../../../../api/system';
import { Button } from '../../../../components/ui/buttons';
import { translate } from '../../../../helpers/l10n';
import { Alert } from '../../../../components/ui/Alert';
interface State {
- systemUpgrades: SystemUpgrade[][];
+ systemUpgrades: T.SystemUpgrade[][];
openSystemUpgradeForm: boolean;
}
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 ec695d0194f..33f60e68f48 100644
--- a/server/sonar-web/src/main/js/apps/system/styles.css
+++ b/server/sonar-web/src/main/js/apps/system/styles.css
@@ -26,6 +26,13 @@
margin-top: -12px;
}
+.system-info-copy-paste-id-info {
+ max-width: 550px;
+ padding: var(--gridSize) calc(2 * var(--gridSize));
+ clear: both;
+ line-height: 1.8;
+}
+
.system-info-health-info .status-indicator {
position: relative;
top: 8px;
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 e2d26559342..85f34adb82b 100644
--- a/server/sonar-web/src/main/js/apps/system/utils.ts
+++ b/server/sonar-web/src/main/js/apps/system/utils.ts
@@ -25,15 +25,6 @@ import {
RawQuery,
serializeStringArray
} from '../../helpers/query';
-import {
- ClusterSysInfo,
- HealthType,
- NodeInfo,
- SysInfo,
- SysInfoSection,
- SysValueObject,
- SystemUpgrade
-} from '../../api/system';
import { formatMeasure } from '../../helpers/measures';
export interface Query {
@@ -41,132 +32,167 @@ export interface Query {
}
export const LOGS_LEVELS = ['INFO', 'DEBUG', 'TRACE'];
+const DEFAULT_LOG_LEVEL = LOGS_LEVELS[0];
+
+export const APP_NODES_FIELD = 'Application Nodes';
+export const CE_FIELD_PREFIX = 'Compute Engine';
+export const CE_LOGGING_FIELD = 'Compute Engine Logging';
export const HA_FIELD = 'High Availability';
+export const HEALTH_CAUSES_FIELD = 'Health Causes';
export const HEALTH_FIELD = 'Health';
-export const HEALTHCAUSES_FIELD = 'Health Causes';
+export const LOGS_LEVEL_FIELD = 'Logs Level';
+export const NAME_FIELD = 'Name';
+export const NCLOC_FIELD = 'ncloc';
export const PLUGINS_FIELD = 'Plugins';
+export const SEARCH_NODES_FIELD = 'Search Nodes';
+export const SEARCH_PREFIX = 'Search';
+export const SERVER_ID_FIELD = 'Server ID';
export const SETTINGS_FIELD = 'Settings';
-
-export function ignoreInfoFields(sysInfoObject: SysValueObject): SysValueObject {
+export const STATE_FIELD = 'State';
+export const STATS_FIELD = 'Statistics';
+export const SYSTEM_FIELD = 'System';
+export const VERSION_FIELD = 'Version';
+export const WEB_LOGGING_FIELD = 'Web Logging';
+export const WEB_PREFIX = 'Web';
+
+export function ignoreInfoFields(sysInfoObject: T.SysInfoValueObject) {
return omit(sysInfoObject, [
HEALTH_FIELD,
- HEALTHCAUSES_FIELD,
- 'Name',
+ HEALTH_CAUSES_FIELD,
+ NAME_FIELD,
PLUGINS_FIELD,
- SETTINGS_FIELD
- ]) as SysValueObject;
+ SETTINGS_FIELD,
+ SERVER_ID_FIELD,
+ VERSION_FIELD
+ ]);
}
-export function getHealth(sysInfoObject: SysValueObject): HealthType {
- return sysInfoObject[HEALTH_FIELD] as HealthType;
+export function getHealth(sysInfoObject: T.SysInfoBase) {
+ return sysInfoObject[HEALTH_FIELD];
}
-export function getHealthCauses(sysInfoObject: SysValueObject): string[] {
- return sysInfoObject[HEALTHCAUSES_FIELD] as string[];
+export function getHealthCauses(sysInfoObject: T.SysInfoBase) {
+ return sysInfoObject[HEALTH_CAUSES_FIELD];
}
-export function getLogsLevel(sysInfoObject?: SysValueObject): string {
- if (!sysInfoObject) {
- return LOGS_LEVELS[0];
- }
- if (sysInfoObject['Web Logging'] || sysInfoObject['Compute Engine Logging']) {
- return sortBy(
- [
- getLogsLevel((sysInfoObject as NodeInfo)['Web Logging']),
- getLogsLevel((sysInfoObject as NodeInfo)['Compute Engine Logging'])
- ],
- logLevel => LOGS_LEVELS.indexOf(logLevel)
- )[1];
- }
- if (sysInfoObject['System']) {
- return getLogsLevel((sysInfoObject as SysInfo)['System']);
+export function getLogsLevel(sysInfoObject?: T.SysInfoValueObject): string {
+ if (sysInfoObject !== undefined) {
+ if (isLogInfoBlock(sysInfoObject)) {
+ return sysInfoObject[LOGS_LEVEL_FIELD];
+ } else if (hasLoggingInfo(sysInfoObject)) {
+ return sortBy(
+ [
+ getLogsLevel(sysInfoObject[WEB_LOGGING_FIELD]),
+ getLogsLevel(sysInfoObject[CE_LOGGING_FIELD])
+ ],
+ logLevel => LOGS_LEVELS.indexOf(logLevel)
+ )[1];
+ }
}
- return (sysInfoObject['Logs Level'] || LOGS_LEVELS[0]) as string;
+ return DEFAULT_LOG_LEVEL;
}
-export function getAppNodes(sysInfoData: ClusterSysInfo): NodeInfo[] {
- return sysInfoData['Application Nodes'];
+export function getAppNodes(sysInfoData: T.SysInfoCluster): T.SysInfoAppNode[] {
+ return sysInfoData[APP_NODES_FIELD];
}
-export function getSearchNodes(sysInfoData: ClusterSysInfo): NodeInfo[] {
- return sysInfoData['Search Nodes'];
+export function getSearchNodes(sysInfoData: T.SysInfoCluster): T.SysInfoSearchNode[] {
+ return sysInfoData[SEARCH_NODES_FIELD];
}
-export function isCluster(sysInfoData?: SysInfo): boolean {
- return (
- sysInfoData !== undefined && sysInfoData['System'] && sysInfoData['System'][HA_FIELD] === true
- );
+export function isCluster(
+ sysInfoData: T.SysInfoCluster | T.SysInfoStandalone
+): sysInfoData is T.SysInfoCluster {
+ return sysInfoData[SYSTEM_FIELD] && sysInfoData[SYSTEM_FIELD][HA_FIELD] === true;
}
-export function getServerId(sysInfoData?: SysInfo): string | undefined {
- return sysInfoData && sysInfoData['System']['Server ID'];
+export function isLogInfoBlock(
+ sysInfoObject: T.SysInfoValueObject
+): sysInfoObject is T.SysInfoLogging {
+ return sysInfoObject[LOGS_LEVEL_FIELD] !== undefined;
}
-export function getSystemLogsLevel(sysInfoData?: SysInfo): string {
- const defaultLevel = LOGS_LEVELS[0];
- if (!sysInfoData) {
- return defaultLevel;
- }
+export function hasLoggingInfo(
+ sysInfoObject: T.SysInfoValueObject
+): sysInfoObject is T.SysInfoStandalone | T.SysInfoAppNode {
+ return Boolean(sysInfoObject[WEB_LOGGING_FIELD] || sysInfoObject[CE_LOGGING_FIELD]);
+}
+
+export function getServerId(sysInfoData: T.SysInfoCluster | T.SysInfoStandalone): string {
+ return sysInfoData && sysInfoData[SYSTEM_FIELD][SERVER_ID_FIELD];
+}
+
+export function getVersion(sysInfoData: T.SysInfoStandalone): string | undefined {
+ return sysInfoData && sysInfoData[SYSTEM_FIELD][VERSION_FIELD];
+}
+
+export function getClusterVersion(sysInfoData: T.SysInfoCluster): string | undefined {
+ const appNodes = getAppNodes(sysInfoData);
+ return appNodes.length > 0 ? appNodes[0][SYSTEM_FIELD][VERSION_FIELD] : undefined;
+}
+
+export function getSystemLogsLevel(sysInfoData: T.SysInfoCluster | T.SysInfoStandalone): string {
if (isCluster(sysInfoData)) {
- const logLevels = sortBy(
- getAppNodes(sysInfoData as ClusterSysInfo).map(getLogsLevel),
- logLevel => LOGS_LEVELS.indexOf(logLevel)
+ const logLevels = sortBy(getAppNodes(sysInfoData).map(getLogsLevel), logLevel =>
+ LOGS_LEVELS.indexOf(logLevel)
);
- return logLevels.length > 0 ? logLevels[logLevels.length - 1] : defaultLevel;
+ return logLevels.length > 0 ? logLevels[logLevels.length - 1] : DEFAULT_LOG_LEVEL;
} else {
return getLogsLevel(sysInfoData);
}
}
-export function getNodeName(nodeInfo: NodeInfo): string {
- return nodeInfo['Name'];
+export function getNodeName(nodeInfo: T.SysInfoAppNode | T.SysInfoSearchNode): string {
+ return nodeInfo[NAME_FIELD];
}
-function getSystemData(sysInfoData: SysInfo): SysValueObject {
- const statData: SysValueObject = {};
- const statistics = sysInfoData['Statistics'] as SysValueObject;
+function getSystemData(sysInfoData: T.SysInfoBase): T.SysInfoValueObject {
+ const statData: T.SysInfoValueObject = {};
+ const statistics = sysInfoData[STATS_FIELD] as T.SysInfoValueObject; // TODO
if (statistics) {
- statData['Lines of Code'] = formatMeasure(statistics['ncloc'] as number, 'INT');
+ statData['Lines of Code'] = formatMeasure(statistics[NCLOC_FIELD] as number, 'INT');
}
- return { ...sysInfoData['System'], ...statData };
+ return { ...sysInfoData[SYSTEM_FIELD], ...statData };
}
-export function getClusterMainCardSection(sysInfoData: ClusterSysInfo): SysValueObject {
+export function getClusterMainCardSection(sysInfoData: T.SysInfoCluster): T.SysInfoValueObject {
return {
...getSystemData(sysInfoData),
- ...(omit(sysInfoData, [
- 'Application Nodes',
+ ...omit(sysInfoData, [
+ APP_NODES_FIELD,
PLUGINS_FIELD,
- 'Search Nodes',
+ SEARCH_NODES_FIELD,
SETTINGS_FIELD,
- 'Statistics',
- 'System'
- ]) as SysValueObject)
+ STATS_FIELD,
+ SYSTEM_FIELD
+ ])
};
}
-export function getStandaloneMainSections(sysInfoData: SysInfo): SysValueObject {
+export function getStandaloneMainSections(sysInfoData: T.SysInfoBase): T.SysInfoValueObject {
return {
...getSystemData(sysInfoData),
...(omitBy(
sysInfoData,
(value, key) =>
value == null ||
- [PLUGINS_FIELD, SETTINGS_FIELD, 'Statistics', 'System'].includes(key) ||
- key.startsWith('Compute Engine') ||
- key.startsWith('Search') ||
- key.startsWith('Web')
- ) as SysValueObject)
+ [PLUGINS_FIELD, SETTINGS_FIELD, STATS_FIELD, SYSTEM_FIELD].includes(key) ||
+ key.startsWith(CE_FIELD_PREFIX) ||
+ key.startsWith(SEARCH_PREFIX) ||
+ key.startsWith(WEB_PREFIX)
+ ) as T.SysInfoValueObject)
};
}
-export function getStandaloneSecondarySections(sysInfoData: SysInfo): SysInfoSection {
+export function getStandaloneSecondarySections(sysInfoData: T.SysInfoBase): T.SysInfoSection {
return {
- Web: pickBy(sysInfoData, (_, key) => key.startsWith('Web')) as SysValueObject,
+ Web: pickBy(sysInfoData, (_, key) => key.startsWith(WEB_PREFIX)) as T.SysInfoValueObject,
'Compute Engine': pickBy(sysInfoData, (_, key) =>
- key.startsWith('Compute Engine')
- ) as SysValueObject,
- 'Search Engine': pickBy(sysInfoData, (_, key) => key.startsWith('Search')) as SysValueObject
+ key.startsWith(CE_FIELD_PREFIX)
+ ) as T.SysInfoValueObject,
+ 'Search Engine': pickBy(sysInfoData, (_, key) =>
+ key.startsWith(SEARCH_PREFIX)
+ ) as T.SysInfoValueObject
};
}
@@ -179,9 +205,9 @@ export function getFileNameSuffix(suffix?: string) {
);
}
-export function groupSections(sysInfoData: SysValueObject) {
- const mainSection: SysValueObject = {};
- const sections: SysInfoSection = {};
+export function groupSections(sysInfoData: T.SysInfoValueObject) {
+ const mainSection: T.SysInfoValueObject = {};
+ const sections: T.SysInfoSection = {};
each(sysInfoData, (item, key) => {
if (typeof item !== 'object' || item instanceof Array) {
mainSection[key] = item;
@@ -205,15 +231,15 @@ export const serializeQuery = memoize(
})
);
-export function sortUpgrades(upgrades: SystemUpgrade[]): SystemUpgrade[] {
+export function sortUpgrades(upgrades: T.SystemUpgrade[]): T.SystemUpgrade[] {
return sortBy(upgrades, [
- (upgrade: SystemUpgrade) => -Number(upgrade.version.split('.')[0]),
- (upgrade: SystemUpgrade) => -Number(upgrade.version.split('.')[1] || 0),
- (upgrade: SystemUpgrade) => -Number(upgrade.version.split('.')[2] || 0)
+ (upgrade: T.SystemUpgrade) => -Number(upgrade.version.split('.')[0]),
+ (upgrade: T.SystemUpgrade) => -Number(upgrade.version.split('.')[1] || 0),
+ (upgrade: T.SystemUpgrade) => -Number(upgrade.version.split('.')[2] || 0)
]);
}
-export function groupUpgrades(upgrades: SystemUpgrade[]): SystemUpgrade[][] {
+export function groupUpgrades(upgrades: T.SystemUpgrade[]): T.SystemUpgrade[][] {
const groupedVersions = groupBy(upgrades, upgrade => upgrade.version.split('.')[0]);
const sortedMajor = sortBy(Object.keys(groupedVersions), key => -Number(key));
return sortedMajor.map(key => groupedVersions[key]);