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;' },
|
||||
last_check: { label: _('Last check'), width: 200, expand: false, type: 'date' },
|
||||
attempts: { label: _('Attempts'), width: 50, expand: false, },
|
||||
status_information: { label: _('Information'), width: 600, expand: true, },
|
||||
actions: { label: 'Actions', width: 100, expand: true, special: 'actions' },
|
||||
status_information: { label: _('Information'), width: 600, expand: false, },
|
||||
actions: { label: 'Actions', width: 120, expand: false, special: 'actions' },
|
||||
};
|
||||
|
||||
|
||||
@ -144,16 +144,19 @@ 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 );
|
||||
this._prefsButton = this._createButton ( 'preferences-system-symbolic', _('Preferences'), this._onPreferencesActivate );
|
||||
this._buttonMenu.actor.add_child (this._prefsButton);
|
||||
|
||||
this._updateButton = this._createButton ( 'emblem-synchronizing-symbolic', 'Reload', this.updateStatus ); // Implement this
|
||||
this._buttonMenu.actor.add_child (this._updateButton );
|
||||
if ( this.serverLogic && this.serverLogic.canRecheck )
|
||||
{
|
||||
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 );
|
||||
|
||||
let _intermediate = new PopupMenu.PopupBaseMenuItem ( {
|
||||
@ -194,6 +197,12 @@ class Indicator extends PanelMenu.Button {
|
||||
'UNKNOWN': 0 };
|
||||
}
|
||||
|
||||
recheckAll ( )
|
||||
{
|
||||
this.spinChildOf ( this._recheckButton );
|
||||
this.serverLogic.recheckAll ( this._recheckButton );
|
||||
}
|
||||
|
||||
updateStatus ( )
|
||||
{
|
||||
this.spinChildOf ( this._reloadButton );
|
||||
@ -262,7 +271,7 @@ class Indicator extends PanelMenu.Button {
|
||||
_iconBin.child = this.sortIcons [ colName ];
|
||||
|
||||
let _button = new St.Button ( {
|
||||
x_align: Clutter.ActorAlign.START,
|
||||
x_align: Clutter.ActorAlign.FILL,
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
width: col.width,
|
||||
reactive: true,
|
||||
@ -294,24 +303,28 @@ class Indicator extends PanelMenu.Button {
|
||||
|
||||
if ( ! col [ 'special' ] )
|
||||
_child = new St.Label ( { style_class: 'monito-label',
|
||||
width: col.width,
|
||||
text: text.toString(),
|
||||
x_align: ( col.align ? col.align : Clutter.ActorAlign.START ),
|
||||
style: ( col.style ? col.style : '' ) } );
|
||||
else if ( col.special == 'actions' && this.serverLogic.canRecheck )
|
||||
{
|
||||
_child = new St.BoxLayout ( { x_expand: false,
|
||||
vertical: false } );
|
||||
_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.service = text;
|
||||
_button.connect ( 'clicked', Lang.bind ( this, this._onRecheckButtonClick ) );
|
||||
_button.child = new St.Icon ( {
|
||||
icon_name: 'view-refresh-symbolic',
|
||||
icon_name: 'system-run-symbolic',
|
||||
icon_size: 16,
|
||||
width: 16,
|
||||
height: 16,
|
||||
@ -320,7 +333,6 @@ class Indicator extends PanelMenu.Button {
|
||||
}
|
||||
|
||||
let _bin = new St.Bin({
|
||||
// style: 'background: purple',
|
||||
track_hover: true,
|
||||
width: col.width,
|
||||
x_expand: col.expand,
|
||||
@ -374,7 +386,7 @@ class Indicator extends PanelMenu.Button {
|
||||
}
|
||||
|
||||
let headerBox = new St.BoxLayout({
|
||||
hover: true,
|
||||
track_hover: true,
|
||||
x_expand: true
|
||||
});
|
||||
this._box.add_child(headerBox);
|
||||
@ -389,7 +401,7 @@ class Indicator extends PanelMenu.Button {
|
||||
this._box.add_child(scrollBox);
|
||||
|
||||
let tableBox = new St.BoxLayout({
|
||||
hover: true,
|
||||
track_hover: true,
|
||||
vertical: true,
|
||||
x_expand: true,
|
||||
});
|
||||
|
4
prefs.js
4
prefs.js
@ -281,8 +281,8 @@ function createPrefWidgets ( noteBook, type, isActive )
|
||||
else if ( prefEntry.key == 'type' )
|
||||
{
|
||||
[ { name: 'Icinga', value: 'Icinga server' },
|
||||
{ name: 'Icinga2', value: 'Icinga2 server (using Icingaweb2)' },
|
||||
{ name: 'Icinga2API', value: 'Icinga2 server (using API)' } ].forEach((item) => {
|
||||
{ name: 'Icinga2API', value: 'Icinga2 server (using API, prefered)' },
|
||||
{ name: 'Icinga2', value: 'Icinga2 server (using Icingaweb2, limited)' } ].forEach((item) => {
|
||||
this.prefWidgets[prefEntry.key].insert ( -1, item.name, item.value );
|
||||
} );
|
||||
}
|
||||
|
@ -22,8 +22,8 @@
|
||||
<schemalist >
|
||||
<enum id="org.gnome.shell.extensions.monito.MonitoringType">
|
||||
<value value="0" nick="Icinga"/>
|
||||
<value value="1" nick="Icinga2"/>
|
||||
<value value="2" nick="Icinga2API"/>
|
||||
<value value="1" nick="Icinga2API"/>
|
||||
<value value="2" nick="Icinga2"/>
|
||||
</enum>
|
||||
|
||||
<enum id="org.gnome.shell.extensions.monito.DisplayType">
|
||||
|
@ -224,4 +224,86 @@ class GenericServer {
|
||||
}
|
||||
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
|
||||
{
|
||||
let json = JSON.parse ( _data );
|
||||
|
||||
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 );
|
||||
|
@ -71,7 +71,7 @@ class Icinga2 extends GenericServer {
|
||||
attempts: entry.service_attempt,
|
||||
has_been_acknowledged: parseInt(entry.service_acknowledged),
|
||||
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.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' );
|
||||
log ( message.request_headers );
|
||||
// log ( message.request_headers );
|
||||
|
||||
this.authenticateAndSend ( message, this.handleCMDMessage );
|
||||
}
|
||||
@ -84,6 +99,7 @@ class Icinga2API extends GenericServer {
|
||||
|
||||
for ( var entry of json.results )
|
||||
{
|
||||
// log ( JSON.stringify(entry) );
|
||||
this.status.service_status.push ( {
|
||||
status: _statuses [ entry.attrs.state ],
|
||||
host_name: entry.attrs.host_name,
|
||||
@ -91,7 +107,7 @@ class Icinga2API extends GenericServer {
|
||||
has_been_acknowledged: parseInt(entry.attrs.acknowledgement),
|
||||
attempts: '%d/%d'.format(entry.attrs.check_attempt,entry.attrs.max_check_attempts),
|
||||
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…
Reference in New Issue
Block a user