aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-web/src/main/js/api/system.js7
-rw-r--r--server/sonar-web/src/main/js/apps/system/app.js58
-rw-r--r--server/sonar-web/src/main/js/apps/system/item-boolean.js11
-rw-r--r--server/sonar-web/src/main/js/apps/system/item-log-level.js20
-rw-r--r--server/sonar-web/src/main/js/apps/system/item-object.js14
-rw-r--r--server/sonar-web/src/main/js/apps/system/item-value.js26
-rw-r--r--server/sonar-web/src/main/js/apps/system/main.js55
-rw-r--r--server/sonar-web/src/main/js/apps/system/section.js22
-rw-r--r--server/sonar-web/src/main/js/main/nav/settings/settings-nav.js3
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/controllers/system_controller.rb4
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/system/index.html.erb6
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/system/new.html.erb4
12 files changed, 170 insertions, 60 deletions
diff --git a/server/sonar-web/src/main/js/api/system.js b/server/sonar-web/src/main/js/api/system.js
index 59ef364d9ee..226f8724ef8 100644
--- a/server/sonar-web/src/main/js/api/system.js
+++ b/server/sonar-web/src/main/js/api/system.js
@@ -1,6 +1,13 @@
+import { getJSON } from '../helpers/request.js';
import $ from 'jquery';
+// TODO migrate to fetch()
export function setLogLevel (level) {
let url = baseUrl + '/api/system/change_log_level';
return $.post(url, { level });
}
+
+export function getSystemInfo () {
+ let url = baseUrl + '/api/system/info';
+ return getJSON(url);
+}
diff --git a/server/sonar-web/src/main/js/apps/system/app.js b/server/sonar-web/src/main/js/apps/system/app.js
index 391c313d9ec..b4b9a61c4a6 100644
--- a/server/sonar-web/src/main/js/apps/system/app.js
+++ b/server/sonar-web/src/main/js/apps/system/app.js
@@ -1,57 +1,9 @@
-import $ from 'jquery';
-import {setLogLevel} from '../../api/system';
+import React from 'react';
+import Main from './main';
-const LOG_LEVELS = ['INFO', 'DEBUG', 'TRACE'];
-
-window.sonarqube.appStarted.then(() => {
- let cell = $('#sonarqube-logs-level').find('td:last-child');
- if (cell.length) {
- let currentValue = cell.text().trim();
- cell.empty();
-
- let select = $('<select>');
- cell.append(select);
-
- LOG_LEVELS.forEach(logLevel => {
- let option = $('<option>');
- option.prop('value', logLevel);
- option.text(logLevel);
- option.prop('selected', logLevel === currentValue);
- select.append(option);
- });
-
- let format = (state) => {
- let className = state.id !== 'INFO' ? 'text-danger' : '';
- return `<span class="${className}">${state.id}</span>`;
- };
-
- let warning = $('<div>')
- .addClass('spacer-top text-danger')
- .text(window.t('system.log_level.warning'));
-
- let placeWarning = function () {
- if (select.val() === 'INFO') {
- warning.detach();
- } else {
- warning.insertAfter(select);
- }
- };
-
- placeWarning();
-
- $(select)
- .select2({
- width: '120px',
- minimumResultsForSearch: 999,
- formatResult: format,
- formatSelection: format
- })
- .on('change', () => {
- let newValue = select.val();
- setLogLevel(newValue);
- placeWarning();
- });
- }
+window.sonarqube.appStarted.then(options => {
+ var el = document.querySelector(options.el);
+ React.render(<Main/>, el);
});
diff --git a/server/sonar-web/src/main/js/apps/system/item-boolean.js b/server/sonar-web/src/main/js/apps/system/item-boolean.js
new file mode 100644
index 00000000000..58f6dd7d9b8
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/item-boolean.js
@@ -0,0 +1,11 @@
+import React from 'react';
+
+export default React.createClass({
+ render() {
+ if (this.props.value) {
+ return <i className="icon-check"/>;
+ } else {
+ return <i className="icon-delete"/>;
+ }
+ }
+});
diff --git a/server/sonar-web/src/main/js/apps/system/item-log-level.js b/server/sonar-web/src/main/js/apps/system/item-log-level.js
new file mode 100644
index 00000000000..2f888d7100b
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/item-log-level.js
@@ -0,0 +1,20 @@
+import React from 'react';
+import { setLogLevel } from '../../api/system';
+
+const LOG_LEVELS = ['INFO', 'DEBUG', 'TRACE'];
+
+export default React.createClass({
+ onChange() {
+ let newValue = React.findDOMNode(this.refs.select).value;
+ setLogLevel(newValue);
+ },
+
+ render() {
+ let options = LOG_LEVELS.map(level => {
+ return <option key={level} value={level}>{level}</option>;
+ });
+ return <select ref="select"
+ onChange={this.onChange}
+ defaultValue={this.props.value}>{options}</select>;
+ }
+});
diff --git a/server/sonar-web/src/main/js/apps/system/item-object.js b/server/sonar-web/src/main/js/apps/system/item-object.js
new file mode 100644
index 00000000000..15583def4bb
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/item-object.js
@@ -0,0 +1,14 @@
+import React from 'react';
+import ItemValue from './item-value';
+
+export default React.createClass({
+ render() {
+ let rows = Object.keys(this.props.value).map(key => {
+ return <tr key={key}>
+ <td className="thin nowrap">{key}</td>
+ <td><ItemValue value={this.props.value[key]}/></td>
+ </tr>;
+ });
+ return <table className="data">{rows}</table>;
+ }
+});
diff --git a/server/sonar-web/src/main/js/apps/system/item-value.js b/server/sonar-web/src/main/js/apps/system/item-value.js
new file mode 100644
index 00000000000..a4d2da93154
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/item-value.js
@@ -0,0 +1,26 @@
+import React from 'react';
+import ItemBoolean from './item-boolean';
+import ItemObject from './item-object';
+import ItemLogLevel from './item-log-level';
+
+export default React.createClass({
+ render() {
+ if (this.props.name === 'Logs Level') {
+ return <ItemLogLevel value={this.props.value}/>;
+ }
+
+ let rawValue = this.props.value,
+ formattedValue;
+ switch (typeof this.props.value) {
+ case 'boolean':
+ formattedValue = <ItemBoolean value={rawValue}/>;
+ break;
+ case 'object':
+ formattedValue = <ItemObject value={rawValue}/>;
+ break;
+ default:
+ formattedValue = <code>{rawValue}</code>;
+ }
+ return formattedValue;
+ }
+});
diff --git a/server/sonar-web/src/main/js/apps/system/main.js b/server/sonar-web/src/main/js/apps/system/main.js
new file mode 100644
index 00000000000..fe69d83a6c0
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/main.js
@@ -0,0 +1,55 @@
+import _ from 'underscore';
+import React from 'react';
+import { getSystemInfo } from '../../api/system';
+import Section from './section';
+
+const SECTIONS_ORDER = ['SonarQube', 'Database', 'Plugins', 'System', 'ElasticSearch', 'JvmProperties',
+ 'ComputeEngineQueue'];
+
+export default React.createClass({
+ componentDidMount() {
+ getSystemInfo().then(info => this.setState({ sections: this.parseSections(info) }));
+ },
+
+ parseSections (data) {
+ let sections = Object.keys(data).map(section => {
+ return { name: section, items: this.parseItems(data[section]) };
+ });
+ return this.orderSections(sections);
+ },
+
+ orderSections (sections) {
+ return _.sortBy(sections, section => SECTIONS_ORDER.indexOf(section.name));
+ },
+
+ parseItems (data) {
+ let items = Object.keys(data).map(item => {
+ return { name: item, value: data[item] };
+ });
+ return this.orderItems(items);
+ },
+
+ orderItems (items) {
+ return _.sortBy(items, 'name');
+ },
+
+ render() {
+ let sections = null;
+ if (this.state && this.state.sections) {
+ sections = this.state.sections.map(section => {
+ return <Section key={section.name} section={section.name} items={section.items}/>;
+ });
+ }
+
+ return <div className="page">
+ <header className="page-header">
+ <h1 className="page-title">{window.t('system_info.page')}</h1>
+ <div className="page-actions">
+ <a className="spacer-right" href={window.baseUrl + '/api/system/logs'} id="logs-link">Logs</a>
+ <a href={window.baseUrl + '/api/system/info'} id="download-link">Download</a>
+ </div>
+ </header>
+ {sections}
+ </div>;
+ }
+});
diff --git a/server/sonar-web/src/main/js/apps/system/section.js b/server/sonar-web/src/main/js/apps/system/section.js
new file mode 100644
index 00000000000..63b05a45520
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/section.js
@@ -0,0 +1,22 @@
+import React from 'react';
+import ItemValue from './item-value';
+
+export default React.createClass({
+ render() {
+ let items = this.props.items.map(item => {
+ return <tr key={item.name}>
+ <td className="thin">
+ <div style={{ width: '25vw', overflow: 'hidden', textOverflow: 'ellipsis' }}>{item.name}</div>
+ </td>
+ <td style={{ wordBreak: 'break-all' }}><ItemValue name={item.name} value={item.value}/></td>
+ </tr>;
+ });
+
+ return <div className="big-spacer-bottom">
+ <h3 className="spacer-bottom">{this.props.section}</h3>
+ <table className="data zebra" id={this.props.section}>
+ <tbody>{items}</tbody>
+ </table>
+ </div>;
+ }
+});
diff --git a/server/sonar-web/src/main/js/main/nav/settings/settings-nav.js b/server/sonar-web/src/main/js/main/nav/settings/settings-nav.js
index 13fae339cda..5f186c494b0 100644
--- a/server/sonar-web/src/main/js/main/nav/settings/settings-nav.js
+++ b/server/sonar-web/src/main/js/main/nav/settings/settings-nav.js
@@ -57,7 +57,8 @@ export default React.createClass({
</a>
<ul className="dropdown-menu">
{this.renderLink('/updatecenter', window.t('update_center.page'))}
- {this.renderLink('/system', window.t('system_info.page'))}
+ {this.renderLink('/system/index', window.t('system_info.page'))}
+ {this.renderNewLink('/system/new', window.t('system_info.page'))}
</ul>
</li>
</ul>
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/system_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/system_controller.rb
index 929d1a6fcc9..0234fe68808 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/system_controller.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/system_controller.rb
@@ -32,4 +32,8 @@ class SystemController < ApplicationController
]
end
+ def new
+
+ end
+
end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/index.html.erb
index f80abacd882..51e1c98c663 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/index.html.erb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/index.html.erb
@@ -14,9 +14,3 @@
<% end %>
</div>
-
-
-<% content_for :extra_script do %>
- <script src="<%= ApplicationController.root_context -%>/js/bundles/system.js?v=<%= sonar_version -%>"></script>
-<% end %>
-
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/new.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/new.html.erb
new file mode 100644
index 00000000000..8e9f0861c90
--- /dev/null
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/new.html.erb
@@ -0,0 +1,4 @@
+<% content_for :extra_script do %>
+ <script src="<%= ApplicationController.root_context -%>/js/bundles/system.js?v=<%= sonar_version -%>"></script>
+<% end %>
+