Keep unread notifications in sync with headerbar
This commit is contained in:
+13
-1
@@ -11,6 +11,7 @@ import { API_ORIGIN, TOKEN_TYPES } from './constants.js';
|
||||
import { redirectIfNeeded } from './utils.js';
|
||||
import ProfileModel from './models/ProfileModel.js';
|
||||
import ProvisionModel from './models/ProvisionModel.js';
|
||||
import NotificationsModel from './models/NotificationsModel.js';
|
||||
import DashboardModel from './models/DashboardModel.js';
|
||||
import BrandingModel from './models/BrandingModel.js';
|
||||
import Headerbar from './components/Headerbar.vue';
|
||||
@@ -275,12 +276,14 @@ fetcher.globalOptions.errorHook = (error) => {
|
||||
const dashboardModel = DashboardModel.create();
|
||||
const profileModel = ProfileModel.create();
|
||||
const provisionModel = ProvisionModel.create();
|
||||
const notificationModel = NotificationsModel.create();
|
||||
|
||||
const subscriptionRequiredDialog = useTemplateRef('subscriptionRequiredDialog');
|
||||
const ready = ref(false);
|
||||
const view = ref('');
|
||||
const profile = ref({});
|
||||
const dashboardDomain = ref('');
|
||||
const notificationCount = ref(0);
|
||||
const subscription = ref({
|
||||
plan: {},
|
||||
});
|
||||
@@ -392,6 +395,12 @@ async function refreshConfigAndFeatures() {
|
||||
dashboardDomain.value = result.adminDomain;
|
||||
}
|
||||
|
||||
async function refreshNotifications() {
|
||||
const [error, result] = await notificationModel.list(false);
|
||||
if (error) return console.error(error);
|
||||
notificationCount.value = result.length;
|
||||
}
|
||||
|
||||
async function onOnline() {
|
||||
ready.value = true;
|
||||
await refreshConfigAndFeatures(); // reload dashboard if needed after an update
|
||||
@@ -407,6 +416,7 @@ provide('features', features);
|
||||
provide('profile', profile);
|
||||
provide('refreshProfile', refreshProfile);
|
||||
provide('refreshFeatures', refreshConfigAndFeatures);
|
||||
provide('refreshNotifications', refreshNotifications);
|
||||
provide('dashboardDomain', dashboardDomain);
|
||||
provide('isMobile', isMobile);
|
||||
|
||||
@@ -443,6 +453,8 @@ onMounted(async () => {
|
||||
|
||||
console.log(`Cloudron dashboard v${config.value.version}`);
|
||||
|
||||
if (profile.value.isAtLeastAdmin) refreshNotifications();
|
||||
|
||||
ready.value = true;
|
||||
});
|
||||
|
||||
@@ -463,7 +475,7 @@ onUnmounted(() => {
|
||||
<SideBar v-if="profile.isAtLeastUserManager" :items="menuItems" :cloudron-name="config.cloudronName" :cloudron-avatar-url="avatarUrl"/>
|
||||
|
||||
<div style="flex-grow: 1; display: flex; flex-direction: column; overflow: hidden; height: 100%;">
|
||||
<Headerbar :config="config" :subscription="subscription"/>
|
||||
<Headerbar :config="config" :subscription="subscription" :notification-count="notificationCount"/>
|
||||
|
||||
<div style="display: flex; justify-content: center; overflow: auto; flex-grow: 1; padding: 0; margin: 0 10px; position: relative;">
|
||||
<KeepAlive>
|
||||
|
||||
@@ -7,11 +7,10 @@ const t = i18n.t;
|
||||
import { onMounted, onUnmounted, ref, useTemplateRef, inject } from 'vue';
|
||||
import { marked } from 'marked';
|
||||
import { Menu, Popover, Icon, InputDialog, Spinner } from '@cloudron/pankow';
|
||||
import NotificationsModel from '../models/NotificationsModel.js';
|
||||
import ServicesModel from '../models/ServicesModel.js';
|
||||
import ProfileModel from '../models/ProfileModel.js';
|
||||
|
||||
defineProps(['config', 'subscription']);
|
||||
defineProps(['config', 'subscription', 'notificationCount']);
|
||||
|
||||
const profile = inject('profile');
|
||||
|
||||
@@ -25,21 +24,6 @@ function onOpenHelp(popover, event, elem) {
|
||||
const servicesModel = ServicesModel.create();
|
||||
const profileModel = ProfileModel.create();
|
||||
|
||||
const notificationModel = NotificationsModel.create();
|
||||
const notifications = ref([]);
|
||||
|
||||
async function refresh() {
|
||||
const [error, result] = await notificationModel.list(false);
|
||||
if (error) return console.error(error);
|
||||
|
||||
result.forEach(n => {
|
||||
n.isCollapsed = true;
|
||||
n.busy = false;
|
||||
});
|
||||
|
||||
notifications.value = result;
|
||||
}
|
||||
|
||||
const subscriptionRequiredDialog = inject('subscriptionRequiredDialog');
|
||||
|
||||
function onSubscriptionRequired() {
|
||||
@@ -95,8 +79,6 @@ function onAvatarClick(event) {
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (profile.value.isAtLeastAdmin) await refresh();
|
||||
|
||||
await trackPlatformStatus();
|
||||
});
|
||||
|
||||
@@ -136,7 +118,7 @@ onUnmounted(() => {
|
||||
<!-- Warnings if subscription is expired or unpaid -->
|
||||
<div v-if="profile.isAtLeastOwner && subscription.plan.id === 'expired'" class="headerbar-action subscription-expired" style="gap: 6px" @click="onSubscriptionRequired()">Subscription Expired</div>
|
||||
|
||||
<a class="headerbar-action" v-if="profile.isAtLeastAdmin" href="/#/notifications"><Icon :icon="notifications.length ? 'fas fa-bell' : 'far fa-bell'"/> {{ notifications.length > 99 ? '99+' : notifications.length }}</a>
|
||||
<a class="headerbar-action" v-if="profile.isAtLeastAdmin" href="/#/notifications"><Icon :icon="notificationCount > 0 ? 'fas fa-bell' : 'far fa-bell'"/> {{ notificationCount > 99 ? '99+' : notificationCount }}</a>
|
||||
<div class="headerbar-action pankow-no-mobile" v-if="profile.isAtLeastAdmin" ref="helpButton" @click="onOpenHelp(helpPopover, $event, helpButton)"><Icon icon="fa fa-question"/></div>
|
||||
<!-- <a class="headerbar-action" v-if="profile.isAtLeastAdmin" href="#/support"><Icon icon="fa fa-question"/></a> -->
|
||||
<a class="headerbar-action" @click.capture="onAvatarClick($event)"><img :src="profile.avatarUrl" @error="event => event.target.src = '/img/avatar-default-symbolic.svg'"/> {{ profile.username }}</a>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { marked } from 'marked';
|
||||
import { eachLimit } from 'async';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ref, onMounted, inject } from 'vue';
|
||||
import { Button } from '@cloudron/pankow';
|
||||
import { prettyDate } from '@cloudron/pankow/utils';
|
||||
import NotificationsModel from '../models/NotificationsModel.js';
|
||||
@@ -12,6 +12,7 @@ const notificationsModel = NotificationsModel.create();
|
||||
const busy = ref(true);
|
||||
const notifications = ref([]);
|
||||
const notificationsAllBusy = ref(false);
|
||||
const refreshNotifications = inject('refreshNotifications');
|
||||
|
||||
async function refresh() {
|
||||
const [error, result] = await notificationsModel.list();
|
||||
@@ -30,6 +31,7 @@ async function onMarkNotificationRead(notification) {
|
||||
if (error) return console.error(error);
|
||||
|
||||
await refresh();
|
||||
refreshNotifications();
|
||||
}
|
||||
|
||||
async function onMarkNotificationUnread(notification) {
|
||||
@@ -38,6 +40,7 @@ async function onMarkNotificationUnread(notification) {
|
||||
if (error) return console.error(error);
|
||||
|
||||
await refresh();
|
||||
refreshNotifications();
|
||||
}
|
||||
|
||||
async function onMarkAllNotificationRead() {
|
||||
@@ -50,6 +53,7 @@ async function onMarkAllNotificationRead() {
|
||||
});
|
||||
|
||||
await refresh();
|
||||
refreshNotifications();
|
||||
|
||||
notificationsAllBusy.value = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user