- Implement Hover

- Implement services lines fold/unfold
- Implement new action for services lines : launche browser
- Some refactoring
This commit is contained in:
Benjamin Drieu 2022-05-11 12:08:41 +02:00
parent 31120af615
commit c046b12723
7 changed files with 156 additions and 43 deletions

View File

@ -168,16 +168,16 @@ class Indicator extends PanelMenu.Button {
this._buttonMenu.actor.add_child (this._searchField); 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); this._buttonMenu.actor.add_child (this._prefsButton);
if ( this.serverLogic && this.serverLogic.canRecheck ) 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._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 ); this._buttonMenu.actor.add_child (this._reloadButton );
let _intermediate = new PopupMenu.PopupBaseMenuItem ( { let _intermediate = new PopupMenu.PopupBaseMenuItem ( {
@ -330,35 +330,31 @@ class Indicator extends PanelMenu.Button {
text = '…'; text = '…';
if ( ! col [ 'special' ] ) if ( ! col [ 'special' ] )
{
_child = new St.Label ( { style_class: 'monito-label', _child = new St.Label ( { style_class: 'monito-label',
reactive: true,
can_focus: true,
track_hover: true,
width: col.width, width: col.width,
text: text.toString(), text: text.toString().replace(/\n.*/s, ''),
x_align: ( col.align ? col.align : Clutter.ActorAlign.START ), x_align: ( col.align ? col.align : Clutter.ActorAlign.START ),
style: ( col.style ? col.style : '' ) } ); 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, _child = new St.BoxLayout ( { x_expand: true,
vertical: false, vertical: false,
width: col.width, } ); width: col.width, } );
let _button = new St.Button ( {
style_class: 'button small-button', if ( this.serverLogic.canRecheck )
x_expand: true, {
x_align: Clutter.ActorAlign.END, _child.add_child ( this._createButton ( 'small', 'mail-send-receive-symbolic', text, this._onRecheckButtonClick ) );
y_align: Clutter.ActorAlign.CENTER, }
width: 24, _child.add_child ( this._createButton ( 'small', 'web-browser-symbolic', text, this._onOpenInBrowser ) );
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 );
} }
let _bin = new St.Bin({ let _bin = new St.Bin({
@ -457,8 +453,10 @@ class Indicator extends PanelMenu.Button {
let infoBox = new St.BoxLayout({ let infoBox = new St.BoxLayout({
style_class: 'monito-service-line', style_class: 'monito-service-line',
style: _style, style: _style,
track_hover: true,
x_expand: true, x_expand: true,
reactive: true,
can_focus: true,
track_hover: true,
}); });
tableBox.add_child(infoBox); 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 ] ) ); 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 ++; _row ++;
} }
@ -578,25 +575,101 @@ class Indicator extends PanelMenu.Button {
this.serverLogic.recheck ( e.service ); 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({ let button = new St.Button({
x_align: Clutter.ActorAlign.END, x_align: Clutter.ActorAlign.END,
y_align: Clutter.ActorAlign.CENTER, y_align: Clutter.ActorAlign.CENTER,
reactive: true, reactive: true,
can_focus: true, can_focus: true,
track_hover: true, track_hover: true,
accessible_name: text, accessible_name: _text,
style_class: 'button big-button', style_class: 'button %s-button'.format(sizeName),
rotation_angle_x: 0.0, rotation_angle_x: 0.0,
// width: size,
// height: size
}); });
button.prevIcon = icon; button.prevIcon = icon;
if ( data instanceof Object )
button.service = data;
button.child = new St.Icon({ button.child = new St.Icon({
style_class: 'monito-button-icon', style_class: 'monito-button-icon',
icon_name: icon, icon_name: icon,
icon_size: 24, icon_size: size - 4,
width: 24, width: size - 4,
height: 24, height: size - 4
}); });
button.connect('clicked', Lang.bind(this, callback ) ); button.connect('clicked', Lang.bind(this, callback ) );

View File

@ -49,7 +49,8 @@ const prefs = [
{ type: Gtk.ComboBoxText, category: 'Settings', label: _('Type'), key: 'type' }, { type: Gtk.ComboBoxText, category: 'Settings', label: _('Type'), key: 'type' },
{ type: Gtk.Entry, category: 'Settings', label: _('Username'), key: 'username' }, { type: Gtk.Entry, category: 'Settings', label: _('Username'), key: 'username' },
{ type: Gtk.Entry, category: 'Settings', label: _('Password'), key: 'password' }, { 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.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: _('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 }, { 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 mainWidget = new Gtk.Notebook( { } );
let prefsWidget = new Gtk.Grid({ let prefsWidget = new Gtk.Grid({
// margin: 18, margin: 18,
column_spacing: 12, column_spacing: 12,
row_spacing: 12, row_spacing: 12,
column_homogeneous: false, column_homogeneous: false,
@ -107,14 +108,14 @@ function buildPrefsWidget() {
// Add a simple title and add it to the prefsWidget // Add a simple title and add it to the prefsWidget
let title = new Gtk.Label({ let title = new Gtk.Label({
label: `<b>${Me.metadata.name} Preferences</b>`, label: '<b>' + _('Monito Preferences') + '</b>',
halign: Gtk.Align.START, halign: Gtk.Align.START,
use_markup: true, use_markup: true,
}); });
prefsWidget.attach(title, 0, 0, 2, 1); prefsWidget.attach(title, 0, 0, 2, 1);
let _label = new Gtk.Label({ let _label = new Gtk.Label({
label: 'Poll delay in seconds', label: _('Poll delay in seconds'),
visible: true, visible: true,
halign: Gtk.Align.START, halign: Gtk.Align.START,
}); });
@ -132,16 +133,33 @@ function buildPrefsWidget() {
prefsWidget.attach ( _entry, 1, 1, 1, 1 ); prefsWidget.attach ( _entry, 1, 1, 1, 1 );
this.settings.bind ( 'poll-delay', _entry, 'value', Gio.SettingsBindFlags.DEFAULT ); 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) // Misc Settings (TBD)
mainWidget.append_page ( prefsWidget, mainWidget.append_page ( prefsWidget,
new Gtk.Label ( { label: 'General', } ) ); new Gtk.Label ( { label: _('General'), } ) );
// Accounts // Accounts
this._accountsWidgetContainer = new Gtk.Box( { orientation: Gtk.Orientation.HORIZONTAL, this._accountsWidgetContainer = new Gtk.Box( { orientation: Gtk.Orientation.HORIZONTAL,
homogeneous: false, } ); homogeneous: false, } );
mainWidget.append_page ( this._accountsWidgetContainer, mainWidget.append_page ( this._accountsWidgetContainer,
new Gtk.Label ( { label: 'Servers', } ) ); new Gtk.Label ( { label: _('Servers'), } ) );
let accountsChooserContainer = new Gtk.Box( { orientation: Gtk.Orientation.VERTICAL, let accountsChooserContainer = new Gtk.Box( { orientation: Gtk.Orientation.VERTICAL,
homogeneous: false, } ); homogeneous: false, } );

View File

@ -48,6 +48,10 @@
<default>300</default> <default>300</default>
</key> </key>
<key name="web-browser" type="s">
<default>"/usr/bin/firefox"</default>
</key>
</schema> </schema>
<!-- Account list --> <!-- Account list -->
@ -77,6 +81,10 @@
<default>''</default> <default>''</default>
</key> </key>
<key name="url" type="s">
<default>''</default>
</key>
<key name="urlcgi" type="s"> <key name="urlcgi" type="s">
<default>''</default> <default>''</default>
</key> </key>

View File

@ -110,13 +110,12 @@ class GenericServer {
this.status.service_status = [ ]; this.status.service_status = [ ];
this.error = null; this.error = null;
log ( message.status_code ); // log ( message.status_code );
log ( message.response_body ); // log ( message.response_body );
message.response_headers.foreach ((name, val) => { message.response_headers.foreach ((name, val) => {
log (name, val); log (name, val);
}); });
log ( message.response_body.data ); // log ( message.response_body.data );
if ( message.status_code != Soup.Status.OK ) if ( message.status_code != Soup.Status.OK )
{ {

View File

@ -79,5 +79,10 @@ class Icinga2 extends GenericServer {
this.extension.refreshUI ( this ); this.extension.refreshUI ( this );
return ! this.error; return ! this.error;
} }
getUrlForService ( service )
{
return this._settings.get_string ( 'url' ) ; // + monitoring/service/show?host=XXX&service=XXX
}
} }

View File

@ -121,5 +121,11 @@ class Icinga2API extends GenericServer {
this.extension.refreshUI ( this ); this.extension.refreshUI ( this );
return ! this.error; return ! this.error;
} }
getUrlForService ( service )
{
return this._settings.get_string ( 'url' ) ;
}
} }

View File

@ -72,6 +72,10 @@
line-height: 20px; line-height: 20px;
} }
.monito-service-line:hover {
font-weight: bold;
}
.monito-title { .monito-title {
margin: 2px; margin: 2px;
font-size: 200%; font-size: 200%;