Implement natural date + fixes
This commit is contained in:
parent
f18d8bbd61
commit
5cfb752943
40
extension.js
40
extension.js
@ -62,8 +62,8 @@ const column_definitions = {
|
|||||||
has_been_acknowledged: { label: _('Ack'), width: 50, expand: false, align: Clutter.ActorAlign.CENTER, style: 'font-weight:bold;' },
|
has_been_acknowledged: { label: _('Ack'), width: 50, expand: false, align: Clutter.ActorAlign.CENTER, style: 'font-weight:bold;' },
|
||||||
last_check: { label: _('Last check'), width: 200, expand: false, type: 'date' },
|
last_check: { label: _('Last check'), width: 200, expand: false, type: 'date' },
|
||||||
attempts: { label: _('Attempts'), width: 50, expand: false, },
|
attempts: { label: _('Attempts'), width: 50, expand: false, },
|
||||||
status_information: { label: _('Information'), width: 600, expand: true, },
|
status_information: { label: _('Information'), width: 600, expand: false, },
|
||||||
actions: { label: 'Actions', width: 100, expand: true, special: 'actions' },
|
actions: { label: 'Actions', width: 120, expand: false, special: 'actions' },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -144,16 +144,19 @@ class Indicator extends PanelMenu.Button {
|
|||||||
_iconBin.child = _icon;
|
_iconBin.child = _icon;
|
||||||
this._buttonMenu.actor.add_actor(_iconBin);
|
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._buttonMenu.actor.add_actor(this._mainLabel);
|
||||||
|
|
||||||
this._prefsButton = this._createButton ( 'preferences-system-symbolic', 'Preferences', this._onPreferencesActivate );
|
this._prefsButton = this._createButton ( 'preferences-system-symbolic', _('Preferences'), this._onPreferencesActivate );
|
||||||
this._buttonMenu.actor.add_child (this._prefsButton);
|
this._buttonMenu.actor.add_child (this._prefsButton);
|
||||||
|
|
||||||
this._updateButton = this._createButton ( 'emblem-synchronizing-symbolic', 'Reload', this.updateStatus ); // Implement this
|
if ( this.serverLogic && this.serverLogic.canRecheck )
|
||||||
this._buttonMenu.actor.add_child (this._updateButton );
|
{
|
||||||
|
this._recheckButton = this._createButton ( 'system-run-symbolic', _('Recheck all'), this.recheckAll );
|
||||||
|
this._buttonMenu.actor.add_child (this._recheckButton );
|
||||||
|
}
|
||||||
|
|
||||||
this._reloadButton = this._createButton ( 'view-refresh-symbolic', 'Reload', this.updateStatus );
|
this._reloadButton = this._createButton ( '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 ( {
|
||||||
@ -194,6 +197,12 @@ class Indicator extends PanelMenu.Button {
|
|||||||
'UNKNOWN': 0 };
|
'UNKNOWN': 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recheckAll ( )
|
||||||
|
{
|
||||||
|
this.spinChildOf ( this._recheckButton );
|
||||||
|
this.serverLogic.recheckAll ( this._recheckButton );
|
||||||
|
}
|
||||||
|
|
||||||
updateStatus ( )
|
updateStatus ( )
|
||||||
{
|
{
|
||||||
this.spinChildOf ( this._reloadButton );
|
this.spinChildOf ( this._reloadButton );
|
||||||
@ -262,7 +271,7 @@ class Indicator extends PanelMenu.Button {
|
|||||||
_iconBin.child = this.sortIcons [ colName ];
|
_iconBin.child = this.sortIcons [ colName ];
|
||||||
|
|
||||||
let _button = new St.Button ( {
|
let _button = new St.Button ( {
|
||||||
x_align: Clutter.ActorAlign.START,
|
x_align: Clutter.ActorAlign.FILL,
|
||||||
y_align: Clutter.ActorAlign.CENTER,
|
y_align: Clutter.ActorAlign.CENTER,
|
||||||
width: col.width,
|
width: col.width,
|
||||||
reactive: true,
|
reactive: true,
|
||||||
@ -294,24 +303,28 @@ class Indicator extends PanelMenu.Button {
|
|||||||
|
|
||||||
if ( ! col [ 'special' ] )
|
if ( ! col [ 'special' ] )
|
||||||
_child = new St.Label ( { style_class: 'monito-label',
|
_child = new St.Label ( { style_class: 'monito-label',
|
||||||
|
width: col.width,
|
||||||
text: text.toString(),
|
text: text.toString(),
|
||||||
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 )
|
else if ( col.special == 'actions' && this.serverLogic.canRecheck )
|
||||||
{
|
{
|
||||||
_child = new St.BoxLayout ( { x_expand: false,
|
_child = new St.BoxLayout ( { x_expand: true,
|
||||||
vertical: false } );
|
vertical: false,
|
||||||
|
width: col.width, } );
|
||||||
let _button = new St.Button ( {
|
let _button = new St.Button ( {
|
||||||
style_class: 'button small-button',
|
style_class: 'button small-button',
|
||||||
x_expand: true,
|
x_expand: true,
|
||||||
x_align: Clutter.ActorAlign.END,
|
x_align: Clutter.ActorAlign.END,
|
||||||
y_align: Clutter.ActorAlign.CENTER,
|
y_align: Clutter.ActorAlign.CENTER,
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
can_focus: true,
|
can_focus: true,
|
||||||
} );
|
} );
|
||||||
_button.service = text;
|
_button.service = text;
|
||||||
_button.connect ( 'clicked', Lang.bind ( this, this._onRecheckButtonClick ) );
|
_button.connect ( 'clicked', Lang.bind ( this, this._onRecheckButtonClick ) );
|
||||||
_button.child = new St.Icon ( {
|
_button.child = new St.Icon ( {
|
||||||
icon_name: 'view-refresh-symbolic',
|
icon_name: 'system-run-symbolic',
|
||||||
icon_size: 16,
|
icon_size: 16,
|
||||||
width: 16,
|
width: 16,
|
||||||
height: 16,
|
height: 16,
|
||||||
@ -320,7 +333,6 @@ class Indicator extends PanelMenu.Button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let _bin = new St.Bin({
|
let _bin = new St.Bin({
|
||||||
// style: 'background: purple',
|
|
||||||
track_hover: true,
|
track_hover: true,
|
||||||
width: col.width,
|
width: col.width,
|
||||||
x_expand: col.expand,
|
x_expand: col.expand,
|
||||||
@ -374,7 +386,7 @@ class Indicator extends PanelMenu.Button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let headerBox = new St.BoxLayout({
|
let headerBox = new St.BoxLayout({
|
||||||
hover: true,
|
track_hover: true,
|
||||||
x_expand: true
|
x_expand: true
|
||||||
});
|
});
|
||||||
this._box.add_child(headerBox);
|
this._box.add_child(headerBox);
|
||||||
@ -389,7 +401,7 @@ class Indicator extends PanelMenu.Button {
|
|||||||
this._box.add_child(scrollBox);
|
this._box.add_child(scrollBox);
|
||||||
|
|
||||||
let tableBox = new St.BoxLayout({
|
let tableBox = new St.BoxLayout({
|
||||||
hover: true,
|
track_hover: true,
|
||||||
vertical: true,
|
vertical: true,
|
||||||
x_expand: true,
|
x_expand: true,
|
||||||
});
|
});
|
||||||
|
4
prefs.js
4
prefs.js
@ -281,8 +281,8 @@ function createPrefWidgets ( noteBook, type, isActive )
|
|||||||
else if ( prefEntry.key == 'type' )
|
else if ( prefEntry.key == 'type' )
|
||||||
{
|
{
|
||||||
[ { name: 'Icinga', value: 'Icinga server' },
|
[ { name: 'Icinga', value: 'Icinga server' },
|
||||||
{ name: 'Icinga2', value: 'Icinga2 server (using Icingaweb2)' },
|
{ name: 'Icinga2API', value: 'Icinga2 server (using API, prefered)' },
|
||||||
{ name: 'Icinga2API', value: 'Icinga2 server (using API)' } ].forEach((item) => {
|
{ name: 'Icinga2', value: 'Icinga2 server (using Icingaweb2, limited)' } ].forEach((item) => {
|
||||||
this.prefWidgets[prefEntry.key].insert ( -1, item.name, item.value );
|
this.prefWidgets[prefEntry.key].insert ( -1, item.name, item.value );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
<schemalist >
|
<schemalist >
|
||||||
<enum id="org.gnome.shell.extensions.monito.MonitoringType">
|
<enum id="org.gnome.shell.extensions.monito.MonitoringType">
|
||||||
<value value="0" nick="Icinga"/>
|
<value value="0" nick="Icinga"/>
|
||||||
<value value="1" nick="Icinga2"/>
|
<value value="1" nick="Icinga2API"/>
|
||||||
<value value="2" nick="Icinga2API"/>
|
<value value="2" nick="Icinga2"/>
|
||||||
</enum>
|
</enum>
|
||||||
|
|
||||||
<enum id="org.gnome.shell.extensions.monito.DisplayType">
|
<enum id="org.gnome.shell.extensions.monito.DisplayType">
|
||||||
|
@ -224,4 +224,86 @@ class GenericServer {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
formatDate ( date )
|
||||||
|
{
|
||||||
|
if ( typeof date == 'string' || date instanceof String )
|
||||||
|
{
|
||||||
|
date = Date.parse ( date ) / 1000;
|
||||||
|
log ( date );
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.timeAgo ( new Date ( date * 1000 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
getFormattedDate(date, prefomattedDate = false, hideYear = false)
|
||||||
|
{
|
||||||
|
const MONTH_NAMES = [
|
||||||
|
'Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.',
|
||||||
|
'Jul.', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.'
|
||||||
|
];
|
||||||
|
|
||||||
|
const day = date.getDate();
|
||||||
|
const month = MONTH_NAMES[date.getMonth()];
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const hours = date.getHours();
|
||||||
|
let minutes = date.getMinutes();
|
||||||
|
|
||||||
|
if (minutes < 10) {
|
||||||
|
// Adding leading zero to minutes
|
||||||
|
minutes = _(`0${ minutes }`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prefomattedDate) {
|
||||||
|
// Today at 10:20
|
||||||
|
// Yesterday at 10:20
|
||||||
|
return _(`${ prefomattedDate } at ${ hours }:${ minutes }`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hideYear) {
|
||||||
|
// 10. January at 10:20
|
||||||
|
return _(`${ month } ${ day } at ${ hours }:${ minutes }`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10. January 2017. at 10:20
|
||||||
|
return _(`${ year } ${ month } ${ day }`);
|
||||||
|
}
|
||||||
|
|
||||||
|
timeAgo ( dateParam )
|
||||||
|
{
|
||||||
|
if (!dateParam) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const date = typeof dateParam === 'object' ? dateParam : new Date(dateParam);
|
||||||
|
const DAY_IN_MS = 86400000; // 24 * 60 * 60 * 1000
|
||||||
|
const today = new Date();
|
||||||
|
const yesterday = new Date(today - DAY_IN_MS);
|
||||||
|
const seconds = Math.round((today - date) / 1000);
|
||||||
|
const minutes = Math.round(seconds / 60);
|
||||||
|
const isToday = today.toDateString() === date.toDateString();
|
||||||
|
const isYesterday = yesterday.toDateString() === date.toDateString();
|
||||||
|
const isThisYear = today.getFullYear() === date.getFullYear();
|
||||||
|
|
||||||
|
|
||||||
|
if (seconds < 5) {
|
||||||
|
return 'now';
|
||||||
|
} else if (seconds < 60) {
|
||||||
|
return `${ seconds } seconds ago`;
|
||||||
|
} else if (seconds < 90) {
|
||||||
|
return 'a minute ago';
|
||||||
|
} else if (minutes < 60) {
|
||||||
|
return `${ minutes } minutes ago`;
|
||||||
|
} else if (isToday) {
|
||||||
|
return this.getFormattedDate(date, 'today'); // Today at 10:20
|
||||||
|
} else if (isYesterday) {
|
||||||
|
return this.getFormattedDate(date, 'yesterday'); // Yesterday at 10:20
|
||||||
|
} else if (isThisYear) {
|
||||||
|
return this.getFormattedDate(date, false, true); // 10. January at 10:20
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.getFormattedDate(date); // 10. January 2017. at 10:20
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,11 @@ class Icinga extends GenericServer {
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
let json = JSON.parse ( _data );
|
let json = JSON.parse ( _data );
|
||||||
|
|
||||||
this.status = json.status;
|
this.status = json.status;
|
||||||
|
log ( this.status );
|
||||||
|
for ( var entry of this.status.service_status )
|
||||||
|
entry.last_check = this.formatDate ( entry.last_check );
|
||||||
}
|
}
|
||||||
|
|
||||||
this.extension.refreshUI ( this );
|
this.extension.refreshUI ( this );
|
||||||
|
@ -71,7 +71,7 @@ class Icinga2 extends GenericServer {
|
|||||||
attempts: entry.service_attempt,
|
attempts: entry.service_attempt,
|
||||||
has_been_acknowledged: parseInt(entry.service_acknowledged),
|
has_been_acknowledged: parseInt(entry.service_acknowledged),
|
||||||
status_information: entry.service_output,
|
status_information: entry.service_output,
|
||||||
last_check: new Date ( parseInt(entry.service_last_state_change) * 1000 ) . toString(),
|
last_check: this.formatDate(parseInt(entry.service_last_state_change)),
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,10 +62,25 @@ class Icinga2API extends GenericServer {
|
|||||||
message.request_body.flatten();
|
message.request_body.flatten();
|
||||||
message.button = entry.button;
|
message.button = entry.button;
|
||||||
|
|
||||||
// log ( '> Body: ' + message.request_body.data );
|
message.request_headers.append ( 'Accept', 'application/json' );
|
||||||
|
// log ( message.request_headers );
|
||||||
|
|
||||||
|
this.authenticateAndSend ( message, this.handleCMDMessage );
|
||||||
|
}
|
||||||
|
|
||||||
|
recheckAll ( button )
|
||||||
|
{
|
||||||
|
let message = Soup.form_request_new_from_hash ( 'POST', this.urlcgi + '/actions/reschedule-check', { } );
|
||||||
|
|
||||||
|
let params = '{ "type": "Service", "force": true, "pretty": true }';
|
||||||
|
|
||||||
|
message.request_body.truncate();
|
||||||
|
message.request_body.append ( params );
|
||||||
|
message.request_body.flatten();
|
||||||
|
message.button = button;
|
||||||
|
|
||||||
message.request_headers.append ( 'Accept', 'application/json' );
|
message.request_headers.append ( 'Accept', 'application/json' );
|
||||||
log ( message.request_headers );
|
// log ( message.request_headers );
|
||||||
|
|
||||||
this.authenticateAndSend ( message, this.handleCMDMessage );
|
this.authenticateAndSend ( message, this.handleCMDMessage );
|
||||||
}
|
}
|
||||||
@ -84,6 +99,7 @@ class Icinga2API extends GenericServer {
|
|||||||
|
|
||||||
for ( var entry of json.results )
|
for ( var entry of json.results )
|
||||||
{
|
{
|
||||||
|
// log ( JSON.stringify(entry) );
|
||||||
this.status.service_status.push ( {
|
this.status.service_status.push ( {
|
||||||
status: _statuses [ entry.attrs.state ],
|
status: _statuses [ entry.attrs.state ],
|
||||||
host_name: entry.attrs.host_name,
|
host_name: entry.attrs.host_name,
|
||||||
@ -91,7 +107,7 @@ class Icinga2API extends GenericServer {
|
|||||||
has_been_acknowledged: parseInt(entry.attrs.acknowledgement),
|
has_been_acknowledged: parseInt(entry.attrs.acknowledgement),
|
||||||
attempts: '%d/%d'.format(entry.attrs.check_attempt,entry.attrs.max_check_attempts),
|
attempts: '%d/%d'.format(entry.attrs.check_attempt,entry.attrs.max_check_attempts),
|
||||||
status_information: entry.attrs.last_check_result.output,
|
status_information: entry.attrs.last_check_result.output,
|
||||||
last_check: new Date ( entry.attrs.last_state_change * 1000 ) . toString(),
|
last_check: this.formatDate(parseInt(entry.attrs.last_check)),
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user