jcloud/dashboard/src2/objects/notification.js
2025-04-12 17:39:38 +08:00

141 lines
3.2 KiB
JavaScript

import { h } from 'vue';
import router from '../router';
import { getDocResource } from '../utils/resource';
import { unreadNotificationsCount } from '../data/notifications';
import { Tooltip, jingrowRequest } from 'jingrow-ui';
import { icon } from '../utils/components';
import { getTeam } from '../data/team';
import { toast } from 'vue-sonner';
const getNotification = (name) => {
return getDocResource({
pagetype: 'Jcloud Notification',
name: name,
whitelistedMethods: {
markNotificationAsRead: 'mark_as_read',
},
});
};
export default {
pagetype: 'Jcloud Notification',
whitelistedMethods: {},
list: {
resource() {
let $team = getTeam();
return {
type: 'list',
pagetype: 'Jcloud Notification',
url: 'jcloud.api.notifications.get_notifications',
auto: true,
filters: {
read: 'Unread',
},
cache: ['Notifications'],
};
},
route: '/notifications',
title: '通知',
orderBy: 'creation desc',
filterControls() {
return [
{
type: 'tab',
label: '已读',
fieldname: 'read',
options: ['全部', '未读'],
default: '未读',
},
];
},
onRowClick(row) {
const notification = getNotification(row.name);
notification.markNotificationAsRead.submit().then(() => {
unreadNotificationsCount.setData((data) => data - 1);
if (row.route) router.push(row.route);
});
},
actions({ listResource: notifications }) {
return [
{
label: '全部标记为已读',
slots: {
prefix: icon('check-circle'),
},
async onClick() {
toast.promise(
jingrowRequest({
url: '/api/method/jcloud.api.notifications.mark_all_notifications_as_read',
}),
{
success: () => {
notifications.reload();
return '所有通知已标记为已读';
},
loading: '正在将所有通知标记为已读...',
error: (error) =>
error.messages?.length
? error.messages.join('\n')
: error.message,
},
);
},
},
];
},
columns: [
{
label: '标题',
fieldname: 'title',
width: '20rem',
format(value, row) {
return value || row.type;
},
suffix(row) {
if (row.is_actionable && !row.is_addressed) {
let AlertIcon = icon('alert-circle');
return h(
Tooltip,
{
text: '此通知需要您的关注',
},
{
default: () =>
h(
'div',
{
class: 'ml-2 text-red-500',
},
h(AlertIcon),
),
},
);
}
},
},
{
label: '消息',
fieldname: 'message',
type: 'Component',
width: '40rem',
component({ row }) {
return h('div', {
class: 'truncate text-base text-gray-600',
// replace all html tags except <b>
innerHTML: row.message
.replace(/<(?!\/?b\b)[^>]*>/g, '')
.split('\n')[0],
});
},
},
{
label: '',
fieldname: 'creation',
type: 'Timestamp',
align: 'right',
},
],
},
routes: [],
};