mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 13:39:24 +08:00
feat(notification): add "Mark all as read" functionality and improve message status toggling
This commit is contained in:
parent
04296bbac8
commit
e3caaee61c
@ -21,6 +21,7 @@ import {
|
||||
fetchMessages,
|
||||
inboxVisible,
|
||||
isFecthingMessageObs,
|
||||
markAllMessagesAsRead,
|
||||
selectedChannelNameObs,
|
||||
selectedMessageListObs,
|
||||
showMsgLoadingMoreObs,
|
||||
@ -48,7 +49,15 @@ const MessageList = observer(() => {
|
||||
read: t('Read'),
|
||||
unread: t('Unread'),
|
||||
};
|
||||
|
||||
const onMarkAllReadClick = useCallback(() => {
|
||||
if (selectedChannelName) {
|
||||
markAllMessagesAsRead({ channelName: selectedChannelName });
|
||||
}
|
||||
}, [selectedChannelName]);
|
||||
|
||||
if (!selectedChannelName) return null;
|
||||
|
||||
const onItemClicked = (message) => {
|
||||
updateMessage({
|
||||
filterByTk: message.id,
|
||||
@ -88,9 +97,14 @@ const MessageList = observer(() => {
|
||||
components: { Badge: { dotSize: 8 } },
|
||||
}}
|
||||
>
|
||||
<Typography.Title level={4} style={{ marginBottom: token.marginLG }}>
|
||||
<div
|
||||
style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: token.marginLG }}
|
||||
>
|
||||
<Typography.Title level={4} style={{ margin: 0 }}>
|
||||
{title}
|
||||
</Typography.Title>
|
||||
<Button onClick={onMarkAllReadClick}>{t('Mark all as read')}</Button>
|
||||
</div>
|
||||
|
||||
{messages.length === 0 && isFecthingMessageObs.value ? (
|
||||
<Spin style={{ width: '100%', marginTop: token.marginXXL }} />
|
||||
@ -150,7 +164,7 @@ const MessageList = observer(() => {
|
||||
<Descriptions.Item label={t('Datetime')}>{dayjs(message.receiveTimestamp).fromNow()}</Descriptions.Item>
|
||||
<Descriptions.Item label={t('Status')}>
|
||||
<div style={{ height: token.controlHeight }}>
|
||||
{hoveredMessageId === message.id && message.status === 'unread' ? (
|
||||
{hoveredMessageId === message.id ? (
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
@ -159,12 +173,12 @@ const MessageList = observer(() => {
|
||||
updateMessage({
|
||||
filterByTk: message.id,
|
||||
values: {
|
||||
status: 'read',
|
||||
status: message.status === 'read' ? 'unread' : 'read',
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t('Mark as read')}
|
||||
{t(message.status === 'unread' ? 'Mark as read' : 'Mark as unread')}
|
||||
</Button>
|
||||
) : (
|
||||
<Tag color={message.status === 'unread' ? 'red' : 'green'}>{msgStatusDict[message.status]}</Tag>
|
||||
|
@ -7,19 +7,18 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { observable, autorun } from '@formily/reactive';
|
||||
import { Message } from '../../types';
|
||||
import { autorun, observable } from '@formily/reactive';
|
||||
import { merge } from '@nocobase/utils/client';
|
||||
import { InAppMessagesDefinition, Message } from '../../types';
|
||||
import { getAPIClient } from '../utils';
|
||||
import {
|
||||
channelMapObs,
|
||||
selectedChannelNameObs,
|
||||
channelStatusFilterObs,
|
||||
fetchChannels,
|
||||
InappChannelStatusEnum,
|
||||
channelStatusFilterObs,
|
||||
selectedChannelNameObs,
|
||||
} from './channel';
|
||||
import { userIdObs } from './user';
|
||||
import { InAppMessagesDefinition } from '../../types';
|
||||
import { merge } from '@nocobase/utils/client';
|
||||
|
||||
export const messageMapObs = observable<{ value: Record<string, Message> }>({ value: {} });
|
||||
export const isFecthingMessageObs = observable<{ value: boolean }>({ value: false });
|
||||
@ -80,6 +79,22 @@ export const updateMessage = async (params: { filterByTk: any; values: Record<an
|
||||
updateUnreadMsgsCount();
|
||||
};
|
||||
|
||||
export const markAllMessagesAsRead = async ({ channelName }: { channelName: string }) => {
|
||||
const apiClient = getAPIClient();
|
||||
await apiClient.request({
|
||||
resource: InAppMessagesDefinition.name,
|
||||
action: 'update',
|
||||
method: 'post',
|
||||
params: { filter: { status: 'unread', channelName: channelName }, values: { status: 'read' } },
|
||||
});
|
||||
Object.values(messageMapObs.value).forEach((message) => {
|
||||
if (message.channelName === channelName && message.status === 'unread') {
|
||||
message.status = 'read';
|
||||
}
|
||||
});
|
||||
updateUnreadMsgsCount();
|
||||
};
|
||||
|
||||
autorun(() => {
|
||||
if (selectedChannelNameObs.value) {
|
||||
fetchMessages({ filter: { channelName: selectedChannelNameObs.value } });
|
||||
|
@ -22,6 +22,8 @@
|
||||
"Details page for desktop": "Details page for desktop",
|
||||
"Support two types of links: internal links and external links. If using an internal link, the link starts with\"/\", for example, \"/admin\". If using an external link, the link starts with \"http\", for example, \"https://example.com\".": "Support two types of links: internal links and external links. If using an internal link, the link starts with \"/\", for example, \"/admin\". If using an external link, the link starts with \"http\", for example, \"https://example.com\".",
|
||||
"Mark as read": "Mark as read",
|
||||
"Mark as unread": "Mark as unread",
|
||||
"Mark all as read": "Mark all as read",
|
||||
"Support two types of links: internal links and external links. If using an internal link, the link starts with\"/\", for example, \"/m\". If using an external link, the link starts with \"http\", for example, \"https://example.com\".": "Support two types of links: internal links and external links. If using an internal link, the link starts with \"/\", for example, \"/m\". If using an external link, the link starts with \"http\", for example, \"https://example.com\".",
|
||||
"Details page for mobile": "Details page for mobile",
|
||||
"The message page has already been created.": "The message page has already been created.",
|
||||
|
@ -21,7 +21,9 @@
|
||||
"detail URL": "详情链接",
|
||||
"Details page for desktop": "桌面端详情页",
|
||||
"Support two types of links: internal links and external links. If using an internal link, the link starts with\"/\", for example, \"/admin\". If using an external link, the link starts with \"http\", for example, \"https://example.com\".": "支持两种链接类型:内部链接和外部链接。如果使用内部链接,链接以“/”开头,例如“/admin”。如果使用外部链接,链接以“http”开头,例如“https://example.com”。",
|
||||
"Mark as read": "标记为已读",
|
||||
"Mark as read": "标为已读",
|
||||
"Mark as unread": "标为未读",
|
||||
"Mark all as read": "全部标为已读",
|
||||
"Support two types of links: internal links and external links. If using an internal link, the link starts with\"/\", for example, \"/m\". If using an external link, the link starts with \"http\", for example, \"https://example.com\".": "支持两种链接类型:内部链接和外部链接。如果使用内部链接,链接以“/”开头,例如“/m”。如果使用外部链接,链接以“http”开头,例如“https://example.com”。",
|
||||
"Details page for mobile": "移动端详情页",
|
||||
"The message page has already been created.": "站内信页面已创建。",
|
||||
|
Loading…
x
Reference in New Issue
Block a user