]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6928 Rewrite the System Info page
authorStas Vilchik <vilchiks@gmail.com>
Fri, 16 Oct 2015 16:41:43 +0000 (18:41 +0200)
committerStas Vilchik <vilchiks@gmail.com>
Fri, 16 Oct 2015 16:41:43 +0000 (18:41 +0200)
12 files changed:
server/sonar-web/src/main/js/api/system.js
server/sonar-web/src/main/js/apps/system/app.js
server/sonar-web/src/main/js/apps/system/item-boolean.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/system/item-log-level.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/system/item-object.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/system/item-value.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/system/main.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/system/section.js [new file with mode: 0644]
server/sonar-web/src/main/js/main/nav/settings/settings-nav.js
server/sonar-web/src/main/webapp/WEB-INF/app/controllers/system_controller.rb
server/sonar-web/src/main/webapp/WEB-INF/app/views/system/index.html.erb
server/sonar-web/src/main/webapp/WEB-INF/app/views/system/new.html.erb [new file with mode: 0644]

index 59ef364d9ee5a99e587d0e9979ab0b8319f9a86e..226f8724ef8b68514afdb365c411f6bfedae4426 100644 (file)
@@ -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);
+}
index 391c313d9ec2b006c913390aaa5095cf9f888cf9..b4b9a61c4a6e6a8bd71f0b52c83c04f4ddf8446c 100644 (file)
@@ -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 (file)
index 0000000..58f6dd7
--- /dev/null
@@ -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 (file)
index 0000000..2f888d7
--- /dev/null
@@ -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 (file)
index 0000000..15583de
--- /dev/null
@@ -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 (file)
index 0000000..a4d2da9
--- /dev/null
@@ -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 (file)
index 0000000..fe69d83
--- /dev/null
@@ -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 (file)
index 0000000..63b05a4
--- /dev/null
@@ -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>;
+  }
+});
index 13fae339cda61f8b197c8a046516f33661af5762..5f186c494b02d476ff229afcb5e7f89fb9747bd6 100644 (file)
@@ -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>
index 929d1a6fcc98cd8b81654f402910df747ff5c1c0..0234fe6880832bfa23b3b60572327fc675b7c223 100644 (file)
@@ -32,4 +32,8 @@ class SystemController < ApplicationController
     ]
   end
 
+  def new
+
+  end
+
 end
index f80abacd882455b30ba3134225ed058fb8522e4f..51e1c98c6633383d0172931968724d6398ea0ffe 100644 (file)
@@ -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 (file)
index 0000000..8e9f086
--- /dev/null
@@ -0,0 +1,4 @@
+<% content_for :extra_script do %>
+  <script src="<%= ApplicationController.root_context -%>/js/bundles/system.js?v=<%= sonar_version -%>"></script>
+<% end %>
+