From 11aed2642bdca1f10bc6c51f867c49886a0f042c Mon Sep 17 00:00:00 2001 From: DanyLE Date: Fri, 6 Jan 2023 18:44:11 +0100 Subject: [PATCH] Rework on Notification API + some sytem packages - Rename Syslog to SystemReport - All services previously on SystemReport now moved to the dedicated SystemServices Packages - Rework on a more versatile notification GUI and API - Applications now can display a local toast message instead of pushing a global notification message --- Makefile | 5 +- d.ts/antos.d.ts | 225 +++++++++++++++++- src/core/BaseApplication.ts | 41 +++- src/core/gui.ts | 126 ++++++++++ src/core/tags/NotificationTag.ts | 189 +++++++++++++++ src/core/tags/StackMenuTag.ts | 4 +- src/core/tags/StackPanelTag.ts | 2 +- src/core/tags/WindowTag.ts | 13 + src/core/tags/tag.ts | 7 + src/packages/Files/main.ts | 9 +- src/packages/MarketPlace/main.ts | 16 +- src/packages/Syslog/README.md | 6 - src/packages/Syslog/package.json | 20 -- .../{Syslog => SystemReport}/Makefile | 4 +- src/packages/SystemReport/README.md | 7 + .../SystemReport.ts} | 18 +- src/packages/SystemReport/main.css | 35 +++ src/packages/SystemReport/package.json | 15 ++ .../{Syslog => SystemReport}/scheme.html | 2 +- .../{Syslog => SystemServices}/Calendar.ts | 0 src/packages/SystemServices/Makefile | 11 + .../PushNotification.ts | 29 +-- src/packages/SystemServices/README.md | 0 .../{Syslog => SystemServices}/main.css | 134 ++++------- src/packages/SystemServices/package.json | 15 ++ src/themes/antos_dark/afx-notification.css | 19 ++ src/themes/antos_light/afx-notification.css | 19 ++ src/themes/system/afx-notification.css | 117 +++++++++ 28 files changed, 917 insertions(+), 171 deletions(-) create mode 100644 src/core/tags/NotificationTag.ts delete mode 100644 src/packages/Syslog/README.md delete mode 100644 src/packages/Syslog/package.json rename src/packages/{Syslog => SystemReport}/Makefile (57%) create mode 100644 src/packages/SystemReport/README.md rename src/packages/{Syslog/Syslog.ts => SystemReport/SystemReport.ts} (95%) create mode 100644 src/packages/SystemReport/main.css create mode 100644 src/packages/SystemReport/package.json rename src/packages/{Syslog => SystemReport}/scheme.html (90%) rename src/packages/{Syslog => SystemServices}/Calendar.ts (100%) create mode 100644 src/packages/SystemServices/Makefile rename src/packages/{Syslog => SystemServices}/PushNotification.ts (86%) create mode 100644 src/packages/SystemServices/README.md rename src/packages/{Syslog => SystemServices}/main.css (57%) create mode 100644 src/packages/SystemServices/package.json create mode 100644 src/themes/antos_dark/afx-notification.css create mode 100644 src/themes/antos_light/afx-notification.css create mode 100644 src/themes/system/afx-notification.css diff --git a/Makefile b/Makefile index f7408a2..fb5ed58 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,8 @@ tags = dist/core/tags/tag.js \ dist/core/tags/DesktopTag.js \ dist/core/tags/StackMenuTag.js \ dist/core/tags/StackPanelTag.js \ - dist/core/tags/InputTag.js + dist/core/tags/InputTag.js \ + dist/core/tags/NotificationTag.js javascripts= dist/core/core.js \ dist/core/settings.js \ @@ -63,7 +64,7 @@ javascripts= dist/core/core.js \ antfx = $(tags) \ dist/core/Announcerment.js -packages = Syslog Files MarketPlace Setting NotePad +packages = SystemServices SystemReport Files MarketPlace Setting NotePad main: initd build_javascripts build_themes libs build_packages languages - cp src/index.html $(BUILDDIR)/ diff --git a/d.ts/antos.d.ts b/d.ts/antos.d.ts index 526fc63..e2a7c82 100644 --- a/d.ts/antos.d.ts +++ b/d.ts/antos.d.ts @@ -953,6 +953,46 @@ declare namespace OS { * - System dialogs definition */ namespace GUI { + /** + * Enum definition of different UI locattion + * + * @export + * @enum {string } + */ + enum ANCHOR { + /** + * Center top + */ + NORTH = "NORTH", + /** + * Center bottom + */ + SOUTH = "SOUTH", + /** + * Center left + */ + WEST = "WEST", + /** + * Center right + */ + EST = "EST", + /** + * Top left + */ + NORTH_WEST = "NORTH_WEST", + /** + * Bottom left + */ + SOUTH_WEST = "SOUTH_WEST", + /** + * Top right + */ + NORTH_EST = "NORTH_EST", + /** + * Bottom right + */ + SOUTH_EST = "SOUTH_EST" + } /** * AntOS keyboard shortcut type definition * @@ -1084,6 +1124,46 @@ declare namespace OS { * to each dialog definition for the format of the callback data */ function openDialog(d: string | BaseDialog, data: GenericObject): Promise; + /** + * Toast notification configuration options + * + * + * @export + * @interface ToastOptions + */ + interface ToastOptions { + /** + * Where the Toast is displayed? + * + * @type {ANCHOR} + * @memberof ToastOptions + */ + location?: ANCHOR; + /** + * Timeout (in seconds) before the Toast disappear + * Set this value to 0 to prevent the Toast to disappear, + * in this case, use need to explicitly close the notification + * + * @type {number} + * @memberof ToastOptions + */ + timeout?: number; + /** + * AFXTag that is used to render the data + * + * @type {number} + * @memberof ToastOptions + */ + tag?: string; + } + /** + * Toast notification API + * + * @export + * @param + * @returns + */ + function toast(data: any, opts?: ToastOptions, app?: application.BaseApplication): void; /** * Find a list of applications that support a specific mime * type in the system packages meta-data @@ -2443,6 +2523,12 @@ declare namespace OS { * @memberof BaseApplication */ title(): string | FormattedString; + /** + * Getter to access the application window instance + * + * @memberof BaseApplication + */ + get window(): GUI.tag.WindowTag; /** * Function called when the application exit. * If the input exit event is prevented, the application @@ -2489,6 +2575,15 @@ declare namespace OS { * @memberof BaseApplication */ protected menu(): GUI.BasicItemType[]; + /** + * Show local toast notification + * + * @param {any} data to send + * @param {GUI.ToastOptions} notification options see [[GUI.ToastOptions]] + * @returns {void} + * @memberof BaseApplication + */ + toast(data: any, opts?: GUI.ToastOptions): void; /** * The cleanup function that is called by [[onexit]] function. * Application need to override this function to perform some @@ -3926,6 +4021,12 @@ declare namespace OS { * stored in the `customElements` registry of the browser */ namespace tag { + /** + * Alias to all classes that extends [[AFXTag]] + */ + type AFXTagTypeClass = { + new (): T; + }; /** * Define an AFX tag as a custom element and add it to the * global `customElements` registry. If the tag is redefined, i.e. @@ -7974,7 +8075,7 @@ declare namespace OS { */ reset(): void; /** - * Mount the tab bar and bind some basic events + * Mount the menu and bind some basic events * * @protected * @memberof StackMenuTag @@ -8059,7 +8160,7 @@ declare namespace OS { */ show(e?: JQuery.MouseEventBase): void; /** - * TabBar layout definition + * Tag layout definition * * @protected * @returns {TagLayoutType[]} @@ -8362,7 +8463,7 @@ declare namespace OS { */ navigateBack(): void; /** - * Navigate to a custom tab + * Navigate to a custom panel * * @memberof StackPanelTag */ @@ -8454,6 +8555,118 @@ declare namespace OS { } } } +declare namespace OS { + namespace GUI { + namespace tag { + /** + * Toast notification tag + * + * @export + * @class ToastNotificationTag + * @extends {AFXTag} + */ + class ToastNotificationTag extends AFXTag { + /** + *Creates an instance of ToastNotificationTag. + * @memberof ToastNotificationTag + */ + constructor(); + /** + * Mount the tag + * + * @protected + * @memberof ToastNotificationTag + */ + protected mount(): void; + /** + * Init the tag before mounting + * + * @protected + * @memberof ToastNotificationTag + */ + protected init(): void; + /** + * Re-calibrate tag + * + * @protected + * @memberof ToastNotificationTag + */ + protected calibrate(): void; + /** + * Update the current tag, do nothing in this tag + * + * @param {*} [d] + * @memberof ToastNotificationTag + */ + reload(d?: any): void; + /** + * Tag layout definition + * + * @protected + * @returns {TagLayoutType[]} + * @memberof ToastNotificationTag + */ + protected layout(): TagLayoutType[]; + } + /** + * This tag manage all notification UI on the desktop + * + * @export + * @class NotificationTag + * @extends {AFXTag} + */ + class NotificationTag extends AFXTag { + /** + *Creates an instance of NotificationTag. + * @memberof NotificationTag + */ + constructor(); + /** + * Mount the tag + * + * @protected + * @memberof NotificationTag + */ + protected mount(): void; + /** + * Init the tag before mounting + * + * @protected + * @memberof NotificationTag + */ + protected init(): void; + /** + * Push anotification to a specific location + * + * @memberof NotificationTag + */ + push(tag: AFXTag, loc?: ANCHOR): void; + /** + * Re-calibrate tag + * + * @protected + * @memberof NotificationTag + */ + protected calibrate(): void; + /** + * Update the current tag, do nothing in this tag + * + * @param {*} [d] + * @memberof NotificationTag + */ + reload(d?: any): void; + /** + * Tag layout definition + * + * @protected + * @returns {TagLayoutType[]} + * @memberof NotificationTag + */ + protected layout(): TagLayoutType[]; + } + } + } +} declare namespace OS { namespace GUI { namespace tag { @@ -9066,6 +9279,12 @@ declare namespace OS { */ set apptitle(v: string | FormattedString); get apptitle(): string | FormattedString; + /** + * Get the notification tag + * + * @memberof WindowTag + */ + get notification(): NotificationTag; /** * Resize all the children of the window based on its width and height * diff --git a/src/core/BaseApplication.ts b/src/core/BaseApplication.ts index bbfc1f7..d656c30 100644 --- a/src/core/BaseApplication.ts +++ b/src/core/BaseApplication.ts @@ -380,7 +380,17 @@ namespace OS { title(): string | FormattedString { return (this.scheme as GUI.tag.WindowTag).apptitle; } - + + /** + * Getter to access the application window instance + * + * @memberof BaseApplication + */ + get window(): GUI.tag.WindowTag + { + return this.scheme as GUI.tag.WindowTag; + } + /** * Function called when the application exit. * If the input exit event is prevented, the application @@ -455,6 +465,35 @@ namespace OS { return []; } + /** + * Show local toast notification + * + * @param {any} data to send + * @param {GUI.ToastOptions} notification options see [[GUI.ToastOptions]] + * @returns {void} + * @memberof BaseApplication + */ + toast(data: any, opts?: GUI.ToastOptions): void { + let options: GUI.ToastOptions = { + location: GUI.ANCHOR.SOUTH_EST, + timeout: 3, + tag: "afx-label" + }; + if(opts) + { + for(const k in opts) + { + options[k] = opts[k]; + } + } + let d = data; + if(typeof data == "string" || data instanceof FormattedString) + { + d = {text: data}; + } + this._gui.toast(d,options, this); + } + /** * The cleanup function that is called by [[onexit]] function. * Application need to override this function to perform some diff --git a/src/core/gui.ts b/src/core/gui.ts index 4a37f0c..2c76d4e 100644 --- a/src/core/gui.ts +++ b/src/core/gui.ts @@ -26,6 +26,48 @@ namespace OS { * - System dialogs definition */ export namespace GUI { + /** + * Enum definition of different UI locattion + * + * @export + * @enum {string } + */ + export enum ANCHOR { + /** + * Center top + */ + NORTH = "NORTH", + /** + * Center bottom + */ + SOUTH = "SOUTH", + /** + * Center left + */ + WEST = "WEST", + /** + * Center right + */ + EST = "EST", + + /** + * Top left + */ + NORTH_WEST = "NORTH_WEST", + /** + * Bottom left + */ + SOUTH_WEST = "SOUTH_WEST", + + /** + * Top right + */ + NORTH_EST = "NORTH_EST", + /** + * Bottom right + */ + SOUTH_EST = "SOUTH_EST", + } /** * AntOS keyboard shortcut type definition * @@ -242,6 +284,87 @@ namespace OS { return dialog.init(); }); } + + /** + * Toast notification configuration options + * + * + * @export + * @interface ToastOptions + */ + export interface ToastOptions { + /** + * Where the Toast is displayed? see [[ANCHOR]] + * + * @type {ANCHOR} + * @memberof ToastOptions + */ + location?: ANCHOR; + + /** + * Timeout (in seconds) before the Toast disappear + * Set this value to 0 to prevent the Toast to disappear, + * in this case, use need to explicitly close the notification + * + * @type {number} + * @memberof ToastOptions + */ + timeout?: number; + + /** + * AFXTag that is used to render the data + * + * @type {number} + * @memberof ToastOptions + */ + tag?: string; + } + + /** + * Toast notification API + * Show a toad message on different posisition on screen, see [[ToastOptions]] + * + * @export + * @param + * @returns + */ + export function toast(data: any, opts?: ToastOptions, app: application.BaseApplication = undefined): void + { + let notification_el = undefined; + if(app) + { + notification_el = app.window.notification; + } + else + { + notification_el = $("#sys_notification")[0] as tag.NotificationTag; + } + let options: ToastOptions = { + location: ANCHOR.NORTH, + timeout: 3, + tag: "afx-label" + }; + if(opts) + { + for(const k in opts) + { + options[k] = opts[k]; + } + } + const toast_el = $(``)[0] as tag.ToastNotificationTag; + const content_el = $(`<${options.tag}>`)[0] as AFXTag; + $(toast_el).append(content_el); + toast_el.uify(undefined); + notification_el.push(toast_el, options.location); + content_el.set(data); + if(options.timeout && options.timeout != 0) + { + setTimeout(function(){ + $(toast_el).remove(); + clearTimeout(this); + }, options.timeout*1000); + } + } /** * Find a list of applications that support a specific mime @@ -951,6 +1074,8 @@ namespace OS { ); }); // mount it + const nottification = $("#sys_notification")[0] as tag.NotificationTag; + nottification.uify(undefined); desktop().uify(undefined); } @@ -1104,6 +1229,7 @@ namespace OS {
+
diff --git a/src/core/tags/NotificationTag.ts b/src/core/tags/NotificationTag.ts new file mode 100644 index 0000000..108f6d7 --- /dev/null +++ b/src/core/tags/NotificationTag.ts @@ -0,0 +1,189 @@ +namespace OS { + export namespace GUI { + export namespace tag { + + /** + * Toast notification tag + * + * @export + * @class ToastNotificationTag + * @extends {AFXTag} + */ + export class ToastNotificationTag extends AFXTag { + /** + *Creates an instance of ToastNotificationTag. + * @memberof ToastNotificationTag + */ + constructor() { + super(); + } + + + /** + * Mount the tag + * + * @protected + * @memberof ToastNotificationTag + */ + protected mount() { + $(this.refs.header).on('click',(e) => { + $(this).remove(); + }) + } + + /** + * Init the tag before mounting + * + * @protected + * @memberof ToastNotificationTag + */ + protected init(): void { + }; + + /** + * Re-calibrate tag + * + * @protected + * @memberof ToastNotificationTag + */ + protected calibrate(): void {} + + /** + * Update the current tag, do nothing in this tag + * + * @param {*} [d] + * @memberof ToastNotificationTag + */ + reload(d?: any): void {} + + /** + * Tag layout definition + * + * @protected + * @returns {TagLayoutType[]} + * @memberof ToastNotificationTag + */ + protected layout(): TagLayoutType[] { + return [ + { + el: "div", id: "toast_container", ref: "container", + children:[ + { + el: "div", + ref: "header", + id: "toast_header", + }, + { + el: "div", + ref: "yield", + id:"toast_content", + } + ] + } + ]; + } + } + + + /** + * This tag manage all notification UI on the desktop + * + * @export + * @class NotificationTag + * @extends {AFXTag} + */ + export class NotificationTag extends AFXTag { + /** + *Creates an instance of NotificationTag. + * @memberof NotificationTag + */ + constructor() { + super(); + } + + + /** + * Mount the tag + * + * @protected + * @memberof NotificationTag + */ + protected mount() { + } + + /** + * Init the tag before mounting + * + * @protected + * @memberof NotificationTag + */ + protected init(): void { + }; + + /** + * Push anotification to a specific location + * + * @memberof NotificationTag + */ + push(tag: AFXTag, loc: ANCHOR = ANCHOR.NORTH): void + { + if(!this.refs[loc]) + { + return; + } + switch(loc) + { + case ANCHOR.NORTH: + case ANCHOR.NORTH_EST: + case ANCHOR.NORTH_WEST: + $(this.refs[loc]).prepend(tag); + break; + case ANCHOR.SOUTH: + case ANCHOR.SOUTH_EST: + case ANCHOR.SOUTH_WEST: + $(this.refs[loc]).append(tag); + break; + default: break; + } + this.calibrate(); + } + /** + * Re-calibrate tag + * + * @protected + * @memberof NotificationTag + */ + protected calibrate(): void {} + + /** + * Update the current tag, do nothing in this tag + * + * @param {*} [d] + * @memberof NotificationTag + */ + reload(d?: any): void {} + + /** + * Tag layout definition + * + * @protected + * @returns {TagLayoutType[]} + * @memberof NotificationTag + */ + protected layout(): TagLayoutType[] { + return [ + { el: "div", id: "north", ref: "NORTH" }, + { el: "div", id: "south", ref: "SOUTH" }, + { el: "div", id: "north_west", ref: "NORTH_WEST" }, + { el: "div", id: "south_west", ref: "SOUTH_WEST" }, + { el: "div", id: "north_est", ref: "NORTH_EST" }, + { el: "div", id: "south_est", ref: "SOUTH_EST" } + ]; + } + } + + define("afx-notification", NotificationTag); + define("afx-toast-notification", ToastNotificationTag); + } + } +} diff --git a/src/core/tags/StackMenuTag.ts b/src/core/tags/StackMenuTag.ts index b96dc1c..3e625a9 100644 --- a/src/core/tags/StackMenuTag.ts +++ b/src/core/tags/StackMenuTag.ts @@ -325,7 +325,7 @@ namespace OS { } /** - * Mount the tab bar and bind some basic events + * Mount the menu and bind some basic events * * @protected * @memberof StackMenuTag @@ -546,7 +546,7 @@ namespace OS { } /** - * TabBar layout definition + * Tag layout definition * * @protected * @returns {TagLayoutType[]} diff --git a/src/core/tags/StackPanelTag.ts b/src/core/tags/StackPanelTag.ts index e5854ee..e714651 100644 --- a/src/core/tags/StackPanelTag.ts +++ b/src/core/tags/StackPanelTag.ts @@ -61,7 +61,7 @@ namespace OS { this.navigate() } /** - * Navigate to a custom tab + * Navigate to a custom panel * * @memberof StackPanelTag */ diff --git a/src/core/tags/WindowTag.ts b/src/core/tags/WindowTag.ts index abdda00..4d789f0 100644 --- a/src/core/tags/WindowTag.ts +++ b/src/core/tags/WindowTag.ts @@ -272,6 +272,15 @@ namespace OS { return $(this).attr("apptitle"); } + /** + * Get the notification tag + * + * @memberof WindowTag + */ + get notification(): NotificationTag + { + return this.refs.notification as NotificationTag; + } /** * Resize all the children of the window based on its width and height * @@ -703,6 +712,10 @@ namespace OS { { el: "afx-stack-menu", ref: "stackmenu" + }, + { + el: "afx-notification", + ref: "notification" } ], }, diff --git a/src/core/tags/tag.ts b/src/core/tags/tag.ts index 711ae20..2eb28c9 100644 --- a/src/core/tags/tag.ts +++ b/src/core/tags/tag.ts @@ -595,6 +595,7 @@ namespace OS { return element.hasAttribute(v); } } + HTMLElement.prototype.update = function (d): void { $(this) @@ -632,6 +633,12 @@ namespace OS { * stored in the `customElements` registry of the browser */ export namespace tag { + /** + * Alias to all classes that extends [[AFXTag]] + */ + export type AFXTagTypeClass = { + new (): T; + }; /** * Define an AFX tag as a custom element and add it to the * global `customElements` registry. If the tag is redefined, i.e. diff --git a/src/packages/Files/main.ts b/src/packages/Files/main.ts index 3d12997..c549b3d 100644 --- a/src/packages/Files/main.ts +++ b/src/packages/Files/main.ts @@ -154,7 +154,7 @@ namespace OS { } const path = `${d.file.path}/${d.name}`; await API.VFS.mkar(file.path, path); - this.notify(__("Archive file created: {0}",path )); + this.toast(__("Archive file created: {0}",path )); } catch (error) { this.error(__("Unable to compress file, folder"), error); } @@ -638,7 +638,7 @@ namespace OS { cut: true, files: this.view.selectedFiles.map(x => x.path.asFileHandle()), }; - return this.notify(__("{0} files cut", this.clipboard.files.length)); + return this.toast(__("{0} files cut", this.clipboard.files.length)); case `${this.name}-copy`: if (!file) { @@ -648,7 +648,7 @@ namespace OS { cut: false, files: this.view.selectedFiles.map(x => x.path.asFileHandle()), }; - return this.notify( + return this.toast( __("{0} files copied", this.clipboard.files.length) ); @@ -747,8 +747,7 @@ namespace OS { .publish() .then((r) => { return this.notify( - __("Shared url: {0}", r.result) - ); + __("Shared url: {0}", r.result)); }) .catch((e) => { return this.error( diff --git a/src/packages/MarketPlace/main.ts b/src/packages/MarketPlace/main.ts index baf46aa..83a17b8 100644 --- a/src/packages/MarketPlace/main.ts +++ b/src/packages/MarketPlace/main.ts @@ -126,10 +126,10 @@ namespace OS { try { if (this.btinstall.data.dirty) { await this.updatePackage(); - return this.notify(__("Package updated")); + return this.toast(__("Package updated")); } const n = await this.remoteInstall(); - return this.notify(__("Package installed: {0}", n)); + return this.toast(__("Package installed: {0}", n)); } catch (error) { return this.error(error.toString(), error); } @@ -138,7 +138,7 @@ namespace OS { this.btremove.onbtclick = async () => { try { await this.uninstall(); - return this.notify(__("Packaged uninstalled")); + return this.toast(__("Packaged uninstalled")); } catch (e) { return this.error(e.toString(), e); } @@ -401,8 +401,8 @@ namespace OS { ); }) .catch((_e) => { - this.notify( - __("Unable to read package description") + this.error( + __("Unable to read package description"), _e ); return $(this.appdesc).empty(); }); @@ -487,7 +487,7 @@ namespace OS { case "install": this.localInstall() .then((n) => { - return this.notify( + return this.toast( __("Package installed: {0}", n) ); }) @@ -734,7 +734,7 @@ namespace OS { if (r.error) { throw __("Cannot uninstall package: {0}", r.error).__(); } - this.notify(__("Package uninstalled")); + this.toast(__("Package uninstalled")); // stop all the services if any if (app.services) { for (let srv of Array.from(app.services)) { @@ -787,7 +787,7 @@ namespace OS { } this.bulkUninstall([...dep.uninstall]) .then((_b) => { - this.notify(__("Uninstall successfully")); + this.toast(__("Uninstall successfully")); }) .catch((err) => { this.error(__("Unable to uninstall package(s): {0}", err.toString()), err); diff --git a/src/packages/Syslog/README.md b/src/packages/Syslog/README.md deleted file mode 100644 index 9428146..0000000 --- a/src/packages/Syslog/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Syslog: System notification management and service - -Provide system wise notification service (Push Notification) - -## Change logs --v0.1.2-b: add README diff --git a/src/packages/Syslog/package.json b/src/packages/Syslog/package.json deleted file mode 100644 index bced0ac..0000000 --- a/src/packages/Syslog/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "app": "Syslog", - "pkgname": "Syslog", - "services": [ - "Calendar", - "PushNotification" - ], - "name": "System log", - "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.1.2-b", - "category": "System", - "iconclass": "fa fa-bug", - "mimes": [] -} diff --git a/src/packages/Syslog/Makefile b/src/packages/SystemReport/Makefile similarity index 57% rename from src/packages/Syslog/Makefile rename to src/packages/SystemReport/Makefile index b31541a..84bf0c0 100644 --- a/src/packages/Syslog/Makefile +++ b/src/packages/SystemReport/Makefile @@ -1,4 +1,4 @@ -module_files = Calendar.js PushNotification.js Syslog.js +module_files = SystemReport.js libfiles = @@ -7,5 +7,5 @@ cssfiles = main.css copyfiles = package.json scheme.html README.md -PKG_NAME=Syslog +PKG_NAME=SystemReport include ../pkg.mk \ No newline at end of file diff --git a/src/packages/SystemReport/README.md b/src/packages/SystemReport/README.md new file mode 100644 index 0000000..7576791 --- /dev/null +++ b/src/packages/SystemReport/README.md @@ -0,0 +1,7 @@ +# SystemReport: System notification management and service + +Provide system wise notification service (Push Notification) + +## Change logs +-v0.1.3-b: Rename from Syslog to SystemReport, move all services to SystemServices package +-v0.1.2-b: add README diff --git a/src/packages/Syslog/Syslog.ts b/src/packages/SystemReport/SystemReport.ts similarity index 95% rename from src/packages/Syslog/Syslog.ts rename to src/packages/SystemReport/SystemReport.ts index 2468905..6eed85d 100644 --- a/src/packages/Syslog/Syslog.ts +++ b/src/packages/SystemReport/SystemReport.ts @@ -110,33 +110,33 @@ detail: * * * @export - * @class Syslog + * @class SystemReport * @extends {BaseApplication} */ - export class Syslog extends BaseApplication { + export class SystemReport extends BaseApplication { private loglist: TAG.ListViewTag; private logdetail: HTMLElement; private srv: PushNotification; constructor(args: AppArgumentsType[]) { - super("Syslog", args); + super("SystemReport", args); } /** * * - * @memberof Syslog + * @memberof SystemReport */ /** * * - * @memberof Syslog + * @memberof SystemReport */ main(): void { this.loglist = this.find("loglist") as TAG.ListViewTag; this.logdetail = this.find("logdetail"); this._gui - .pushService("Syslog/PushNotification") + .pushService("SystemServices/PushNotification") .then((srv) => { this.srv = srv as PushNotification; @@ -231,7 +231,7 @@ detail: * * * @param {GenericObject} log - * @memberof Syslog + * @memberof SystemReport */ addLog(log: GenericObject): void { this.loglist.push(log); @@ -241,7 +241,7 @@ detail: * * * @returns {void} - * @memberof Syslog + * @memberof SystemReport */ cleanup(): void { if (this.srv) { @@ -250,6 +250,6 @@ detail: } } - Syslog.singleton = true; + SystemReport.singleton = true; } } diff --git a/src/packages/SystemReport/main.css b/src/packages/SystemReport/main.css new file mode 100644 index 0000000..8597246 --- /dev/null +++ b/src/packages/SystemReport/main.css @@ -0,0 +1,35 @@ +afx-app-window[data-id ='Syslog'] div[data-id ='container']{ + overflow: auto; +} + +afx-app-window[data-id ='Syslog'] .afx-bug-list-item-error { + display: block; + +} + +afx-app-window[data-id ='Syslog'] .afx-bug-list-item-error i::before { + color: chocolate; +} +afx-app-window[data-id ='Syslog'] .afx-bug-list-item-time{ + display: block; + padding-left: 10px; +} +afx-app-window[data-id ='Syslog'] .afx-bug-list-item-time i.label-text{ + font-size: 10px; + font-style: italic; +} + +afx-app-window[data-id ='Syslog'] afx-bug-list-item li.selected { + background-color: #116cd6; + color: white; +} + +afx-app-window[data-id ='Syslog'] pre { + padding: 10px; + margin:0; + user-select: text; + cursor: text; +} +afx-app-window[data-id ='Syslog'] input{ + height: 100%; +} \ No newline at end of file diff --git a/src/packages/SystemReport/package.json b/src/packages/SystemReport/package.json new file mode 100644 index 0000000..9ee901c --- /dev/null +++ b/src/packages/SystemReport/package.json @@ -0,0 +1,15 @@ +{ + "app": "SystemReport", + "pkgname": "SystemReport", + "name": "System report", + "description": "System reports", + "info": { + "author": "Xuan Sang LE", + "email": "xsang.le@gmail.com", + "licences": "GPLv3" + }, + "version": "0.1.3-b", + "category": "System", + "iconclass": "fa fa-bug", + "mimes": [] +} diff --git a/src/packages/Syslog/scheme.html b/src/packages/SystemReport/scheme.html similarity index 90% rename from src/packages/Syslog/scheme.html rename to src/packages/SystemReport/scheme.html index 8c92bb5..1d217f7 100644 --- a/src/packages/Syslog/scheme.html +++ b/src/packages/SystemReport/scheme.html @@ -1,4 +1,4 @@ - + diff --git a/src/packages/Syslog/Calendar.ts b/src/packages/SystemServices/Calendar.ts similarity index 100% rename from src/packages/Syslog/Calendar.ts rename to src/packages/SystemServices/Calendar.ts diff --git a/src/packages/SystemServices/Makefile b/src/packages/SystemServices/Makefile new file mode 100644 index 0000000..e5e035b --- /dev/null +++ b/src/packages/SystemServices/Makefile @@ -0,0 +1,11 @@ +module_files = Calendar.js PushNotification.js + +libfiles = + +cssfiles = main.css + +copyfiles = package.json README.md + + +PKG_NAME=SystemServices +include ../pkg.mk \ No newline at end of file diff --git a/src/packages/Syslog/PushNotification.ts b/src/packages/SystemServices/PushNotification.ts similarity index 86% rename from src/packages/Syslog/PushNotification.ts rename to src/packages/SystemServices/PushNotification.ts index f803f49..a72e15d 100644 --- a/src/packages/Syslog/PushNotification.ts +++ b/src/packages/SystemServices/PushNotification.ts @@ -31,12 +31,10 @@ namespace OS { 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[]; - logmon: Syslog; + logmon: SystemReport; /** *Creates an instance of PushNotification. @@ -70,9 +68,7 @@ namespace OS { */ 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) => @@ -83,18 +79,12 @@ namespace OS { this.subscribe("info", (o) => this.pushout("INFO", o)); 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(); } /** @@ -105,7 +95,7 @@ namespace OS { * @memberof PushNotification */ private showLogReport(): void { - this._gui.launch("Syslog", []); + this._gui.launch("SystemReport", []); } /** @@ -167,16 +157,7 @@ namespace OS { * @memberof PushNotification */ private notifeed(d: GenericObject): void { - let timer: number; - this.mfeed.unshift(d); - $(this.fzone).show(); - timer = window.setTimeout(() => { - this.mfeed.delete(d.domel); - if (this.mfeed.data.length === 0) { - $(this.fzone).hide(); - } - return clearTimeout(timer); - }, 3000); + GUI.toast(d,{timeout: 3, location: GUI.ANCHOR.NORTH}); } /** @@ -230,10 +211,6 @@ namespace OS { - - - - \ `; } diff --git a/src/packages/SystemServices/README.md b/src/packages/SystemServices/README.md new file mode 100644 index 0000000..e69de29 diff --git a/src/packages/Syslog/main.css b/src/packages/SystemServices/main.css similarity index 57% rename from src/packages/Syslog/main.css rename to src/packages/SystemServices/main.css index 65ab4ca..acf833a 100644 --- a/src/packages/Syslog/main.css +++ b/src/packages/SystemServices/main.css @@ -1,86 +1,50 @@ -afx-overlay[data-id = "notifyzone"]{ - /*opacity: 0.85;*/ - - overflow-y: auto; - overflow-x: hidden; - padding:3px; - margin: 0; -} -afx-overlay[data-id = "notifyzone"] afx-button button{ - width: 100%; - border-radius: 0; -} -afx-list-view[data-id = "notifylist"] -{ - padding:0; -} -afx-list-view[data-id = "notifylist"] > div.list-container > ul li{ - border:1px solid #464646; - border-radius: 3px; - margin-bottom: 5px; - -ms-word-break: break-all; - word-break: break-all; - word-break: break-word; - padding-top: 5px; - padding-bottom: 5px; -} - -afx-overlay[data-id = "feedzone"]{ - overflow: hidden; - background-color:transparent; - right:5px; - margin: 0; - padding:0; - top:0; -} -afx-list-view[data-id = "notifeed"] -{ - padding:0; - margin:0; -} -afx-list-view[data-id = "notifeed"] li{ - box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65); - border:1px solid #262626; - border-radius: 6px; - margin-bottom: 2px; - z-index: 99999; - -ms-word-break: break-all; - word-break: break-all; - word-break: break-word; -} - -afx-app-window[data-id ='Syslog'] div[data-id ='container']{ - overflow: auto; -} - -afx-app-window[data-id ='Syslog'] .afx-bug-list-item-error { - display: block; - -} - -afx-app-window[data-id ='Syslog'] .afx-bug-list-item-error i::before { - color: chocolate; -} -afx-app-window[data-id ='Syslog'] .afx-bug-list-item-time{ - display: block; - padding-left: 10px; -} -afx-app-window[data-id ='Syslog'] .afx-bug-list-item-time i.label-text{ - font-size: 10px; - font-style: italic; -} - -afx-app-window[data-id ='Syslog'] afx-bug-list-item li.selected { - background-color: #116cd6; - color: white; -} - -afx-app-window[data-id ='Syslog'] pre { - padding: 10px; - margin:0; - user-select: text; - cursor: text; -} -afx-app-window[data-id ='Syslog'] input{ - height: 100%; +afx-overlay[data-id = "notifyzone"]{ + /*opacity: 0.85;*/ + + overflow-y: auto; + overflow-x: hidden; + padding:3px; + margin: 0; +} +afx-overlay[data-id = "notifyzone"] afx-button button{ + width: 100%; + border-radius: 0; +} +afx-list-view[data-id = "notifylist"] +{ + padding:0; +} +afx-list-view[data-id = "notifylist"] > div.list-container > ul li{ + border:1px solid #464646; + border-radius: 3px; + margin-bottom: 5px; + -ms-word-break: break-all; + word-break: break-all; + word-break: break-word; + padding-top: 5px; + padding-bottom: 5px; +} + +afx-overlay[data-id = "feedzone"]{ + overflow: hidden; + background-color:transparent; + right:5px; + margin: 0; + padding:0; + top:0; +} +afx-list-view[data-id = "notifeed"] +{ + padding:0; + margin:0; +} +afx-list-view[data-id = "notifeed"] li{ + box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65); + border:1px solid #262626; + border-radius: 6px; + margin-bottom: 2px; + z-index: 99999; + -ms-word-break: break-all; + word-break: break-all; + word-break: break-word; } \ No newline at end of file diff --git a/src/packages/SystemServices/package.json b/src/packages/SystemServices/package.json new file mode 100644 index 0000000..7f7965f --- /dev/null +++ b/src/packages/SystemServices/package.json @@ -0,0 +1,15 @@ +{ + "pkgname": "SystemServices", + "services": ["PushNotification", "Calendar"], + "name": "System services", + "description": "System services", + "info": { + "author": "Xuan Sang LE", + "email": "xsang.le@gmail.com", + "licences": "GPLv3" + }, + "version": "0.1.0-a", + "category": "System", + "iconclass": "fa fa-cog", + "mimes": [] +} diff --git a/src/themes/antos_dark/afx-notification.css b/src/themes/antos_dark/afx-notification.css new file mode 100644 index 0000000..63a1059 --- /dev/null +++ b/src/themes/antos_dark/afx-notification.css @@ -0,0 +1,19 @@ +afx-toast-notification div[data-id="toast_container"] div[data-id="toast_header"]::before +{ + font-family: "bootstrap-icons"; + content: "\F62A"; + font-size: 20px; +} + +afx-toast-notification div[data-id="toast_container"] div[data-id="toast_header"]:hover +{ + color: orangered; +} + +afx-toast-notification div[data-id="toast_container"] +{ + box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65); + border:1px solid #262626; + background-color:#3b3b3b; + border-radius: 6px; +} diff --git a/src/themes/antos_light/afx-notification.css b/src/themes/antos_light/afx-notification.css new file mode 100644 index 0000000..ccf3f9f --- /dev/null +++ b/src/themes/antos_light/afx-notification.css @@ -0,0 +1,19 @@ +afx-toast-notification div[data-id="toast_container"] div[data-id="toast_header"]::before +{ + font-family: "bootstrap-icons"; + content: "\F62A"; + font-size: 20px; +} + +afx-toast-notification div[data-id="toast_container"] div[data-id="toast_header"]:hover +{ + color: orangered; +} + +afx-toast-notification div[data-id="toast_container"] +{ + box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65); + border: 1px solid #a6a6a6; + background-color: #f6F6F6; + border-radius: 6px; +} \ No newline at end of file diff --git a/src/themes/system/afx-notification.css b/src/themes/system/afx-notification.css new file mode 100644 index 0000000..3f44b51 --- /dev/null +++ b/src/themes/system/afx-notification.css @@ -0,0 +1,117 @@ +afx-notification { + display: contents; +} + +afx-notification div[data-id="north"] { + position: absolute; + top: 5px; + left: 50%; + transform: translate(-50%, 0); + /*max-width: 30%;*/ + max-height: 100%; + width: fit-content; + height: fit-content; + z-index: 1000000; + display: flex; + flex-direction: column; + align-items: center; + +} + + +afx-notification div[data-id="south"] { + position: absolute; + bottom: 5px; + left: 50%; + transform: translate(-50%, 0); + /*max-width: 30%;*/ + max-height: 100%; + width: fit-content; + height: fit-content; + z-index: 1000000; + display: flex; + flex-direction: column; + align-items: center; +} + +afx-notification div[data-id="north_west"] { + position: absolute; + left: 5px; + top: 5px; + /*max-width: 30%;*/ + max-height: 100%; + width: fit-content; + height: fit-content; + z-index: 1000000; + display: flex; + flex-direction: column; + align-items: flex-start; +} + +afx-notification div[data-id="south_west"] { + position: absolute; + left: 5px; + bottom: 5px; + /*max-width: 30%;*/ + max-height: 100%; + width: fit-content; + height: fit-content; + z-index: 1000000; + display: flex; + flex-direction: column; + align-items: flex-start; +} + +afx-notification div[data-id="north_est"] { + position: absolute; + right: 5px; + top: 5px; + /*max-width: 30%;*/ + max-height: 100%; + width: fit-content; + height: fit-content; + z-index: 1000000; + display: flex; + flex-direction: column; + align-items: flex-end; +} + +afx-notification div[data-id="south_est"] { + position: absolute; + right: 5px; + bottom: 5px; + /*max-width: 30%;*/ + max-height: 100%; + width: fit-content; + height: fit-content; + z-index: 1000000; + display: flex; + flex-direction: column; + align-items: flex-end; +} + +afx-toast-notification { + display: contents; +} + +afx-toast-notification div[data-id="toast_container"] +{ + display: block; + width: fit-content; + height: fit-content; + position: relative; + max-width: 300px; +} + +afx-toast-notification div[data-id="toast_container"] div[data-id="toast_header"] +{ + position: absolute; + width: 20px; + height: 20px; + right: 5px; +} + +afx-toast-notification div[data-id="toast_container"] div[data-id="toast_content"] +{ + padding: 20px 15px; +}