mirror of
https://github.com/lxsang/antos-frontend.git
synced 2025-07-27 03:09:45 +02:00
Switch from coffee script to typescrit
- Better tooling support - Stronger type checking - Unit test with jest - JSDocc support
This commit is contained in:
@ -11,7 +11,7 @@
|
||||
|
||||
// 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 3 of
|
||||
// published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
@ -21,32 +21,32 @@
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
//along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
class Calendar extends this.OS.GUI.BaseService {
|
||||
constructor(args) {
|
||||
super("Calendar", args);
|
||||
//@iconclass = "fa fa-commenting"
|
||||
this.text = "";
|
||||
this.iconclass = "fa fa-calendar";
|
||||
}
|
||||
init() {
|
||||
//update time each second
|
||||
return this.watch(1000, () => {
|
||||
const now = new Date;
|
||||
this.text = now.toString();
|
||||
return this.domel.set("text", this.text);
|
||||
});
|
||||
}
|
||||
namespace OS {
|
||||
export namespace application {
|
||||
export class Calendar extends BaseService {
|
||||
constructor(args: AppArgumentsType[]) {
|
||||
super("Calendar", args);
|
||||
//@iconclass = "fa fa-commenting"
|
||||
this.text = "";
|
||||
this.iconclass = "fa fa-calendar";
|
||||
}
|
||||
|
||||
init(): void {
|
||||
//update time each second
|
||||
this.watch(1000, () => {
|
||||
const now = new Date();
|
||||
this.text = now.toString();
|
||||
(this.domel as GUI.tag.SimpleMenuEntryTag).text = this.text;
|
||||
});
|
||||
}
|
||||
|
||||
awake(e) {
|
||||
return this.openDialog("CalendarDialog" )
|
||||
.then(d => console.log(d));
|
||||
}
|
||||
// do nothing
|
||||
cleanup(evt) {
|
||||
return console.log("cleanup for quit");
|
||||
awake(e: GUI.TagEventType): void {
|
||||
this.openDialog("CalendarDialog").then((d) => console.log(d));
|
||||
}
|
||||
// do nothing
|
||||
cleanup(evt: BaseEvent): void {
|
||||
return console.log("cleanup for quit");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// do nothing
|
||||
|
||||
this.OS.register("Calendar", Calendar);
|
@ -1,175 +0,0 @@
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS208: Avoid top-level this
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
// Copyright 2017-2018 Xuan Sang LE <xsang.le AT gmail DOT com>
|
||||
|
||||
// AnTOS Web desktop is is licensed under the GNU General Public
|
||||
// License v3.0, see the LICENCE file for more information
|
||||
|
||||
// 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 3 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, see https://www.gnu.org/licenses/.
|
||||
|
||||
class PushNotification extends this.OS.GUI.BaseService {
|
||||
constructor(args) {
|
||||
super("PushNotification", args);
|
||||
this.iconclass = "fa fa-bars";
|
||||
this.cb = undefined;
|
||||
this.pending = [];
|
||||
this.logs = [];
|
||||
this.logmon = undefined;
|
||||
}
|
||||
init() {
|
||||
this.view = false;
|
||||
return this._gui.htmlToScheme(PushNotification.scheme, this, this.host);
|
||||
}
|
||||
|
||||
spin(b) {
|
||||
if (b && (this.iconclass === "fa fa-bars")) {
|
||||
this.iconclass = "fa fa-spinner fa-spin";
|
||||
this.update();
|
||||
return $(this._gui.workspace).css("cursor", "wait");
|
||||
} else if (!b && (this.iconclass === "fa fa-spinner fa-spin")) {
|
||||
this.iconclass = "fa fa-bars";
|
||||
this.update();
|
||||
return $(this._gui.workspace).css("cursor", "auto");
|
||||
}
|
||||
}
|
||||
|
||||
main() {
|
||||
this.mlist = this.find("notifylist");
|
||||
this.mfeed = this.find("notifeed");
|
||||
this.nzone = this.find("notifyzone");
|
||||
this.fzone = this.find("feedzone");
|
||||
(this.find("btclear")).set("onbtclick", e => this.mlist.set("data", []));
|
||||
(this.find("bterrlog")).set("onbtclick", e => this.showLogReport());
|
||||
this.subscribe("notification", o => this.pushout('INFO', o));
|
||||
this.subscribe("fail", o => this.pushout('FAIL', o));
|
||||
this.subscribe("error", o => this.pushout('ERROR', o));
|
||||
this.subscribe("info", o => this.pushout('INFO', o));
|
||||
|
||||
|
||||
this.subscribe("loading", o => {
|
||||
this.pending.push(o.id);
|
||||
return this.spin(true);
|
||||
});
|
||||
|
||||
this.subscribe("loaded", o => {
|
||||
const i = this.pending.indexOf(o.id);
|
||||
if (i >= 0) { this.pending.splice(i, 1); }
|
||||
if (this.pending.length === 0) { return this.spin(false); }
|
||||
});
|
||||
|
||||
this.nzone.set("height", "100%");
|
||||
this.fzone.set("height", "100%");
|
||||
|
||||
($(this.nzone)).css("right", 0)
|
||||
.css("top", "0")
|
||||
.css("bottom", "0")
|
||||
.hide();
|
||||
return ($(this.fzone))
|
||||
//.css("z-index", 99999)
|
||||
.css("bottom", "0")
|
||||
.css("bottom", "0")
|
||||
.hide();
|
||||
}
|
||||
|
||||
showLogReport() {
|
||||
return this._gui.launch("Syslog");
|
||||
}
|
||||
|
||||
addLog(s, o) {
|
||||
const logtime = new Date();
|
||||
const log = {
|
||||
type: s,
|
||||
name: o.name,
|
||||
text: `${o.data.m}`,
|
||||
id: o.id,
|
||||
icon: o.data.icon,
|
||||
iconclass: o.data.iconclass,
|
||||
error: o.data.e,
|
||||
time: logtime,
|
||||
closable: true,
|
||||
tag: "afx-bug-list-item"
|
||||
};
|
||||
if (this.logmon) {
|
||||
return this.logmon.addLog(log);
|
||||
} else {
|
||||
return this.logs.push(log);
|
||||
}
|
||||
}
|
||||
|
||||
pushout(s, o) {
|
||||
const d = {
|
||||
text: `[${s}] ${o.name} (${o.id}): ${o.data.m}`,
|
||||
icon: o.data.icon,
|
||||
iconclass: o.data.iconclass,
|
||||
closable: true
|
||||
};
|
||||
if (s !== "INFO") { this.addLog(s, o); }
|
||||
this.mlist.unshift(d);
|
||||
return this.notifeed(d);
|
||||
}
|
||||
|
||||
notifeed(d) {
|
||||
let timer;
|
||||
this.mfeed.unshift(d, true);
|
||||
($(this.fzone)).show();
|
||||
return timer = setTimeout(() => {
|
||||
this.mfeed.remove(d.domel);
|
||||
if (this.mfeed.get("data").length === 0) { ($(this.fzone)).hide(); }
|
||||
return clearTimeout(timer);
|
||||
}
|
||||
, 3000);
|
||||
}
|
||||
|
||||
awake(evt) {
|
||||
if (this.view) { ($(this.nzone)).hide(); } else { ($(this.nzone)).show(); }
|
||||
this.view = !this.view;
|
||||
if (!this.cb) {
|
||||
this.cb = e => {
|
||||
if (!($(e.target)).closest($(this.nzone)).length && !($(e.target)).closest(evt.data.item).length) {
|
||||
($(this.nzone)).hide();
|
||||
$(document).unbind("click", this.cb);
|
||||
return this.view = !this.view;
|
||||
}
|
||||
};
|
||||
}
|
||||
if (this.view) {
|
||||
return $(document).on("click", this.cb);
|
||||
} else {
|
||||
return $(document).unbind("click", this.cb);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup(evt) {}
|
||||
}
|
||||
// do nothing
|
||||
PushNotification.scheme = `\
|
||||
<div>
|
||||
<afx-overlay data-id = "notifyzone" width = "250px">
|
||||
<afx-hbox data-height="30">
|
||||
<afx-button text = "__(Clear all)" data-id = "btclear" ></afx-button>
|
||||
<afx-button iconclass = "fa fa-bug" data-id = "bterrlog" data-width = "25"></afx-button>
|
||||
</afx-hbox>
|
||||
<afx-list-view data-id="notifylist"></afx-list-view>
|
||||
</afx-overlay>
|
||||
<afx-overlay data-id = "feedzone" width = "250">
|
||||
<afx-list-view data-id = "notifeed">
|
||||
</afx-list-view>
|
||||
</afx-overlay>
|
||||
</div>\
|
||||
`;
|
||||
this.OS.register("PushNotification", PushNotification);
|
280
src/packages/Syslog/PushNotification.ts
Normal file
280
src/packages/Syslog/PushNotification.ts
Normal file
@ -0,0 +1,280 @@
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS208: Avoid top-level this
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
// Copyright 2017-2018 Xuan Sang LE <xsang.le AT gmail DOT com>
|
||||
|
||||
// AnTOS Web desktop is is licensed under the GNU General Public
|
||||
// License v3.0, see the LICENCE file for more information
|
||||
|
||||
// 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 3 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, see https://www.gnu.org/licenses/.
|
||||
|
||||
namespace OS {
|
||||
export namespace application {
|
||||
import TAG = GUI.tag;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @export
|
||||
* @class PushNotification
|
||||
* @extends {BaseService}
|
||||
*/
|
||||
export class PushNotification extends BaseService {
|
||||
private pending: number[];
|
||||
private cb: (e: JQuery.ClickEvent) => void;
|
||||
private view: boolean;
|
||||
private mlist: TAG.ListViewTag;
|
||||
private mfeed: TAG.ListViewTag;
|
||||
private nzone: TAG.OverlayTag;
|
||||
private fzone: TAG.OverlayTag;
|
||||
|
||||
logs: GenericObject<any>[];
|
||||
logmon: Syslog;
|
||||
|
||||
/**
|
||||
*Creates an instance of PushNotification.
|
||||
* @param {AppArgumentsType[]} args
|
||||
* @memberof PushNotification
|
||||
*/
|
||||
constructor(args: AppArgumentsType[]) {
|
||||
super("PushNotification", args);
|
||||
this.iconclass = "fa fa-bars";
|
||||
this.cb = undefined;
|
||||
this.pending = [];
|
||||
this.logs = [];
|
||||
this.logmon = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @returns {void}
|
||||
* @memberof PushNotification
|
||||
*/
|
||||
init(): void {
|
||||
this.view = false;
|
||||
return this._gui.htmlToScheme(scheme, this, this.host);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {boolean} b
|
||||
* @memberof PushNotification
|
||||
*/
|
||||
private spin(b: boolean): void {
|
||||
if (b && this.iconclass === "fa fa-bars") {
|
||||
this.iconclass = "fa fa-spinner fa-spin";
|
||||
this.update();
|
||||
$(this._gui.workspace).css("cursor", "wait");
|
||||
} else if (!b && this.iconclass === "fa fa-spinner fa-spin") {
|
||||
this.iconclass = "fa fa-bars";
|
||||
this.update();
|
||||
$(this._gui.workspace).css("cursor", "auto");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @memberof PushNotification
|
||||
*/
|
||||
main(): void {
|
||||
this.mlist = this.find("notifylist") as TAG.ListViewTag;
|
||||
this.mfeed = this.find("notifeed") as TAG.ListViewTag;
|
||||
this.nzone = this.find("notifyzone") as TAG.OverlayTag;
|
||||
this.fzone = this.find("feedzone") as TAG.OverlayTag;
|
||||
(this.find("btclear") as TAG.ButtonTag).onbtclick = (e) =>
|
||||
(this.mlist.data = []);
|
||||
(this.find("bterrlog") as TAG.ButtonTag).onbtclick = (e) =>
|
||||
this.showLogReport();
|
||||
this.subscribe("notification", (o) => this.pushout("INFO", o));
|
||||
this.subscribe("fail", (o) => this.pushout("FAIL", o));
|
||||
this.subscribe("error", (o) => this.pushout("ERROR", o));
|
||||
this.subscribe("info", (o) => this.pushout("INFO", o));
|
||||
|
||||
this.subscribe("loading", (o) => {
|
||||
this.pending.push(o.id);
|
||||
return this.spin(true);
|
||||
});
|
||||
|
||||
this.subscribe("loaded", (o) => {
|
||||
const i = this.pending.indexOf(o.id);
|
||||
if (i >= 0) {
|
||||
this.pending.splice(i, 1);
|
||||
}
|
||||
if (this.pending.length === 0) {
|
||||
return this.spin(false);
|
||||
}
|
||||
});
|
||||
|
||||
this.nzone.height = "100%";
|
||||
this.fzone.height = "100%";
|
||||
|
||||
$(this.nzone)
|
||||
.css("right", 0)
|
||||
.css("top", "0")
|
||||
.css("bottom", "0")
|
||||
.hide();
|
||||
$(this.fzone)
|
||||
//.css("z-index", 99999)
|
||||
.css("bottom", "0")
|
||||
.css("bottom", "0")
|
||||
.hide();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @returns {void}
|
||||
* @memberof PushNotification
|
||||
*/
|
||||
private showLogReport(): void {
|
||||
return this._gui.launch("Syslog", []);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {string} s
|
||||
* @param {GenericObject<any>} o
|
||||
* @memberof PushNotification
|
||||
*/
|
||||
private addLog(s: string, o: GenericObject<any>): void {
|
||||
const logtime = new Date();
|
||||
const log = {
|
||||
type: s,
|
||||
name: o.name,
|
||||
text: `${o.data.m}`,
|
||||
id: o.id,
|
||||
icon: o.data.icon,
|
||||
iconclass: o.data.iconclass,
|
||||
error: o.data.e,
|
||||
time: logtime,
|
||||
closable: true,
|
||||
tag: "afx-bug-list-item",
|
||||
};
|
||||
if (this.logmon) {
|
||||
this.logmon.addLog(log);
|
||||
} else {
|
||||
this.logs.push(log);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {string} s
|
||||
* @param {GenericObject<any>} o
|
||||
* @memberof PushNotification
|
||||
*/
|
||||
private pushout(s: string, o: GenericObject<any>): void {
|
||||
const d = {
|
||||
text: `[${s}] ${o.name} (${o.id}): ${o.data.m}`,
|
||||
icon: o.data.icon,
|
||||
iconclass: o.data.iconclass,
|
||||
closable: true,
|
||||
};
|
||||
if (s !== "INFO") {
|
||||
this.addLog(s, o);
|
||||
}
|
||||
this.mlist.unshift(d);
|
||||
this.notifeed(d);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {GenericObject<any>} d
|
||||
* @memberof PushNotification
|
||||
*/
|
||||
private notifeed(d: GenericObject<any>): void {
|
||||
let timer: number;
|
||||
this.mfeed.unshift(d);
|
||||
$(this.fzone).show();
|
||||
timer = setTimeout(() => {
|
||||
this.mfeed.delete(d.domel);
|
||||
if (this.mfeed.data.length === 0) {
|
||||
$(this.fzone).hide();
|
||||
}
|
||||
return clearTimeout(timer);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {GUI.TagEventType} evt
|
||||
* @memberof PushNotification
|
||||
*/
|
||||
awake(evt: GUI.TagEventType): void {
|
||||
if (this.view) {
|
||||
$(this.nzone).hide();
|
||||
} else {
|
||||
$(this.nzone).show();
|
||||
}
|
||||
this.view = !this.view;
|
||||
if (!this.cb) {
|
||||
this.cb = (e) => {
|
||||
if (
|
||||
!$(e.target).closest($(this.nzone)).length &&
|
||||
!$(e.target).closest(evt.data.item).length
|
||||
) {
|
||||
$(this.nzone).hide();
|
||||
$(document).unbind("click", this.cb);
|
||||
this.view = !this.view;
|
||||
}
|
||||
};
|
||||
}
|
||||
if (this.view) {
|
||||
$(document).on("click", this.cb);
|
||||
} else {
|
||||
$(document).unbind("click", this.cb);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {BaseEvent} evt
|
||||
* @memberof PushNotification
|
||||
*/
|
||||
cleanup(evt: BaseEvent): void {}
|
||||
}
|
||||
}
|
||||
// do nothing
|
||||
const scheme = `\
|
||||
<div>
|
||||
<afx-overlay data-id = "notifyzone" width = "250px">
|
||||
<afx-hbox data-height="30">
|
||||
<afx-button text = "__(Clear all)" data-id = "btclear" ></afx-button>
|
||||
<afx-button iconclass = "fa fa-bug" data-id = "bterrlog" data-width = "25"></afx-button>
|
||||
</afx-hbox>
|
||||
<afx-list-view data-id="notifylist"></afx-list-view>
|
||||
</afx-overlay>
|
||||
<afx-overlay data-id = "feedzone" width = "250">
|
||||
<afx-list-view data-id = "notifeed">
|
||||
</afx-list-view>
|
||||
</afx-overlay>
|
||||
</div>\
|
||||
`;
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS208: Avoid top-level this
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
Ant = this
|
||||
|
||||
class BugListItemTag extends this.OS.GUI.tag["afx-list-item-proto"] {
|
||||
constructor(r, o) {
|
||||
super(r, o);
|
||||
}
|
||||
|
||||
__data__(v) {
|
||||
if (!v) { return; }
|
||||
this.refs.error.set("text", v.text);
|
||||
this.refs.time.set("text", v.time);
|
||||
if (v.icon) { this.refs.error.set("icon", v.icon); }
|
||||
if (!v.icon) {
|
||||
this.refs.error.set("iconclass", v.iconclass ? v.iconclass : "fa fa-bug");
|
||||
}
|
||||
return this.set("closable", v.closable);
|
||||
}
|
||||
|
||||
__selected(v) {
|
||||
return this.get("data").selected = v;
|
||||
}
|
||||
|
||||
|
||||
itemlayout() {
|
||||
return {
|
||||
el: "div", children: [
|
||||
{ el: "afx-label", ref: "error", class: "afx-bug-list-item-error" },
|
||||
{ el: "afx-label", ref: "time", class: "afx-bug-list-item-time" }
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.OS.GUI.define("afx-bug-list-item", BugListItemTag);
|
||||
|
||||
class Syslog extends this.OS.GUI.BaseApplication {
|
||||
constructor(args) {
|
||||
super("Syslog", args);
|
||||
}
|
||||
|
||||
main() {
|
||||
this.loglist = this.find("loglist");
|
||||
this.logdetail = this.find("logdetail");
|
||||
|
||||
this._gui.pushService("Syslog/PushNotification")
|
||||
.then(srv => {
|
||||
this.srv = srv;
|
||||
if (this.srv && this.srv.logs) { this.loglist.set("data", this.srv.logs); }
|
||||
return this.srv.logmon = this;
|
||||
}).catch(e => {
|
||||
this.error(__("Unable to load push notification service"), e);
|
||||
return this.quit();
|
||||
});
|
||||
|
||||
$(this.find("txturi")).val(Ant.OS.setting.system.error_report);
|
||||
this.loglist.set("onlistselect", e => {
|
||||
let data;
|
||||
if (e && e.data) { data = e.data.item.get("data"); }
|
||||
if (!data) { return; }
|
||||
let stacktrace = "None";
|
||||
if (data.error) { stacktrace = data.error.stack; }
|
||||
return $(this.logdetail).text(Syslog.template.format(
|
||||
data.text,
|
||||
data.type,
|
||||
data.time,
|
||||
data.name,
|
||||
data.id,
|
||||
stacktrace
|
||||
)
|
||||
);
|
||||
});
|
||||
this.loglist.set("onitemclose", e => {
|
||||
let el;
|
||||
if (e && e.data) { el = e.data.item; }
|
||||
if (!el) { return true; }
|
||||
const data = el.get("data");
|
||||
console.log(data);
|
||||
if (!data.selected) { return true; }
|
||||
$(this.logdetail).text("");
|
||||
return true;
|
||||
});
|
||||
|
||||
this.find("btnreport").set("onbtclick", e => {
|
||||
const uri = $(this.find("txturi")).val();
|
||||
if (uri === "") { return; }
|
||||
const el = this.loglist.get("selectedItem");
|
||||
if (!el) { return; }
|
||||
const data = el.get("data");
|
||||
if (!data) { return; }
|
||||
return Ant.OS.API.post(uri, data)
|
||||
.then(d => {
|
||||
return this.notify(__("Error reported"));
|
||||
}).catch(e => {
|
||||
return this.notify(__("Unable to report error: {0}", e.toString()));
|
||||
});
|
||||
});
|
||||
|
||||
return this.find("btclean").set("onbtclick", e => {
|
||||
if (!this.srv) { return; }
|
||||
this.srv.logs = [];
|
||||
this.loglist.set("data", this.srv.logs);
|
||||
return $(this.logdetail).text("");
|
||||
});
|
||||
}
|
||||
|
||||
addLog(log) {
|
||||
return this.loglist.push(log);
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
if (this.srv) { return this.srv.logmon = undefined; }
|
||||
}
|
||||
}
|
||||
|
||||
Syslog.template = `\
|
||||
{0}
|
||||
Log type: {1}
|
||||
Log time: {2}
|
||||
Process: {3} ({4})
|
||||
detail:
|
||||
|
||||
{5}\
|
||||
`;
|
||||
Syslog.singleton = true;
|
||||
this.OS.register("Syslog", Syslog);
|
256
src/packages/Syslog/Syslog.ts
Normal file
256
src/packages/Syslog/Syslog.ts
Normal file
@ -0,0 +1,256 @@
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS208: Avoid top-level this
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
|
||||
namespace OS {
|
||||
export namespace GUI {
|
||||
export namespace tag {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @class BugListItemTag
|
||||
* @extends {ListViewItemTag}
|
||||
*/
|
||||
class BugListItemTag extends ListViewItemTag {
|
||||
/**
|
||||
*Creates an instance of BugListItemTag.
|
||||
* @memberof BugListItemTag
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @protected
|
||||
* @memberof BugListItemTag
|
||||
*/
|
||||
protected init(): void {}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @protected
|
||||
* @param {*} [d]
|
||||
* @memberof BugListItemTag
|
||||
*/
|
||||
protected reload(d?: any): void {}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @protected
|
||||
* @returns {void}
|
||||
* @memberof BugListItemTag
|
||||
*/
|
||||
protected ondatachange(): void {
|
||||
if (!this.data) {
|
||||
return;
|
||||
}
|
||||
const etag = this.refs.error as LabelTag;
|
||||
const ttag = this.refs.time as LabelTag;
|
||||
etag.text = this.data.text;
|
||||
ttag.text = this.data.time;
|
||||
if (this.data.icon) {
|
||||
etag.icon = this.data.icon;
|
||||
}
|
||||
if (!this.data.icon) {
|
||||
etag.iconclass = this.data.iconclass
|
||||
? this.data.iconclass
|
||||
: "fa fa-bug";
|
||||
}
|
||||
this.closable = this.data.closable;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @protected
|
||||
* @returns
|
||||
* @memberof BugListItemTag
|
||||
*/
|
||||
protected itemlayout() {
|
||||
return {
|
||||
el: "div",
|
||||
children: [
|
||||
{
|
||||
el: "afx-label",
|
||||
ref: "error",
|
||||
class: "afx-bug-list-item-error",
|
||||
},
|
||||
{
|
||||
el: "afx-label",
|
||||
ref: "time",
|
||||
class: "afx-bug-list-item-time",
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
define("afx-bug-list-item", BugListItemTag);
|
||||
}
|
||||
}
|
||||
const template = `\
|
||||
{0}
|
||||
Log type: {1}
|
||||
Log time: {2}
|
||||
Process: {3} ({4})
|
||||
detail:
|
||||
|
||||
{5}\
|
||||
`;
|
||||
export namespace application {
|
||||
import TAG = GUI.tag;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @export
|
||||
* @class Syslog
|
||||
* @extends {BaseApplication}
|
||||
*/
|
||||
export class Syslog extends BaseApplication {
|
||||
private loglist: TAG.ListViewTag;
|
||||
private logdetail: HTMLElement;
|
||||
private srv: PushNotification;
|
||||
constructor(args: AppArgumentsType[]) {
|
||||
super("Syslog", args);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @memberof Syslog
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @memberof Syslog
|
||||
*/
|
||||
main(): void {
|
||||
this.loglist = this.find("loglist") as TAG.ListViewTag;
|
||||
this.logdetail = this.find("logdetail");
|
||||
|
||||
this._gui
|
||||
.pushService("Syslog/PushNotification")
|
||||
.then((srv) => {
|
||||
|
||||
this.srv = srv as PushNotification;
|
||||
if (this.srv && this.srv.logs) {
|
||||
this.loglist.data = this.srv.logs;
|
||||
}
|
||||
this.srv.logmon = this;
|
||||
})
|
||||
.catch((e) => {
|
||||
this.error(
|
||||
__("Unable to load push notification service"),
|
||||
e
|
||||
);
|
||||
this.quit(false);
|
||||
});
|
||||
|
||||
$(this.find("txturi")).val(Ant.OS.setting.system.error_report);
|
||||
this.loglist.onlistselect = (e) => {
|
||||
let data;
|
||||
if (e && e.data) {
|
||||
data = e.data.item.data;
|
||||
}
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
let stacktrace = "None";
|
||||
if (data.error) {
|
||||
stacktrace = data.error.stack;
|
||||
}
|
||||
$(this.logdetail).text(
|
||||
template.format(
|
||||
data.text,
|
||||
data.type,
|
||||
data.time,
|
||||
data.name,
|
||||
data.id,
|
||||
stacktrace
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
this.loglist.onitemclose = (e) => {
|
||||
let el;
|
||||
if (e && e.data) {
|
||||
el = e.data.item;
|
||||
}
|
||||
if (!el) {
|
||||
return true;
|
||||
}
|
||||
const data = el.get("data");
|
||||
console.log(data);
|
||||
if (!data.selected) {
|
||||
return true;
|
||||
}
|
||||
$(this.logdetail).text("");
|
||||
return true;
|
||||
};
|
||||
const bt = this.find("btnreport") as TAG.ButtonTag;
|
||||
bt.onbtclick = async (e) => {
|
||||
const uri = $(this.find("txturi")).val();
|
||||
if (uri === "") {
|
||||
return;
|
||||
}
|
||||
const el = this.loglist.selectedItem;
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
const data = el.data;
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const d = await Ant.OS.API.post(uri as string, data);
|
||||
return this.notify(__("Error reported"));
|
||||
} catch (e) {
|
||||
return this.notify(
|
||||
__("Unable to report error: {0}", e.toString())
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
(this.find("btclean") as TAG.ButtonTag).onbtclick = (e) => {
|
||||
if (!this.srv) {
|
||||
return;
|
||||
}
|
||||
this.srv.logs = [];
|
||||
this.loglist.data = this.srv.logs;
|
||||
return $(this.logdetail).text("");
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {GenericObject<any>} log
|
||||
* @memberof Syslog
|
||||
*/
|
||||
addLog(log: GenericObject<any>): void {
|
||||
this.loglist.push(log);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @returns {void}
|
||||
* @memberof Syslog
|
||||
*/
|
||||
cleanup(): void {
|
||||
if (this.srv) {
|
||||
return (this.srv.logmon = undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Syslog.singleton = true;
|
||||
}
|
||||
}
|
@ -1,17 +1,20 @@
|
||||
{
|
||||
"app":"Syslog",
|
||||
"app": "Syslog",
|
||||
"pkgname": "Syslog",
|
||||
"services": [ "Calendar", "PushNotification" ],
|
||||
"services": [
|
||||
"Calendar",
|
||||
"PushNotification"
|
||||
],
|
||||
"name": "System log",
|
||||
"description":"Core services and system log",
|
||||
"info":{
|
||||
"description": "Core services and system log",
|
||||
"info": {
|
||||
"author": "Xuan Sang LE",
|
||||
"email": "xsang.le@gmail.com",
|
||||
"credit": "dedicated to some one here",
|
||||
"licences": "GPLv3"
|
||||
},
|
||||
"version":"0.0.1-a",
|
||||
"category":"System",
|
||||
"version": "0.0.1-a",
|
||||
"category": "System",
|
||||
"iconclass": "fa fa-bug",
|
||||
"mimes":[]
|
||||
}
|
||||
"mimes": []
|
||||
}
|
||||
|
Reference in New Issue
Block a user