diff --git a/frappe/hooks.py b/frappe/hooks.py index a1aa2713c3..2e2da857eb 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -424,3 +424,12 @@ after_job = [ extend_bootinfo = [ "frappe.utils.telemetry.add_bootinfo", ] + +get_changelog_feed = [ + { + "title": "Spid", + "creation": "2023-04-03 16:56:51.436456", + "app_name": "Frappe Framework", + "link": "https://frappe.io/wiki", + } +] diff --git a/frappe/public/js/frappe/ui/notifications/notifications.js b/frappe/public/js/frappe/ui/notifications/notifications.js index a0c0257f1d..e02f62a62e 100644 --- a/frappe/public/js/frappe/ui/notifications/notifications.js +++ b/frappe/public/js/frappe/ui/notifications/notifications.js @@ -15,6 +15,7 @@ frappe.ui.Notifications = class Notifications { this.body = this.dropdown_list.find(".notification-list-body"); this.panel_events = this.dropdown_list.find(".panel-events"); this.panel_notifications = this.dropdown_list.find(".panel-notifications"); + this.panel_changelog_feed = this.dropdown_list.find(".panel-changelog-feed"); this.user = frappe.session.user; @@ -57,6 +58,12 @@ frappe.ui.Notifications = class Notifications { view: EventsView, el: this.panel_events, }, + { + label: __("What's New"), + id: "changelog_feed", + view: ChangelogFeedView, + el: this.panel_changelog_feed, + }, ]; let get_headers_html = (item) => { @@ -438,3 +445,53 @@ class EventsView extends BaseNotificationsView { this.container.html(html); } } + +class ChangelogFeedView extends BaseNotificationsView { + make() { + frappe + .xcall("frappe.utils.change_log.get_changelog_feed_items", {}) + .then((changelog_feed_list) => { + this.render_changelog_feed_html(changelog_feed_list); + }); + } + + render_changelog_feed_html(changelog_feed_list) { + let html = ""; + if (changelog_feed_list.length) { + this.container.empty(); + const get_changelog_feed_html = (changelog_feed_item) => { + const timestamp = frappe.datetime.comment_when(changelog_feed_item.creation); + const message_html = `
+
${changelog_feed_item.title}
+
+ ${changelog_feed_item.app_name} | ${timestamp} +
+
`; + + const item_html = ` +
+ ${message_html} +
+ +
`; + + return item_html; + }; + html = changelog_feed_list.map(get_changelog_feed_html).join(""); + } else { + html = ` +
+
+ Generic Empty State +
${__("Nothing New")}
+
+ ${__("There is nothing new for you.")} +
+ `; + } + this.container.html(html); + } +} diff --git a/frappe/public/js/frappe/ui/toolbar/navbar.html b/frappe/public/js/frappe/ui/toolbar/navbar.html index 451a4e7099..45d3055889 100644 --- a/frappe/public/js/frappe/ui/toolbar/navbar.html +++ b/frappe/public/js/frappe/ui/toolbar/navbar.html @@ -48,6 +48,7 @@
+
diff --git a/frappe/utils/change_log.py b/frappe/utils/change_log.py index a4b56686c2..378c796e24 100644 --- a/frappe/utils/change_log.py +++ b/frappe/utils/change_log.py @@ -309,3 +309,15 @@ def show_update_popup(): if update_message: frappe.msgprint(update_message, title=_("New updates are available"), indicator="green") cache.srem("update-user-set", user) + + +@frappe.whitelist() +def get_changelog_feed_items(): + """Returns a list of all fetched changelog feed items""" + + changelog_feed_items = frappe.cache().get_value("changelog_feed") + if not changelog_feed_items: + changelog_feed_items = frappe.get_hooks("get_changelog_feed") + frappe.cache().set_value("changelog_feed", changelog_feed_items, expires_in_sec=60 * 60) + + return changelog_feed_items