From b468ca03267c8c7ccf04e0c446d0ca7d95192692 Mon Sep 17 00:00:00 2001 From: Benjamin Drieu Date: Wed, 11 May 2022 12:08:41 +0200 Subject: [PATCH] - Implement Hover - Implement services lines fold/unfold - Implement new action for services lines : launche browser - Some refactoring --- extension.js | 139 +++++++++++++----- prefs.js | 30 +++- ...ll.extensions.monito@drieu.org.gschema.xml | 8 + servers/genericserver.js | 7 +- servers/icinga2.js | 5 + servers/icinga2api.js | 6 + stylesheet.css | 4 + 7 files changed, 156 insertions(+), 43 deletions(-) diff --git a/extension.js b/extension.js index 0638038..6dc7b27 100644 --- a/extension.js +++ b/extension.js @@ -168,16 +168,16 @@ class Indicator extends PanelMenu.Button { this._buttonMenu.actor.add_child (this._searchField); - this._prefsButton = this._createButton ( 'preferences-system-symbolic', _('Preferences'), this._onPreferencesActivate ); + this._prefsButton = this._createButton ( 'big', 'preferences-system-symbolic', _('Preferences'), this._onPreferencesActivate ); this._buttonMenu.actor.add_child (this._prefsButton); if ( this.serverLogic && this.serverLogic.canRecheck ) { - this._recheckButton = this._createButton ( 'mail-send-receive-symbolic', _('Recheck all'), this.recheckAll ); + this._recheckButton = this._createButton ( 'big', 'mail-send-receive-symbolic', _('Recheck all'), this.recheckAll ); this._buttonMenu.actor.add_child (this._recheckButton ); } - this._reloadButton = this._createButton ( 'view-refresh-symbolic', _('Reload view'), this.updateStatus ); + this._reloadButton = this._createButton ( 'big', 'view-refresh-symbolic', _('Reload view'), this.updateStatus ); this._buttonMenu.actor.add_child (this._reloadButton ); let _intermediate = new PopupMenu.PopupBaseMenuItem ( { @@ -330,35 +330,31 @@ class Indicator extends PanelMenu.Button { text = '…'; if ( ! col [ 'special' ] ) + { _child = new St.Label ( { style_class: 'monito-label', + reactive: true, + can_focus: true, + track_hover: true, width: col.width, - text: text.toString(), + text: text.toString().replace(/\n.*/s, ''), x_align: ( col.align ? col.align : Clutter.ActorAlign.START ), style: ( col.style ? col.style : '' ) } ); - else if ( col.special == 'actions' && this.serverLogic.canRecheck ) + _child.original_text = text.toString(); + _child.connect('button-press-event', Lang.bind(this, this._onExpandLabel ) ); + _child.connect('notify::hover', Lang.bind(this, this._onEnterEvent ) ); + } + else if ( col.special == 'actions' ) { _child = new St.BoxLayout ( { x_expand: true, vertical: false, width: col.width, } ); - let _button = new St.Button ( { - style_class: 'button small-button', - x_expand: true, - x_align: Clutter.ActorAlign.END, - y_align: Clutter.ActorAlign.CENTER, - width: 24, - height: 24, - can_focus: true, - } ); - _button.prevIcon = 'mail-send-receive-symbolic'; - _button.service = text; - _button.connect ( 'clicked', Lang.bind ( this, this._onRecheckButtonClick ) ); - _button.child = new St.Icon ( { - icon_name: 'mail-send-receive-symbolic', - icon_size: 16, - width: 16, - height: 16, - } ); - _child.add_child ( _button ); + + if ( this.serverLogic.canRecheck ) + { + _child.add_child ( this._createButton ( 'small', 'mail-send-receive-symbolic', text, this._onRecheckButtonClick ) ); + } + _child.add_child ( this._createButton ( 'small', 'web-browser-symbolic', text, this._onOpenInBrowser ) ); + } let _bin = new St.Bin({ @@ -457,8 +453,10 @@ class Indicator extends PanelMenu.Button { let infoBox = new St.BoxLayout({ style_class: 'monito-service-line', style: _style, - track_hover: true, x_expand: true, + reactive: true, + can_focus: true, + track_hover: true, }); tableBox.add_child(infoBox); @@ -485,8 +483,7 @@ class Indicator extends PanelMenu.Button { infoBox.add_child ( this.createBin ( entry.status, entry [ _col ], column_definitions [ _col ] ) ); } - if ( this.serverLogic.canRecheck ) - infoBox.add_child ( this.createBin ( entry.status, entry, column_definitions [ 'actions' ] ) ); + infoBox.add_child ( this.createBin ( entry.status, entry, column_definitions [ 'actions' ] ) ); _row ++; } @@ -578,25 +575,101 @@ class Indicator extends PanelMenu.Button { this.serverLogic.recheck ( e.service ); } - _createButton ( icon, text, callback ) { + _onExpandLabel ( e ) + { + log ( "Monito: Click label " + e.original_text ); + let temp = e.text; + e.text = e.original_text; + e.original_text = temp; + if ( e.clutter_text.line_wrap ) + { + e.clutter_text.line_wrap = false; + } + else + { + e.clutter_text.line_wrap = true; + e.clutter_text.line_wrap_mode = Pango.WrapMode.WORD; + e.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; + } + + } + + _onEnterEvent ( e ) + { + log ( "Monito: enter"); + } + + _onOpenInBrowser ( e ) + { + this.spinChildOf ( e ); + e.service.button = e; + + let loop = GLib.MainLoop.new(null, false); + try { + let _cmd = "%s %s".format(settings.get_string ( "web-browser" ), this.serverLogic.getUrlForService ( e.service ) ); + let proc = Gio.Subprocess.new ( + _cmd.split ( ' ' ), + Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE + ); + + let cancellable = new Gio.Cancellable(); + proc.wait_async(cancellable, (proc, result) => { + try { + proc.wait_finish(result); + + if (proc.get_successful()) { + log ( 'Monito: the process succeeded'); + } else { + log ( 'Monito: the process failed' ); + } + this.stopChildSpin ( e.service.button ); + + } catch (e) { + logError(e); + } finally { + loop.quit(); + } + }); + log ( 'Monito: ' + proc ); + } catch ( e ) { + log ( 'Monito: ' + e ); + } + } + + _createButton ( sizeName, icon, data, callback ) { + let size = 24; + if ( sizeName == 'small' ) + size = 24; + else if ( sizeName == 'big' ) + size = 32; + + let _text = ''; + if ( ! data instanceof Object ) + _text = data; + let button = new St.Button({ x_align: Clutter.ActorAlign.END, y_align: Clutter.ActorAlign.CENTER, reactive: true, can_focus: true, track_hover: true, - accessible_name: text, - style_class: 'button big-button', + accessible_name: _text, + style_class: 'button %s-button'.format(sizeName), rotation_angle_x: 0.0, +// width: size, +// height: size }); button.prevIcon = icon; + if ( data instanceof Object ) + button.service = data; + button.child = new St.Icon({ style_class: 'monito-button-icon', icon_name: icon, - icon_size: 24, - width: 24, - height: 24, + icon_size: size - 4, + width: size - 4, + height: size - 4 }); button.connect('clicked', Lang.bind(this, callback ) ); diff --git a/prefs.js b/prefs.js index 41e8a0a..9280fcc 100644 --- a/prefs.js +++ b/prefs.js @@ -49,7 +49,8 @@ const prefs = [ { type: Gtk.ComboBoxText, category: 'Settings', label: _('Type'), key: 'type' }, { type: Gtk.Entry, category: 'Settings', label: _('Username'), key: 'username' }, { type: Gtk.Entry, category: 'Settings', label: _('Password'), key: 'password' }, - { type: Gtk.Entry, category: 'Settings', label: _('URL CGI'), key: 'urlcgi' }, + { type: Gtk.Entry, category: 'Settings', label: _('Web URL'), key: 'url' }, + { type: Gtk.Entry, category: 'Settings', label: _('CGI / API URL'), key: 'urlcgi' }, { type: Gtk.Switch, category: 'Settings', label: _('Check SSL certificate'), key: 'strict-ssl', align: Gtk.Align.START }, { type: Gtk.ColorButton, category: 'Colors', label: _('OK background color'), key: 'ok-color', align: Gtk.Align.START }, { type: Gtk.ColorButton, category: 'Colors', label: _('Warning background color'), key: 'warning-color', align: Gtk.Align.START }, @@ -97,7 +98,7 @@ function buildPrefsWidget() { let mainWidget = new Gtk.Notebook( { } ); let prefsWidget = new Gtk.Grid({ -// margin: 18, + margin: 18, column_spacing: 12, row_spacing: 12, column_homogeneous: false, @@ -107,14 +108,14 @@ function buildPrefsWidget() { // Add a simple title and add it to the prefsWidget let title = new Gtk.Label({ - label: `${Me.metadata.name} Preferences`, + label: '' + _('Monito Preferences') + '', halign: Gtk.Align.START, use_markup: true, }); prefsWidget.attach(title, 0, 0, 2, 1); let _label = new Gtk.Label({ - label: 'Poll delay in seconds', + label: _('Poll delay in seconds'), visible: true, halign: Gtk.Align.START, }); @@ -132,16 +133,33 @@ function buildPrefsWidget() { prefsWidget.attach ( _entry, 1, 1, 1, 1 ); this.settings.bind ( 'poll-delay', _entry, 'value', Gio.SettingsBindFlags.DEFAULT ); + + _label = new Gtk.Label({ + label: _('Web browser'), + visible: true, + halign: Gtk.Align.START, + }); + prefsWidget.attach ( _label, 0, 2, 1, 1 ); + + _entry = new Gtk.Entry ({ + halign: Gtk.Align.FILL, + visible: true, + hexpand: true, + can_focus: true, + }); + prefsWidget.attach ( _entry, 1, 2, 1, 1 ); + this.settings.bind ( 'web-browser', _entry, 'text', Gio.SettingsBindFlags.DEFAULT ); + // Misc Settings (TBD) mainWidget.append_page ( prefsWidget, - new Gtk.Label ( { label: 'General', } ) ); + new Gtk.Label ( { label: _('General'), } ) ); // Accounts this._accountsWidgetContainer = new Gtk.Box( { orientation: Gtk.Orientation.HORIZONTAL, homogeneous: false, } ); mainWidget.append_page ( this._accountsWidgetContainer, - new Gtk.Label ( { label: 'Servers', } ) ); + new Gtk.Label ( { label: _('Servers'), } ) ); let accountsChooserContainer = new Gtk.Box( { orientation: Gtk.Orientation.VERTICAL, homogeneous: false, } ); 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 dc45f34..0f0d9e0 100644 --- a/schemas/org.gnome.shell.extensions.monito@drieu.org.gschema.xml +++ b/schemas/org.gnome.shell.extensions.monito@drieu.org.gschema.xml @@ -48,6 +48,10 @@ 300 + + "/usr/bin/firefox" + + @@ -77,6 +81,10 @@ '' + + '' + + '' diff --git a/servers/genericserver.js b/servers/genericserver.js index 9b8de32..a29b899 100644 --- a/servers/genericserver.js +++ b/servers/genericserver.js @@ -110,14 +110,13 @@ class GenericServer { this.status.service_status = [ ]; this.error = null; - log ( message.status_code ); - log ( message.response_body ); +// log ( message.status_code ); +// log ( message.response_body ); message.response_headers.foreach ((name, val) => { log (name, val); }); - log ( message.response_body.data ); +// log ( message.response_body.data ); - if ( message.status_code != Soup.Status.OK ) { log ( '>>> Error: ' + message.reason_phrase ); diff --git a/servers/icinga2.js b/servers/icinga2.js index f90fed0..9b926a6 100644 --- a/servers/icinga2.js +++ b/servers/icinga2.js @@ -79,5 +79,10 @@ class Icinga2 extends GenericServer { this.extension.refreshUI ( this ); return ! this.error; } + + getUrlForService ( service ) + { + return this._settings.get_string ( 'url' ) ; // + monitoring/service/show?host=XXX&service=XXX + } } diff --git a/servers/icinga2api.js b/servers/icinga2api.js index 960094f..46eb8b0 100644 --- a/servers/icinga2api.js +++ b/servers/icinga2api.js @@ -121,5 +121,11 @@ class Icinga2API extends GenericServer { this.extension.refreshUI ( this ); return ! this.error; } + + getUrlForService ( service ) + { + return this._settings.get_string ( 'url' ) ; + } + } diff --git a/stylesheet.css b/stylesheet.css index 1a58019..3d1fa08 100644 --- a/stylesheet.css +++ b/stylesheet.css @@ -72,6 +72,10 @@ line-height: 20px; } +.monito-service-line:hover { + font-weight: bold; +} + .monito-title { margin: 2px; font-size: 200%;