feat: web notification (#1573)
Co-authored-by: sealday <sealday@gmail.com> Reviewed-on: daoyoucloud/tachybase#1573
This commit is contained in:
parent
2425e43621
commit
4b5d09a3cf
@ -1,17 +0,0 @@
|
||||
import { Plugin } from '../../application/Plugin';
|
||||
|
||||
export class PluginWebNotification extends Plugin {
|
||||
async afterLoad() {
|
||||
// 请求用户授予权限
|
||||
if (Notification.permission !== 'denied') {
|
||||
await Notification.requestPermission();
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
const notification = new Notification('通知标题:', {
|
||||
body: '通知内容',
|
||||
icon: 'https://www.example.com/icon.png', // 通知的图标 URL
|
||||
});
|
||||
}, 2000);
|
||||
}
|
||||
}
|
@ -8,5 +8,4 @@ export * from './custom-components/CustomField';
|
||||
export * from './fields/AssociatedField';
|
||||
export * from './fields/CalcResult';
|
||||
export * from './fields/Expression';
|
||||
export * from './system/OnlineUserProvider';
|
||||
export * from './excel-table/ExcelFile';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { css, useAPIClient, useApp } from '@tachybase/client';
|
||||
import { PinnedPluginListProvider, SchemaComponentOptions, useAPIClient, useApp, useToken } from '@tachybase/client';
|
||||
import { uid } from '@tachybase/schema';
|
||||
|
||||
import { Button, Dropdown } from 'antd';
|
||||
@ -9,6 +9,7 @@ const OnlineUserManger = () => {
|
||||
const app = useApp();
|
||||
const [onlineUserItems, setOnlineUserItems] = useState([]);
|
||||
const api = useAPIClient();
|
||||
const { token } = useToken();
|
||||
useEffect(() => {
|
||||
app.ws.on('message', (event: MessageEvent) => {
|
||||
const data = JSON.parse(event.data);
|
||||
@ -38,32 +39,21 @@ const OnlineUserManger = () => {
|
||||
|
||||
return (
|
||||
<Dropdown menu={{ items: onlineUserItems }}>
|
||||
<Button style={{ width: 'auto' }} type="text">
|
||||
<Button style={{ width: 'auto', color: token.colorTextHeaderMenu }} type="text">
|
||||
在线 {_.size(onlineUserItems)} 人
|
||||
</Button>
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
||||
|
||||
export const OnlineUserDropdown = () => {
|
||||
export const OnlineUserProvider = (props) => {
|
||||
return (
|
||||
<div
|
||||
className={css`
|
||||
.ant-btn {
|
||||
border: 0;
|
||||
height: var(--tb-header-height);
|
||||
width: 46px;
|
||||
border-radius: 0;
|
||||
background: none;
|
||||
color: rgba(255, 255, 255, 0.65) !important;
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
}
|
||||
`}
|
||||
style={{ display: 'inline-block' }}
|
||||
<PinnedPluginListProvider
|
||||
items={{
|
||||
ou: { order: 230, component: 'OnlineUserManger', pin: true, isPublic: true },
|
||||
}}
|
||||
>
|
||||
<OnlineUserManger />
|
||||
</div>
|
||||
<SchemaComponentOptions components={{ OnlineUserManger }}>{props.children}</SchemaComponentOptions>
|
||||
</PinnedPluginListProvider>
|
||||
);
|
||||
};
|
@ -0,0 +1,9 @@
|
||||
import { Plugin } from '@tachybase/client';
|
||||
|
||||
import { OnlineUserProvider } from './OnlineUserProvider';
|
||||
|
||||
export class PluginOnlineUsers extends Plugin {
|
||||
async load() {
|
||||
this.app.use(OnlineUserProvider);
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ import { DepartmentsPlugin } from './features/departments';
|
||||
import { EmbedPlugin } from './features/embed';
|
||||
import { PluginFieldAppends } from './features/field-appends';
|
||||
import { PluginHeraVersion } from './features/hera-version';
|
||||
import { PluginOnlineUsers } from './features/online-users';
|
||||
import { PluginOutbound } from './features/outbound';
|
||||
import { PluginPDF } from './features/pdf';
|
||||
import { PluginSheet } from './features/sheet';
|
||||
@ -62,6 +63,7 @@ export class PluginCoreClient extends Plugin {
|
||||
await this.app.pm.add(PluginPDF);
|
||||
await this.app.pm.add(PluginOutbound);
|
||||
// await this.app.pm.add(PluginModeHighlight);
|
||||
await this.app.pm.add(PluginOnlineUsers);
|
||||
await this.app.pm.add(PluginFieldAppends);
|
||||
await this.app.pm.add(PluginCustomComponents);
|
||||
await this.app.pm.add(PluginSheet);
|
||||
|
@ -10,6 +10,7 @@ import { MessageNotificationProvider } from './MessageNotificationProvider';
|
||||
import { MessagePage } from './MessagePage';
|
||||
import { MessageProvider } from './MessageProvider';
|
||||
import { SubscriptionManager } from './SubscriptionManager';
|
||||
import { PluginWebNotification } from './web-notification/PluginWebNotification';
|
||||
|
||||
interface MessageType {
|
||||
title: string;
|
||||
@ -20,7 +21,7 @@ export class PluginMessagesClient extends Plugin {
|
||||
private _messageTypes: MessageType[] = [];
|
||||
|
||||
async afterAdd() {
|
||||
// await this.app.pm.add()
|
||||
await this.app.pm.add(PluginWebNotification, { name: 'message-web' });
|
||||
}
|
||||
|
||||
async beforeLoad() {}
|
||||
@ -71,11 +72,6 @@ export class PluginMessagesClient extends Plugin {
|
||||
Component: SubscriptionManager,
|
||||
});
|
||||
|
||||
this.registe({
|
||||
name: 'browser',
|
||||
title: lang('Browser notification'),
|
||||
});
|
||||
|
||||
this.registe({
|
||||
name: 'sms',
|
||||
title: lang('SMS notification'),
|
||||
|
@ -0,0 +1,30 @@
|
||||
import { Plugin } from '@tachybase/client';
|
||||
|
||||
import PluginMessagesClient from '..';
|
||||
import { lang } from '../locale';
|
||||
|
||||
export class PluginWebNotification extends Plugin {
|
||||
async afterLoad() {
|
||||
// 请求用户授予权限
|
||||
if (Notification.permission !== 'denied') {
|
||||
await Notification.requestPermission();
|
||||
}
|
||||
}
|
||||
|
||||
async load() {
|
||||
this.pm.get(PluginMessagesClient).registe({
|
||||
name: 'browser',
|
||||
title: lang('Browser notification'),
|
||||
});
|
||||
|
||||
this.app.ws.on('message', (event: MessageEvent) => {
|
||||
const data = JSON.parse(event.data);
|
||||
if (data?.type === 'messages') {
|
||||
const message = data.payload.message;
|
||||
const notification = new Notification(message.title, {
|
||||
body: message.content,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import { Model } from '@tachybase/database';
|
||||
import { PluginWorkflow } from '@tachybase/plugin-workflow';
|
||||
import { Plugin } from '@tachybase/server';
|
||||
import { Gateway, Plugin } from '@tachybase/server';
|
||||
|
||||
import { MessageInstruction } from './instructions/message-instruction';
|
||||
|
||||
@ -9,8 +10,20 @@ export class PluginMessagesServer extends Plugin {
|
||||
async beforeLoad() {}
|
||||
|
||||
async load() {
|
||||
const appName = this.app.name;
|
||||
const workflowPlugin = this.app.getPlugin<PluginWorkflow>(PluginWorkflow);
|
||||
workflowPlugin.registerInstruction('message-instruction', MessageInstruction);
|
||||
this.db.on('messages.afterCreate', async (message: Model, options) => {
|
||||
const gateway = Gateway.getInstance();
|
||||
const ws = gateway['wsServer'];
|
||||
|
||||
ws.sendToConnectionsByTag('app', appName, {
|
||||
type: 'messages',
|
||||
payload: {
|
||||
message: message.toJSON(),
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async install() {}
|
||||
|
@ -0,0 +1,2 @@
|
||||
/node_modules
|
||||
/src
|
1
packages/plugins/@tachybase/plugin-online-user/README.md
Normal file
1
packages/plugins/@tachybase/plugin-online-user/README.md
Normal file
@ -0,0 +1 @@
|
||||
# @tachybase/plugin-online-user
|
2
packages/plugins/@tachybase/plugin-online-user/client.d.ts
vendored
Normal file
2
packages/plugins/@tachybase/plugin-online-user/client.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './dist/client';
|
||||
export { default } from './dist/client';
|
1
packages/plugins/@tachybase/plugin-online-user/client.js
Normal file
1
packages/plugins/@tachybase/plugin-online-user/client.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require('./dist/client/index.js');
|
11
packages/plugins/@tachybase/plugin-online-user/package.json
Normal file
11
packages/plugins/@tachybase/plugin-online-user/package.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "@tachybase/plugin-online-user",
|
||||
"version": "0.22.4",
|
||||
"main": "dist/server/index.js",
|
||||
"dependencies": {},
|
||||
"peerDependencies": {
|
||||
"@tachybase/client": "workspace:*",
|
||||
"@tachybase/server": "workspace:*",
|
||||
"@tachybase/test": "workspace:*"
|
||||
}
|
||||
}
|
2
packages/plugins/@tachybase/plugin-online-user/server.d.ts
vendored
Normal file
2
packages/plugins/@tachybase/plugin-online-user/server.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './dist/server';
|
||||
export { default } from './dist/server';
|
1
packages/plugins/@tachybase/plugin-online-user/server.js
Normal file
1
packages/plugins/@tachybase/plugin-online-user/server.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require('./dist/server/index.js');
|
@ -0,0 +1,21 @@
|
||||
import { Plugin } from '@tachybase/client';
|
||||
|
||||
export class PluginOnlineUserClient extends Plugin {
|
||||
async afterAdd() {
|
||||
// await this.app.pm.add()
|
||||
}
|
||||
|
||||
async beforeLoad() {}
|
||||
|
||||
// You can get and modify the app instance here
|
||||
async load() {
|
||||
console.log(this.app);
|
||||
// this.app.addComponents({})
|
||||
// this.app.addScopes({})
|
||||
// this.app.addProvider()
|
||||
// this.app.addProviders()
|
||||
// this.app.router.add()
|
||||
}
|
||||
}
|
||||
|
||||
export default PluginOnlineUserClient;
|
@ -0,0 +1,2 @@
|
||||
export * from './server';
|
||||
export { default } from './server';
|
@ -0,0 +1 @@
|
||||
export { default } from './plugin';
|
@ -0,0 +1,19 @@
|
||||
import { Plugin } from '@tachybase/server';
|
||||
|
||||
export class PluginOnlineUserServer extends Plugin {
|
||||
async afterAdd() {}
|
||||
|
||||
async beforeLoad() {}
|
||||
|
||||
async load() {}
|
||||
|
||||
async install() {}
|
||||
|
||||
async afterEnable() {}
|
||||
|
||||
async afterDisable() {}
|
||||
|
||||
async remove() {}
|
||||
}
|
||||
|
||||
export default PluginOnlineUserServer;
|
@ -43,6 +43,7 @@
|
||||
"@tachybase/plugin-multi-app-manager": "workspace:*",
|
||||
"@tachybase/plugin-multi-app-share-collection": "workspace:*",
|
||||
"@tachybase/plugin-oidc": "workspace:*",
|
||||
"@tachybase/plugin-online-user": "workspace:*",
|
||||
"@tachybase/plugin-saml": "workspace:*",
|
||||
"@tachybase/plugin-sequence-field": "workspace:*",
|
||||
"@tachybase/plugin-sms-auth": "workspace:*",
|
||||
|
@ -18,6 +18,7 @@ export class PresetTachyBase extends Plugin {
|
||||
'acl',
|
||||
'messages',
|
||||
// optional plugins, default enabled
|
||||
'online-user',
|
||||
'action-bulk-edit',
|
||||
'action-bulk-update',
|
||||
'action-duplicate',
|
||||
|
@ -3656,6 +3656,18 @@ importers:
|
||||
specifier: ^6.25.1
|
||||
version: 6.25.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
|
||||
packages/plugins/@tachybase/plugin-online-user:
|
||||
dependencies:
|
||||
'@tachybase/client':
|
||||
specifier: workspace:*
|
||||
version: link:../../../core/client
|
||||
'@tachybase/server':
|
||||
specifier: workspace:*
|
||||
version: link:../../../core/server
|
||||
'@tachybase/test':
|
||||
specifier: workspace:*
|
||||
version: link:../../../core/test
|
||||
|
||||
packages/plugins/@tachybase/plugin-print-template:
|
||||
dependencies:
|
||||
'@bull-board/api':
|
||||
@ -4512,6 +4524,9 @@ importers:
|
||||
'@tachybase/plugin-oidc':
|
||||
specifier: workspace:*
|
||||
version: link:../../plugins/@tachybase/plugin-oidc
|
||||
'@tachybase/plugin-online-user':
|
||||
specifier: workspace:*
|
||||
version: link:../../plugins/@tachybase/plugin-online-user
|
||||
'@tachybase/plugin-saml':
|
||||
specifier: workspace:*
|
||||
version: link:../../plugins/@tachybase/plugin-saml
|
||||
|
Loading…
Reference in New Issue
Block a user