diff --git a/extension.js b/extension.js
index 51baaef..5ab724f 100644
--- a/extension.js
+++ b/extension.js
@@ -46,6 +46,7 @@ const SETTINGS_SCHEMA_ACCOUNT = "org.gnome.shell.extensions.monito.account";
const SETTINGS_SCHEMA_ACCOUNT_PATH = "/org/gnome/shell/extensions/monito/account";
const Convenience = Me.imports.convenience;
+const GenericServer = Me.imports.servers.genericserver.GenericServer;
const Icinga = Me.imports.servers.icinga.Icinga;
const Icinga2 = Me.imports.servers.icinga2.Icinga2;
const Preferences = Me.imports.prefs;
@@ -53,14 +54,14 @@ const Preferences = Me.imports.prefs;
let settings = Convenience.getSettings(SETTINGS_SCHEMA);
let account_settings = [ ];
-const column_definitions = [
- { name: 'status', width: 50, expand: false, },
- { name: 'host_name', width: 300, expand: false, },
- { name: 'service_display_name', width: 300, expand: false, },
- { name: 'last_check', width: 200, expand: false, },
- { name: 'attempts', width: 50, expand: false, },
- { name: 'status_information', width: 600, expand: true, },
-];
+const column_definitions = {
+ status: { label: _('Status'), width: 50, expand: false, },
+ host_name: { label: _('Host name'), width: 300, expand: false, },
+ service_display_name: { label: _('Service'), width: 300, expand: false, },
+ last_check: { label: _('Last check'), width: 200, expand: false, },
+ attempts: { label: _('Attempts'), width: 50, expand: false, },
+ status_information: { label: _('Information'), width: 600, expand: true, },
+};
const Indicator = GObject.registerClass(
@@ -77,6 +78,16 @@ class Indicator extends PanelMenu.Button {
this.criticalBoxes = { };
this.unknownBoxes = { };
+ this.sortIcons = { };
+ account_settings [ server ] = Preferences.getAccountSettings ( this.server );
+ this.account_settings = account_settings [ server ];
+
+ let type = this.account_settings.get_string ( "type" );
+ if ( type == 'Icinga' )
+ this.serverlogic = new Icinga ( this.server );
+ else if ( type == 'Icinga2' )
+ this.serverlogic = new Icinga2 ( this.server );
+
this.initUI ( );
}
@@ -85,32 +96,30 @@ class Indicator extends PanelMenu.Button {
this.add_child(box);
monitoLog ( '> Server ' + this.server );
- account_settings [ this.server ] = Preferences.getAccountSettings ( this.server );
- let _account_settings = account_settings [ this.server ];
let serverBox = new St.BoxLayout ( { style_class: 'monito-serverbox' } );
box.add_child(serverBox);
let name_box = new St.BoxLayout( { style_class: 'monito-namebox' } );
- this.namesBoxes [ this.server ] = new St.Label ( { text: _account_settings.get_string ( 'name' ) } );
+ this.namesBoxes [ this.server ] = new St.Label ( { text: this.account_settings.get_string ( 'name' ) } );
name_box.add_child ( this.namesBoxes [ this.server ] );
serverBox.add_child(name_box);
- _account_settings.bind ( 'name', this.namesBoxes [ this.server ], 'text', Gio.SettingsBindFlags.GET );
+ this.account_settings.bind ( 'name', this.namesBoxes [ this.server ], 'text', Gio.SettingsBindFlags.GET );
this.namesBoxes [ this.server ].connect ( 'button-press-event', Lang.bind ( this, function ( ) { this.setMenu ( this.menu ); } ) );
let warning_box = new St.BoxLayout({ style_class: 'monito-warning-box monito-box' });
- warning_box.set_style ( 'background-color: ' + _account_settings.get_string ( 'warning-color' ) );
- _account_settings.connect("changed::warning-color", Lang.bind ( { widget: warning_box }, setColor ) );
+ warning_box.set_style ( 'background-color: ' + this.account_settings.get_string ( 'warning-color' ) );
+ this.account_settings.connect("changed::warning-color", Lang.bind ( { widget: warning_box }, setColor ) );
this.warningBoxes [ this.server ] = new St.Label({ text: String(_status['WARNING']) })
warning_box.add_child ( this.warningBoxes [ this.server ] );
serverBox.add_child(warning_box);
let critical_box = new St.BoxLayout({ style_class: 'monito-critical-box monito-box' });
- critical_box.set_style ( 'background-color: ' + _account_settings.get_string ( 'critical-color' ) );
- _account_settings.connect("changed::critical-color", Lang.bind ( { widget: critical_box }, setColor ) );
+ critical_box.set_style ( 'background-color: ' + this.account_settings.get_string ( 'critical-color' ) );
+ this.account_settings.connect("changed::critical-color", Lang.bind ( { widget: critical_box }, setColor ) );
this.criticalBoxes [ this.server ] = new St.Label({ text: String(_status['CRITICAL']) })
critical_box.add_child ( this.criticalBoxes [ this.server ] );
@@ -135,7 +144,7 @@ class Indicator extends PanelMenu.Button {
_iconBin.child = _icon;
this._buttonMenu.actor.add_actor(_iconBin);
- this._mainLabel = new St.Label({ style_class: 'monito-title', text: 'Monito Checker', x_expand: true });
+ this._mainLabel = new St.Label ( { style_class: 'monito-title', text: 'Monito Checker', x_expand: true } );
this._buttonMenu.actor.add_actor(this._mainLabel);
this._prefsButton = this._createButton ( 'preferences-system-symbolic', 'Preferences', this._onPreferencesActivate );
@@ -184,57 +193,63 @@ class Indicator extends PanelMenu.Button {
updateStatus ( )
{
- for ( let _server of Preferences.getServersList() )
+ if ( ! this.serverlogic.refresh ( this ) )
{
- let _account_settings = Preferences.getAccountSettings ( this.server );
-
- let type = _account_settings.get_string("type");
- let username = _account_settings.get_string("username");
- let password = _account_settings.get_string("password");
- let urlcgi = _account_settings.get_string("urlcgi");
-
- if ( ! urlcgi )
- {
- monitoLog ( 'Not updating monito because no URL configured' );
- }
- else
- {
- let _serverLogic;
- if ( type == 'Icinga' )
- _serverLogic = new Icinga ( this.server );
- else if ( type == 'Icinga2' )
- _serverLogic = new Icinga2 ( this.server );
-
- if ( ! _serverLogic.refresh ( this ) )
- {
- this.warningBoxes[this.server].set_text ( '…' );
- this.criticalBoxes[this.server].set_text ( '…' );
- // TODO: Add display of error if any
- }
- }
+ this.warningBoxes[this.server].set_text ( '…' );
+ this.criticalBoxes[this.server].set_text ( '…' );
}
this.setupTimeout ( );
}
- createHeaderBin ( status, text, col ) {
- let _widths = [ 300, 300, 200, 50, 600 ];
- let _bin = new St.Bin({
- style_class: 'monito-service-' + status,
- width: col.width,
- x_expand: col.expand,
- child: new St.Button ( {
+ createHeaderBin ( colName ) {
+ let col = column_definitions [ colName ];
+
+ let _box = new St.BoxLayout ( { vertical: false,
+ x_expand: true } );
+ _box.add_child ( new St.Label ( { text: col.label,
+ x_expand: true,
+ x_align: Clutter.ActorAlign.START } ) );
+
+ let _iconBin = new St.Bin ( { x_align: Clutter.ActorAlign.END });
+ _box.add_child ( _iconBin );
+
+ let _iconName = '';
+ let _sortOrder = Preferences.getSortOrder ( this.server );
+ if ( _sortOrder.indexOf ( colName + '+' ) >= 0 )
+ _iconName = 'view-sort-descending-symbolic';
+ else if ( _sortOrder.indexOf ( colName + '-' ) >= 0 )
+ _iconName = 'view-sort-ascending-symbolic';
+
+ this.sortIcons [ colName ] = new St.Icon ( {
+ style_class: 'monito-button-icon',
+ icon_name: _iconName,
+ icon_size: 16,
+ } );
+ _iconBin.child = this.sortIcons [ colName ];
+
+ let _button = new St.Button ( {
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.CENTER,
width: col.width,
reactive: true,
can_focus: true,
track_hover: true,
- accessible_name: text,
+ accessible_name: col.label,
style_class: 'button',
- label: col.name,
- })
+ } );
+ _button.column = colName;
+
+ _button.add_actor ( _box );
+ _button.connect ( 'clicked', Lang.bind ( this, this._onSortColumnClick ) );
+
+ let _bin = new St.Bin({
+ style_class: 'monito-service',
+ width: col.width,
+ x_expand: col.expand,
+ child: _button,
});
+
return _bin;
}
@@ -249,14 +264,14 @@ class Indicator extends PanelMenu.Button {
return _bin;
}
- refreshUI ( serverLogic ) {
- this.initStatus ( ); // Specialize !
+ refreshUI ( ) {
+ this.initStatus ( );
this._box.remove_all_children();
- if ( serverLogic.error )
+ if ( this.serverlogic.error )
{
- this._box.add_child ( new St.Label ( { style_class: 'monito-network-error', text: serverLogic.error } ) );
+ this._box.add_child ( new St.Label ( { style_class: 'monito-network-error', text: this.serverlogic.error } ) );
return;
}
@@ -265,8 +280,10 @@ class Indicator extends PanelMenu.Button {
x_expand: true
});
this._box.add_child(headerBox);
- for ( let col of column_definitions )
- headerBox.add_child ( this.createHeaderBin ( '', col.name, col ) );
+
+ let _columns = Preferences.getColumns ( this.server );
+ for ( let _col of _columns )
+ headerBox.add_child ( this.createHeaderBin ( _col ) );
let scrollBox = new St.ScrollView ( { hscrollbar_policy: St.PolicyType.NEVER,
enable_mouse_scrolling: true, } );
@@ -279,29 +296,28 @@ class Indicator extends PanelMenu.Button {
});
scrollBox.add_actor(tableBox);
- for ( let i = 0 ; i < serverLogic.status.service_status.length ; i ++ )
+ for ( let entry of this.serverlogic.getProcessedStatus ( ) )
{
- _status [ serverLogic.status.service_status[i].status ] ++;
- if ( serverLogic.status.service_status[i].status != 'OK' )
+ _status [ entry.status ] ++;
+ if ( entry.status != 'OK' )
{
let infoBox = new St.BoxLayout({
- style_class: 'monito-service-line monito-service-line-' + serverLogic.status.service_status[i].status,
+ style_class: 'monito-service-line monito-service-line-' + entry.status,
track_hover: true,
x_expand: true,
});
tableBox.add_child(infoBox);
- for ( let col of column_definitions )
+ let _columns = Preferences.getColumns ( this.server );
+ for ( let _col of _columns )
{
- infoBox.add_child ( this.createBin ( serverLogic.status.service_status[i].status,
- serverLogic.status.service_status[i][col.name],
- col ) );
+ infoBox.add_child ( this.createBin ( entry.status, entry [ _col ], column_definitions [ _col ] ) );
}
}
}
- this.warningBoxes[serverLogic.server].set_text ( String(_status.WARNING) );
- this.criticalBoxes[serverLogic.server].set_text ( String(_status.CRITICAL) );
+ this.warningBoxes[this.serverlogic.server].set_text ( String(_status.WARNING) );
+ this.criticalBoxes[this.serverlogic.server].set_text ( String(_status.CRITICAL) );
return;
}
@@ -319,6 +335,26 @@ class Indicator extends PanelMenu.Button {
return 0;
}
+ _onSortColumnClick ( button ) {
+ monitoLog ( 'column >> ' + button.column );
+
+ let _sortOrder = Preferences.getSortOrder ( this.server );
+ let _columns = Preferences.getColumns ( this.server );
+
+ let _indexPlus = _sortOrder.indexOf ( button.column + '+' );
+ let _indexMinus = _sortOrder.indexOf ( button.column + '-' );
+
+ if ( _indexPlus >= 0 )
+ _sortOrder [ _indexPlus ] = button.column + '-';
+ else if ( _indexMinus >= 0 )
+ _sortOrder.splice ( _indexMinus, 1 );
+ else
+ _sortOrder.unshift ( button.column + '+' );
+
+ Preferences.setSortOrder ( this.server, _sortOrder );
+ this.refreshUI ( );
+ }
+
_createButton ( icon, text, callback ) {
let button = new St.Button({
x_align: Clutter.ActorAlign.END,
diff --git a/prefs.js b/prefs.js
index 4c8fc44..6907999 100644
--- a/prefs.js
+++ b/prefs.js
@@ -174,6 +174,30 @@ function getAccountSettings ( id )
}
+function getSortOrder ( server )
+{
+ return this.getAccountSettings ( server ) . get_strv ( 'columns-order' );
+}
+
+
+function setSortOrder ( server, sort_order )
+{
+ return this.getAccountSettings ( server ) . set_strv ( 'columns-order', sort_order );
+}
+
+
+function getColumns ( server )
+{
+ return this.getAccountSettings ( server ) . get_strv ( 'columns' );
+}
+
+
+function setColumns ( server, columns )
+{
+ return this.getAccountSettings ( server ) . set_strv ( 'columns', columns );
+}
+
+
function createAccountWidgets ( isActive )
{
// Accounts
diff --git a/schemas/org.gnome.shell.extensions.monito@drieu.org.gschema.xml b/schemas/org.gnome.shell.extensions.monito@drieu.org.gschema.xml
index 228d517..95bdcf0 100644
--- a/schemas/org.gnome.shell.extensions.monito@drieu.org.gschema.xml
+++ b/schemas/org.gnome.shell.extensions.monito@drieu.org.gschema.xml
@@ -93,11 +93,11 @@
- ['service_description']
+ ['status','host_name','service_display_name','last_check','attempts','status_information']
-
- [0]
+
+ ['host_name+','service_display_name+']
diff --git a/servers/genericserver.js b/servers/genericserver.js
new file mode 100644
index 0000000..e399943
--- /dev/null
+++ b/servers/genericserver.js
@@ -0,0 +1,76 @@
+/* -*- mode: js; js-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Monito Gnome-Shell extension
+ Copyright (C) 2021 Benjamin Drieu
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 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 General Public License for more details.
+
+ You should have received a copy of the GNU 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.
+
+ SPDX-License-Identifier: GPL-2.0-or-later
+*/
+
+const { Soup } = imports.gi;
+
+const ExtensionUtils = imports.misc.extensionUtils;
+const Lang = imports.lang;
+const Main = imports.ui.main;
+const Me = ExtensionUtils.getCurrentExtension();
+const Preferences = Me.imports.prefs;
+
+let _httpSession;
+
+
+class GenericServer {
+ constructor ( _server, _serverType = 'Generic' )
+ {
+ log ( '>>> New %s server #%s'.format ( _serverType, _server ) );
+
+ this.server = _server;
+ }
+
+ getProcessedStatus ( )
+ {
+ let status = this.status.service_status;
+
+ this.columns = Preferences.getColumns(this.server);
+ this.sortOrder = Preferences.getSortOrder(this.server);
+
+ log ( this.sortOrder );
+ status = status.sort ( Lang.bind ( this, this.compareServices ) );
+
+ return status;
+ }
+
+
+ compareServices ( a, b )
+ {
+ for ( let _comparison of this.sortOrder )
+ {
+ let _name = _comparison.substring ( 0, _comparison.length - 1 );
+ let _order = _comparison.substring ( _comparison.length - 1, _comparison.length );
+ if ( _name && _order && _name in a && _name in b )
+ {
+ let _result = a [ _name ] . localeCompare ( b [ _name ] );
+ if ( _result != 0 )
+ {
+ if ( _order == '-' )
+ return - _result;
+ else
+ return _result;
+ }
+ }
+ }
+ return 0;
+ }
+}
diff --git a/servers/icinga.js b/servers/icinga.js
index bf46a6f..bb34d84 100644
--- a/servers/icinga.js
+++ b/servers/icinga.js
@@ -27,14 +27,14 @@ const Lang = imports.lang;
const Main = imports.ui.main;
const Me = ExtensionUtils.getCurrentExtension();
const Preferences = Me.imports.prefs;
+const GenericServer = Me.imports.servers.genericserver.GenericServer;
let _httpSession;
-class Icinga {
+class Icinga extends GenericServer {
constructor ( _server ) {
- log ( '>>> New Icinga #' + _server );
- this.server = _server
+ super(_server, 'Icinga');
}
refresh ( extension ) {
diff --git a/servers/icinga2.js b/servers/icinga2.js
index b78ea26..12f7d47 100644
--- a/servers/icinga2.js
+++ b/servers/icinga2.js
@@ -27,15 +27,15 @@ const Lang = imports.lang;
const Main = imports.ui.main;
const Me = ExtensionUtils.getCurrentExtension();
const Preferences = Me.imports.prefs;
+const GenericServer = Me.imports.servers.genericserver.GenericServer;
let _httpSession;
-class Icinga2 {
+class Icinga2 extends GenericServer {
constructor ( _server ) {
- log ( '>>> New Icinga2 #' + _server );
- this.server = _server
- }
+ super(_server, 'Icinga2');
+ }
refresh ( extension ) {
this.extension = extension;