@nocobase/plugin-notification-manager 2.1.0-beta.9 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client-v2.d.ts +2 -0
- package/client-v2.js +1 -0
- package/dist/client/507.6b177256a5fdfe2f.js +10 -0
- package/dist/client/89.4f9da72110fbe97a.js +10 -0
- package/dist/client/index.js +1 -1
- package/dist/client-v2/49.83c515a7f909c364.js +10 -0
- package/dist/client-v2/852.543c355801fd322f.js +10 -0
- package/dist/client-v2/components/ContentConfigForm.d.ts +14 -0
- package/dist/client-v2/components/MessageConfigForm.d.ts +12 -0
- package/dist/client-v2/components/User/UserAddition.d.ts +16 -0
- package/dist/client-v2/components/User/UserSelect.d.ts +16 -0
- package/dist/client-v2/components/User/index.d.ts +12 -0
- package/dist/client-v2/index.d.ts +15 -0
- package/dist/client-v2/index.js +10 -0
- package/dist/client-v2/locale.d.ts +12 -0
- package/dist/client-v2/notification-manager.d.ts +36 -0
- package/dist/client-v2/pages/ChannelsPage.d.ts +10 -0
- package/dist/client-v2/pages/LogsPage.d.ts +10 -0
- package/dist/client-v2/plugin.d.ts +19 -0
- package/dist/client-v2/utils/notificationTypeOptions.d.ts +34 -0
- package/dist/collections/channel.d.ts +1 -0
- package/dist/collections/channel.js +1 -0
- package/dist/collections/messageLog.d.ts +1 -0
- package/dist/collections/messageLog.js +1 -0
- package/dist/externalVersion.js +14 -9
- package/dist/locale/de-DE.json +1 -0
- package/dist/locale/en-US.json +1 -0
- package/dist/locale/es-ES.json +1 -0
- package/dist/locale/fr-FR.json +1 -0
- package/dist/locale/hu-HU.json +1 -0
- package/dist/locale/id-ID.json +1 -0
- package/dist/locale/it-IT.json +1 -0
- package/dist/locale/ja-JP.json +1 -0
- package/dist/locale/ko-KR.json +1 -0
- package/dist/locale/nl-NL.json +1 -0
- package/dist/locale/pt-BR.json +1 -0
- package/dist/locale/ru-RU.json +1 -0
- package/dist/locale/tr-TR.json +1 -0
- package/dist/locale/uk-UA.json +1 -0
- package/dist/locale/vi-VN.json +1 -0
- package/dist/locale/zh-CN.json +1 -0
- package/dist/locale/zh-TW.json +1 -0
- package/dist/node_modules/uuid/dist/bin/uuid +2 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/index.js +104 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/max.js +7 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/md5.js +200 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/native.js +10 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/nil.js +7 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/parse.js +44 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/regex.js +7 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/rng.js +23 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/sha1.js +82 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/stringify.js +38 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/v1.js +131 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/v1ToV6.js +26 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/v3.js +11 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/v35.js +63 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/v4.js +32 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/v5.js +11 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/v6.js +42 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/v6ToV1.js +26 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/v7.js +152 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/validate.js +12 -0
- package/dist/node_modules/uuid/dist/commonjs-browser/version.js +15 -0
- package/dist/node_modules/uuid/dist/esm-browser/index.js +14 -0
- package/dist/node_modules/uuid/dist/esm-browser/max.js +1 -0
- package/dist/node_modules/uuid/dist/esm-browser/md5.js +194 -0
- package/dist/node_modules/uuid/dist/esm-browser/native.js +4 -0
- package/dist/node_modules/uuid/dist/esm-browser/nil.js +1 -0
- package/dist/node_modules/uuid/dist/esm-browser/parse.js +37 -0
- package/dist/node_modules/uuid/dist/esm-browser/regex.js +1 -0
- package/dist/node_modules/uuid/dist/esm-browser/rng.js +17 -0
- package/dist/node_modules/uuid/dist/esm-browser/sha1.js +76 -0
- package/dist/node_modules/uuid/dist/esm-browser/stringify.js +31 -0
- package/dist/node_modules/uuid/dist/esm-browser/v1.js +125 -0
- package/dist/node_modules/uuid/dist/esm-browser/v1ToV6.js +20 -0
- package/dist/node_modules/uuid/dist/esm-browser/v3.js +4 -0
- package/dist/node_modules/uuid/dist/esm-browser/v35.js +55 -0
- package/dist/node_modules/uuid/dist/esm-browser/v4.js +25 -0
- package/dist/node_modules/uuid/dist/esm-browser/v5.js +4 -0
- package/dist/node_modules/uuid/dist/esm-browser/v6.js +36 -0
- package/dist/node_modules/uuid/dist/esm-browser/v6ToV1.js +20 -0
- package/dist/node_modules/uuid/dist/esm-browser/v7.js +146 -0
- package/dist/node_modules/uuid/dist/esm-browser/validate.js +5 -0
- package/dist/node_modules/uuid/dist/esm-browser/version.js +8 -0
- package/dist/node_modules/uuid/dist/esm-node/index.js +14 -0
- package/dist/node_modules/uuid/dist/esm-node/max.js +1 -0
- package/dist/node_modules/uuid/dist/esm-node/md5.js +10 -0
- package/dist/node_modules/uuid/dist/esm-node/native.js +4 -0
- package/dist/node_modules/uuid/dist/esm-node/nil.js +1 -0
- package/dist/node_modules/uuid/dist/esm-node/parse.js +37 -0
- package/dist/node_modules/uuid/dist/esm-node/regex.js +1 -0
- package/dist/node_modules/uuid/dist/esm-node/rng.js +10 -0
- package/dist/node_modules/uuid/dist/esm-node/sha1.js +10 -0
- package/dist/node_modules/uuid/dist/esm-node/stringify.js +31 -0
- package/dist/node_modules/uuid/dist/esm-node/v1.js +125 -0
- package/dist/node_modules/uuid/dist/esm-node/v1ToV6.js +20 -0
- package/dist/node_modules/uuid/dist/esm-node/v3.js +4 -0
- package/dist/node_modules/uuid/dist/esm-node/v35.js +55 -0
- package/dist/node_modules/uuid/dist/esm-node/v4.js +25 -0
- package/dist/node_modules/uuid/dist/esm-node/v5.js +4 -0
- package/dist/node_modules/uuid/dist/esm-node/v6.js +32 -0
- package/dist/node_modules/uuid/dist/esm-node/v6ToV1.js +20 -0
- package/dist/node_modules/uuid/dist/esm-node/v7.js +146 -0
- package/dist/node_modules/uuid/dist/esm-node/validate.js +5 -0
- package/dist/node_modules/uuid/dist/esm-node/version.js +8 -0
- package/dist/node_modules/uuid/dist/index.js +1 -0
- package/dist/node_modules/uuid/dist/max.js +7 -0
- package/dist/node_modules/uuid/dist/md5-browser.js +200 -0
- package/dist/node_modules/uuid/dist/md5.js +17 -0
- package/dist/node_modules/uuid/dist/native-browser.js +10 -0
- package/dist/node_modules/uuid/dist/native.js +11 -0
- package/dist/node_modules/uuid/dist/nil.js +7 -0
- package/dist/node_modules/uuid/dist/parse.js +44 -0
- package/dist/node_modules/uuid/dist/regex.js +7 -0
- package/dist/node_modules/uuid/dist/rng-browser.js +23 -0
- package/dist/node_modules/uuid/dist/rng.js +17 -0
- package/dist/node_modules/uuid/dist/sha1-browser.js +82 -0
- package/dist/node_modules/uuid/dist/sha1.js +17 -0
- package/dist/node_modules/uuid/dist/stringify.js +38 -0
- package/dist/node_modules/uuid/dist/uuid-bin.js +75 -0
- package/dist/node_modules/uuid/dist/v1.js +131 -0
- package/dist/node_modules/uuid/dist/v1ToV6.js +26 -0
- package/dist/node_modules/uuid/dist/v3.js +11 -0
- package/dist/node_modules/uuid/dist/v35.js +63 -0
- package/dist/node_modules/uuid/dist/v4.js +32 -0
- package/dist/node_modules/uuid/dist/v5.js +11 -0
- package/dist/node_modules/uuid/dist/v6.js +38 -0
- package/dist/node_modules/uuid/dist/v6ToV1.js +26 -0
- package/dist/node_modules/uuid/dist/v7.js +152 -0
- package/dist/node_modules/uuid/dist/validate.js +12 -0
- package/dist/node_modules/uuid/dist/version.js +15 -0
- package/dist/node_modules/uuid/package.json +1 -0
- package/dist/server/base-notification-channel.d.ts +3 -1
- package/dist/server/manager.d.ts +52 -5
- package/dist/server/manager.js +168 -17
- package/dist/server/plugin.d.ts +49 -2
- package/dist/server/plugin.js +65 -2
- package/dist/server/types.d.ts +7 -3
- package/package.json +3 -2
- package/dist/client/035b24990a46d186.js +0 -10
- package/dist/client/b1941306dc0db9f3.js +0 -10
package/dist/server/manager.d.ts
CHANGED
|
@@ -8,19 +8,66 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Registry } from '@nocobase/utils';
|
|
10
10
|
import PluginNotificationManagerServer from './plugin';
|
|
11
|
-
import type { NotificationChannelConstructor, RegisterServerTypeFnParams, SendOptions, SendUserOptions, WriteLogOptions } from './types';
|
|
11
|
+
import type { NotificationQueueMessage, NotificationChannelConstructor, RegisterServerTypeFnParams, ReceiversOptions, SendOptions, SendUserOptions, WriteLogOptions } from './types';
|
|
12
12
|
export declare class NotificationManager implements NotificationManager {
|
|
13
|
+
private static readonly SLOW_SEND_THRESHOLD_MS;
|
|
13
14
|
private plugin;
|
|
14
15
|
channelTypes: Registry<{
|
|
15
16
|
Channel: NotificationChannelConstructor;
|
|
17
|
+
useQueue: boolean;
|
|
16
18
|
}>;
|
|
17
19
|
constructor({ plugin }: {
|
|
18
20
|
plugin: PluginNotificationManagerServer;
|
|
19
21
|
});
|
|
20
|
-
registerType({ type, Channel }: RegisterServerTypeFnParams): void;
|
|
21
|
-
createSendingRecord: (options: WriteLogOptions) => Promise<any
|
|
22
|
+
registerType({ type, Channel, useQueue }: RegisterServerTypeFnParams): void;
|
|
23
|
+
createSendingRecord: (options: WriteLogOptions) => Promise<import("@nocobase/database").Model<any, any>>;
|
|
24
|
+
private toQueueMessage;
|
|
25
|
+
private getQueuedResult;
|
|
26
|
+
private getDirectResult;
|
|
27
|
+
private getDeferredResult;
|
|
28
|
+
private shouldUseQueue;
|
|
29
|
+
private enqueue;
|
|
30
|
+
private dispatchAfterCommit;
|
|
22
31
|
findChannel(name: string): Promise<any>;
|
|
23
|
-
|
|
24
|
-
|
|
32
|
+
private getReceiverMeta;
|
|
33
|
+
send(params: SendOptions): Promise<{
|
|
34
|
+
status: "success" | "failure";
|
|
35
|
+
reason: string;
|
|
36
|
+
triggerFrom: string;
|
|
37
|
+
channelName: string;
|
|
38
|
+
receivers: ReceiversOptions;
|
|
39
|
+
queued: boolean;
|
|
40
|
+
} | {
|
|
41
|
+
status: "success";
|
|
42
|
+
triggerFrom: string;
|
|
43
|
+
channelName: string;
|
|
44
|
+
receivers: ReceiversOptions;
|
|
45
|
+
} | {
|
|
46
|
+
status: "failure";
|
|
47
|
+
reason: string;
|
|
48
|
+
triggerFrom: string;
|
|
49
|
+
channelName: string;
|
|
50
|
+
receivers: ReceiversOptions;
|
|
51
|
+
}>;
|
|
52
|
+
sendNow(params: NotificationQueueMessage): Promise<any>;
|
|
53
|
+
sendToUsers(options: SendUserOptions): Promise<({
|
|
54
|
+
status: "success" | "failure";
|
|
55
|
+
reason: string;
|
|
56
|
+
triggerFrom: string;
|
|
57
|
+
channelName: string;
|
|
58
|
+
receivers: ReceiversOptions;
|
|
59
|
+
queued: boolean;
|
|
60
|
+
} | {
|
|
61
|
+
status: "success";
|
|
62
|
+
triggerFrom: string;
|
|
63
|
+
channelName: string;
|
|
64
|
+
receivers: ReceiversOptions;
|
|
65
|
+
} | {
|
|
66
|
+
status: "failure";
|
|
67
|
+
reason: string;
|
|
68
|
+
triggerFrom: string;
|
|
69
|
+
channelName: string;
|
|
70
|
+
receivers: ReceiversOptions;
|
|
71
|
+
})[]>;
|
|
25
72
|
}
|
|
26
73
|
export default NotificationManager;
|
package/dist/server/manager.js
CHANGED
|
@@ -31,65 +31,215 @@ __export(manager_exports, {
|
|
|
31
31
|
});
|
|
32
32
|
module.exports = __toCommonJS(manager_exports);
|
|
33
33
|
var import_utils = require("@nocobase/utils");
|
|
34
|
+
var import_uuid = require("uuid");
|
|
34
35
|
var import_constant = require("../constant");
|
|
35
36
|
var import_compile = require("./utils/compile");
|
|
36
37
|
class NotificationManager {
|
|
38
|
+
static SLOW_SEND_THRESHOLD_MS = 500;
|
|
37
39
|
plugin;
|
|
38
40
|
channelTypes = new import_utils.Registry();
|
|
39
41
|
constructor({ plugin }) {
|
|
40
42
|
this.plugin = plugin;
|
|
41
43
|
}
|
|
42
|
-
registerType({ type, Channel }) {
|
|
43
|
-
this.channelTypes.register(type, { Channel });
|
|
44
|
+
registerType({ type, Channel, useQueue = true }) {
|
|
45
|
+
this.channelTypes.register(type, { Channel, useQueue });
|
|
44
46
|
}
|
|
45
47
|
createSendingRecord = async (options) => {
|
|
46
|
-
const
|
|
47
|
-
return
|
|
48
|
+
const LogsModel = this.plugin.app.db.getModel(import_constant.COLLECTION_NAME.logs);
|
|
49
|
+
return LogsModel.create(
|
|
50
|
+
{
|
|
51
|
+
id: (0, import_uuid.v4)(),
|
|
52
|
+
...options
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
hooks: false,
|
|
56
|
+
validate: false
|
|
57
|
+
}
|
|
58
|
+
);
|
|
48
59
|
};
|
|
60
|
+
toQueueMessage(params) {
|
|
61
|
+
const { transaction, ...message } = params;
|
|
62
|
+
return message;
|
|
63
|
+
}
|
|
64
|
+
getQueuedResult(params) {
|
|
65
|
+
return {
|
|
66
|
+
status: "success",
|
|
67
|
+
triggerFrom: params.triggerFrom,
|
|
68
|
+
channelName: params.channelName,
|
|
69
|
+
receivers: params.receivers,
|
|
70
|
+
queued: true
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
getDirectResult(params, result) {
|
|
74
|
+
return {
|
|
75
|
+
status: result.status,
|
|
76
|
+
reason: result.reason,
|
|
77
|
+
triggerFrom: params.triggerFrom,
|
|
78
|
+
channelName: params.channelName,
|
|
79
|
+
receivers: params.receivers,
|
|
80
|
+
queued: false
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
getDeferredResult(params) {
|
|
84
|
+
return {
|
|
85
|
+
status: "success",
|
|
86
|
+
triggerFrom: params.triggerFrom,
|
|
87
|
+
channelName: params.channelName,
|
|
88
|
+
receivers: params.receivers
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
async shouldUseQueue(channelName) {
|
|
92
|
+
const channel = await this.findChannel(channelName);
|
|
93
|
+
if (!channel) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
const channelType = this.channelTypes.get(channel.notificationType);
|
|
97
|
+
return (channelType == null ? void 0 : channelType.useQueue) ?? true;
|
|
98
|
+
}
|
|
99
|
+
async enqueue(message) {
|
|
100
|
+
await this.plugin.app.eventQueue.publish(this.plugin.sendQueueChannel, message);
|
|
101
|
+
}
|
|
102
|
+
async dispatchAfterCommit(message) {
|
|
103
|
+
const useQueue = await this.shouldUseQueue(message.channelName);
|
|
104
|
+
if (useQueue) {
|
|
105
|
+
await this.enqueue(message);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
await this.sendNow(message);
|
|
109
|
+
}
|
|
49
110
|
async findChannel(name) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
111
|
+
return await this.plugin.getChannel(name);
|
|
112
|
+
}
|
|
113
|
+
getReceiverMeta(receivers) {
|
|
114
|
+
if (!receivers) {
|
|
115
|
+
return {};
|
|
116
|
+
}
|
|
117
|
+
if (receivers.type === "userId") {
|
|
118
|
+
return {
|
|
119
|
+
receiverType: receivers.type,
|
|
120
|
+
receiverCount: receivers.value.length
|
|
121
|
+
};
|
|
54
122
|
}
|
|
55
|
-
return
|
|
123
|
+
return {
|
|
124
|
+
receiverType: receivers.type
|
|
125
|
+
};
|
|
56
126
|
}
|
|
57
127
|
async send(params) {
|
|
58
|
-
this.
|
|
128
|
+
const queueMessage = this.toQueueMessage(params);
|
|
129
|
+
const transaction = params.transaction;
|
|
130
|
+
if (transaction == null ? void 0 : transaction.afterCommit) {
|
|
131
|
+
transaction.afterCommit(() => {
|
|
132
|
+
return this.dispatchAfterCommit(queueMessage).catch((error) => {
|
|
133
|
+
this.plugin.logger.error("notification dispatch failed after transaction committed", {
|
|
134
|
+
channelName: params.channelName,
|
|
135
|
+
triggerFrom: params.triggerFrom,
|
|
136
|
+
reason: error instanceof Error ? `${error.name}: ${error.message}` : JSON.stringify(error)
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
return this.getDeferredResult(params);
|
|
141
|
+
}
|
|
142
|
+
const useQueue = await this.shouldUseQueue(params.channelName);
|
|
143
|
+
if (!useQueue) {
|
|
144
|
+
const result = await this.sendNow(queueMessage);
|
|
145
|
+
return this.getDirectResult(params, result);
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
await this.enqueue(queueMessage);
|
|
149
|
+
return this.getQueuedResult(params);
|
|
150
|
+
} catch (error) {
|
|
151
|
+
const reason = error instanceof Error ? `${error.name}: ${error.message}` : JSON.stringify(error);
|
|
152
|
+
this.plugin.logger.error("notification queue publish failed", {
|
|
153
|
+
channelName: params.channelName,
|
|
154
|
+
triggerFrom: params.triggerFrom,
|
|
155
|
+
reason
|
|
156
|
+
});
|
|
157
|
+
return {
|
|
158
|
+
status: "failure",
|
|
159
|
+
reason,
|
|
160
|
+
triggerFrom: params.triggerFrom,
|
|
161
|
+
channelName: params.channelName,
|
|
162
|
+
receivers: params.receivers
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async sendNow(params) {
|
|
167
|
+
const startedAt = Date.now();
|
|
168
|
+
const receiverMeta = this.getReceiverMeta(params.receivers);
|
|
169
|
+
const compileStartedAt = Date.now();
|
|
59
170
|
const message = (0, import_compile.compile)(params.message ?? {}, params.data ?? {});
|
|
171
|
+
const compileMs = Date.now() - compileStartedAt;
|
|
60
172
|
const messageData = { ...params.receivers ? { receivers: params.receivers } : {}, ...message };
|
|
61
173
|
const logData = {
|
|
62
174
|
triggerFrom: params.triggerFrom,
|
|
63
175
|
channelName: params.channelName,
|
|
64
176
|
message: messageData
|
|
65
177
|
};
|
|
178
|
+
let findChannelMs = 0;
|
|
179
|
+
let channelSendMs = 0;
|
|
66
180
|
try {
|
|
181
|
+
const findChannelStartedAt = Date.now();
|
|
67
182
|
const channel = await this.findChannel(params.channelName);
|
|
183
|
+
findChannelMs = Date.now() - findChannelStartedAt;
|
|
68
184
|
if (channel) {
|
|
69
185
|
const Channel = this.channelTypes.get(channel.notificationType).Channel;
|
|
70
186
|
const instance = new Channel(this.plugin.app);
|
|
71
187
|
logData.channelTitle = channel.title;
|
|
72
188
|
logData.notificationType = channel.notificationType;
|
|
73
189
|
logData.receivers = params.receivers;
|
|
74
|
-
const
|
|
190
|
+
const channelSendStartedAt = Date.now();
|
|
191
|
+
const result = await instance.send({
|
|
192
|
+
message,
|
|
193
|
+
channel,
|
|
194
|
+
receivers: params.receivers
|
|
195
|
+
});
|
|
196
|
+
channelSendMs = Date.now() - channelSendStartedAt;
|
|
75
197
|
logData.status = result.status;
|
|
76
198
|
logData.reason = result.reason;
|
|
77
199
|
} else {
|
|
78
200
|
logData.status = "failure";
|
|
79
201
|
logData.reason = "channel not found";
|
|
80
202
|
}
|
|
81
|
-
this.createSendingRecord(logData);
|
|
203
|
+
await this.createSendingRecord(logData);
|
|
204
|
+
const totalMs = Date.now() - startedAt;
|
|
205
|
+
if (totalMs >= NotificationManager.SLOW_SEND_THRESHOLD_MS) {
|
|
206
|
+
this.plugin.logger.warn("notification send is slow", {
|
|
207
|
+
channelName: params.channelName,
|
|
208
|
+
triggerFrom: params.triggerFrom,
|
|
209
|
+
status: logData.status,
|
|
210
|
+
notificationType: logData.notificationType,
|
|
211
|
+
compileMs,
|
|
212
|
+
findChannelMs,
|
|
213
|
+
channelSendMs,
|
|
214
|
+
totalMs,
|
|
215
|
+
...receiverMeta
|
|
216
|
+
});
|
|
217
|
+
}
|
|
82
218
|
return logData;
|
|
83
219
|
} catch (error) {
|
|
84
220
|
logData.status = "failure";
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
this.
|
|
221
|
+
const totalMs = Date.now() - startedAt;
|
|
222
|
+
const reason = error instanceof Error ? `${error.name}: ${error.message}` : JSON.stringify(error);
|
|
223
|
+
this.plugin.logger.error("notification send failed", {
|
|
224
|
+
channelName: params.channelName,
|
|
225
|
+
triggerFrom: params.triggerFrom,
|
|
226
|
+
compileMs,
|
|
227
|
+
findChannelMs,
|
|
228
|
+
channelSendMs,
|
|
229
|
+
totalMs,
|
|
230
|
+
reason,
|
|
231
|
+
...receiverMeta
|
|
232
|
+
});
|
|
233
|
+
logData.reason = reason;
|
|
234
|
+
await this.createSendingRecord(logData);
|
|
88
235
|
return logData;
|
|
89
236
|
}
|
|
90
237
|
}
|
|
91
238
|
async sendToUsers(options) {
|
|
92
|
-
this.plugin.logger.
|
|
239
|
+
this.plugin.logger.debug("notificationManager.sendToUsers", {
|
|
240
|
+
channelCount: options.channels.length,
|
|
241
|
+
userCount: options.userIds.length
|
|
242
|
+
});
|
|
93
243
|
const { userIds, channels, message, data = {} } = options;
|
|
94
244
|
return await Promise.all(
|
|
95
245
|
channels.map(
|
|
@@ -98,7 +248,8 @@ class NotificationManager {
|
|
|
98
248
|
message,
|
|
99
249
|
data,
|
|
100
250
|
triggerFrom: "sendToUsers",
|
|
101
|
-
receivers: { value: userIds, type: "userId" }
|
|
251
|
+
receivers: { value: userIds, type: "userId" },
|
|
252
|
+
transaction: options.transaction
|
|
102
253
|
})
|
|
103
254
|
)
|
|
104
255
|
);
|
package/dist/server/plugin.d.ts
CHANGED
|
@@ -6,18 +6,65 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
+
import type { Cache } from '@nocobase/cache';
|
|
9
10
|
import type { Logger } from '@nocobase/logger';
|
|
11
|
+
import { Transactionable } from '@nocobase/database';
|
|
10
12
|
import { Plugin } from '@nocobase/server';
|
|
11
13
|
import { RegisterServerTypeFnParams, SendOptions, SendUserOptions } from './types';
|
|
12
14
|
export declare class PluginNotificationManagerServer extends Plugin {
|
|
15
|
+
private static readonly CHANNELS_CACHE_KEY;
|
|
13
16
|
private manager;
|
|
14
17
|
logger: Logger;
|
|
18
|
+
cache: Cache;
|
|
19
|
+
get sendQueueChannel(): string;
|
|
20
|
+
private ensureCache;
|
|
21
|
+
parseChannel(instance: any): any;
|
|
22
|
+
loadChannels(options?: Transactionable): Promise<void>;
|
|
23
|
+
getChannel(name: string): Promise<any>;
|
|
15
24
|
get channelTypes(): import("@nocobase/utils").Registry<{
|
|
16
25
|
Channel: import("./types").NotificationChannelConstructor;
|
|
26
|
+
useQueue: boolean;
|
|
17
27
|
}>;
|
|
18
28
|
registerChannelType(params: RegisterServerTypeFnParams): void;
|
|
19
|
-
send(options: SendOptions): Promise<
|
|
20
|
-
|
|
29
|
+
send(options: SendOptions): Promise<{
|
|
30
|
+
status: "success" | "failure";
|
|
31
|
+
reason: string;
|
|
32
|
+
triggerFrom: string;
|
|
33
|
+
channelName: string;
|
|
34
|
+
receivers: import("./types").ReceiversOptions;
|
|
35
|
+
queued: boolean;
|
|
36
|
+
} | {
|
|
37
|
+
status: "success";
|
|
38
|
+
triggerFrom: string;
|
|
39
|
+
channelName: string;
|
|
40
|
+
receivers: import("./types").ReceiversOptions;
|
|
41
|
+
} | {
|
|
42
|
+
status: "failure";
|
|
43
|
+
reason: string;
|
|
44
|
+
triggerFrom: string;
|
|
45
|
+
channelName: string;
|
|
46
|
+
receivers: import("./types").ReceiversOptions;
|
|
47
|
+
}>;
|
|
48
|
+
sendNow(options: SendOptions): Promise<any>;
|
|
49
|
+
sendToUsers(options: SendUserOptions): Promise<({
|
|
50
|
+
status: "success" | "failure";
|
|
51
|
+
reason: string;
|
|
52
|
+
triggerFrom: string;
|
|
53
|
+
channelName: string;
|
|
54
|
+
receivers: import("./types").ReceiversOptions;
|
|
55
|
+
queued: boolean;
|
|
56
|
+
} | {
|
|
57
|
+
status: "success";
|
|
58
|
+
triggerFrom: string;
|
|
59
|
+
channelName: string;
|
|
60
|
+
receivers: import("./types").ReceiversOptions;
|
|
61
|
+
} | {
|
|
62
|
+
status: "failure";
|
|
63
|
+
reason: string;
|
|
64
|
+
triggerFrom: string;
|
|
65
|
+
channelName: string;
|
|
66
|
+
receivers: import("./types").ReceiversOptions;
|
|
67
|
+
})[]>;
|
|
21
68
|
afterAdd(): Promise<void>;
|
|
22
69
|
beforeLoad(): Promise<void>;
|
|
23
70
|
load(): Promise<void>;
|
package/dist/server/plugin.js
CHANGED
|
@@ -41,10 +41,50 @@ __export(plugin_exports, {
|
|
|
41
41
|
});
|
|
42
42
|
module.exports = __toCommonJS(plugin_exports);
|
|
43
43
|
var import_server = require("@nocobase/server");
|
|
44
|
+
var import_constant = require("../constant");
|
|
44
45
|
var import_manager = __toESM(require("./manager"));
|
|
45
46
|
class PluginNotificationManagerServer extends import_server.Plugin {
|
|
47
|
+
static CHANNELS_CACHE_KEY = "channels";
|
|
46
48
|
manager;
|
|
47
49
|
logger;
|
|
50
|
+
cache;
|
|
51
|
+
get sendQueueChannel() {
|
|
52
|
+
return `${this.name}.send`;
|
|
53
|
+
}
|
|
54
|
+
async ensureCache() {
|
|
55
|
+
if (!this.cache) {
|
|
56
|
+
this.cache = await this.app.cacheManager.createCache({
|
|
57
|
+
name: this.name,
|
|
58
|
+
prefix: this.name
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return this.cache;
|
|
62
|
+
}
|
|
63
|
+
parseChannel(instance) {
|
|
64
|
+
return this.app.environment.renderJsonTemplate(instance.toJSON());
|
|
65
|
+
}
|
|
66
|
+
async loadChannels(options) {
|
|
67
|
+
const cache = await this.ensureCache();
|
|
68
|
+
const repository = this.app.db.getRepository(import_constant.COLLECTION_NAME.channels);
|
|
69
|
+
const channels = await repository.find({
|
|
70
|
+
transaction: options == null ? void 0 : options.transaction
|
|
71
|
+
});
|
|
72
|
+
const channelsCache = {};
|
|
73
|
+
for (const channel of channels) {
|
|
74
|
+
channelsCache[channel.get("name")] = this.parseChannel(channel);
|
|
75
|
+
}
|
|
76
|
+
await cache.set(PluginNotificationManagerServer.CHANNELS_CACHE_KEY, channelsCache);
|
|
77
|
+
}
|
|
78
|
+
async getChannel(name) {
|
|
79
|
+
const cache = await this.ensureCache();
|
|
80
|
+
const channels = await cache.get(PluginNotificationManagerServer.CHANNELS_CACHE_KEY) || void 0;
|
|
81
|
+
if (!channels) {
|
|
82
|
+
await this.loadChannels();
|
|
83
|
+
const reloadedChannels = await cache.get(PluginNotificationManagerServer.CHANNELS_CACHE_KEY);
|
|
84
|
+
return (reloadedChannels == null ? void 0 : reloadedChannels[name]) || null;
|
|
85
|
+
}
|
|
86
|
+
return channels[name] || null;
|
|
87
|
+
}
|
|
48
88
|
get channelTypes() {
|
|
49
89
|
return this.manager.channelTypes;
|
|
50
90
|
}
|
|
@@ -54,6 +94,10 @@ class PluginNotificationManagerServer extends import_server.Plugin {
|
|
|
54
94
|
async send(options) {
|
|
55
95
|
return await this.manager.send(options);
|
|
56
96
|
}
|
|
97
|
+
async sendNow(options) {
|
|
98
|
+
const { transaction, ...message } = options;
|
|
99
|
+
return await this.manager.sendNow(message);
|
|
100
|
+
}
|
|
57
101
|
async sendToUsers(options) {
|
|
58
102
|
return await this.manager.sendToUsers(options);
|
|
59
103
|
}
|
|
@@ -69,8 +113,8 @@ class PluginNotificationManagerServer extends import_server.Plugin {
|
|
|
69
113
|
this.app.resourceManager.registerActionHandler("messages:send", async (ctx, next) => {
|
|
70
114
|
var _a, _b;
|
|
71
115
|
const sendOptions = (_b = (_a = ctx.action) == null ? void 0 : _a.params) == null ? void 0 : _b.values;
|
|
72
|
-
this.manager.send(sendOptions);
|
|
73
|
-
next();
|
|
116
|
+
await this.manager.send(sendOptions);
|
|
117
|
+
await next();
|
|
74
118
|
});
|
|
75
119
|
this.app.acl.registerSnippet({
|
|
76
120
|
name: "pm.notification.channels",
|
|
@@ -80,16 +124,35 @@ class PluginNotificationManagerServer extends import_server.Plugin {
|
|
|
80
124
|
name: "pm.notification.logs",
|
|
81
125
|
actions: ["notificationSendLogs:*"]
|
|
82
126
|
});
|
|
127
|
+
this.app.on("afterStart", async () => {
|
|
128
|
+
await this.loadChannels();
|
|
129
|
+
});
|
|
83
130
|
}
|
|
84
131
|
async load() {
|
|
132
|
+
const Channel = this.app.db.getModel(import_constant.COLLECTION_NAME.channels);
|
|
133
|
+
Channel.afterSave(async (_model, { transaction }) => {
|
|
134
|
+
await this.loadChannels({ transaction });
|
|
135
|
+
});
|
|
136
|
+
Channel.afterDestroy(async (_model, { transaction }) => {
|
|
137
|
+
await this.loadChannels({ transaction });
|
|
138
|
+
});
|
|
139
|
+
this.app.eventQueue.subscribe(this.sendQueueChannel, {
|
|
140
|
+
concurrency: 1,
|
|
141
|
+
idle: () => true,
|
|
142
|
+
process: async (message) => {
|
|
143
|
+
await this.manager.sendNow(message);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
85
146
|
}
|
|
86
147
|
async install() {
|
|
87
148
|
}
|
|
88
149
|
async afterEnable() {
|
|
89
150
|
}
|
|
90
151
|
async afterDisable() {
|
|
152
|
+
this.app.eventQueue.unsubscribe(this.sendQueueChannel);
|
|
91
153
|
}
|
|
92
154
|
async remove() {
|
|
155
|
+
this.app.eventQueue.unsubscribe(this.sendQueueChannel);
|
|
93
156
|
}
|
|
94
157
|
}
|
|
95
158
|
var plugin_default = PluginNotificationManagerServer;
|
package/dist/server/types.d.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
+
import { Transactionable } from '@nocobase/database';
|
|
9
10
|
import { Application } from '@nocobase/server';
|
|
10
11
|
import { BaseNotificationChannel } from './base-notification-channel';
|
|
11
12
|
/**
|
|
@@ -33,9 +34,10 @@ export type SendFnType<Message> = (args: {
|
|
|
33
34
|
message: Message;
|
|
34
35
|
channel: ChannelOptions;
|
|
35
36
|
receivers?: ReceiversOptions;
|
|
37
|
+
transaction?: Transactionable['transaction'];
|
|
36
38
|
}) => Promise<{
|
|
37
39
|
message: Message;
|
|
38
|
-
status: 'success' | '
|
|
40
|
+
status: 'success' | 'failure';
|
|
39
41
|
reason?: string;
|
|
40
42
|
}>;
|
|
41
43
|
export type ReceiversOptions = {
|
|
@@ -46,14 +48,15 @@ export type ReceiversOptions = {
|
|
|
46
48
|
type: 'channel-self-defined';
|
|
47
49
|
channelType: string;
|
|
48
50
|
};
|
|
49
|
-
export interface SendOptions {
|
|
51
|
+
export interface SendOptions extends Transactionable {
|
|
50
52
|
channelName: string;
|
|
51
53
|
message: Record<string, any>;
|
|
52
54
|
triggerFrom: string;
|
|
53
55
|
receivers?: ReceiversOptions;
|
|
54
56
|
data?: Record<string, any>;
|
|
55
57
|
}
|
|
56
|
-
export
|
|
58
|
+
export type NotificationQueueMessage = Omit<SendOptions, 'transaction'>;
|
|
59
|
+
export interface SendUserOptions extends Transactionable {
|
|
57
60
|
userIds: number[];
|
|
58
61
|
channels: string[];
|
|
59
62
|
message: Record<string, any>;
|
|
@@ -63,4 +66,5 @@ export type NotificationChannelConstructor = new (app: Application) => BaseNotif
|
|
|
63
66
|
export type RegisterServerTypeFnParams = {
|
|
64
67
|
type: string;
|
|
65
68
|
Channel: NotificationChannelConstructor;
|
|
69
|
+
useQueue?: boolean;
|
|
66
70
|
};
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"description.ru-RU": "Предоставляет единый сервис управления, включающий конфигурирование каналов, логирование и другие функции, поддерживает настройку различных каналов уведомлений, включая внутренние сообщения и электронную почту.",
|
|
7
7
|
"displayName.zh-CN": "通知管理",
|
|
8
8
|
"description.zh-CN": "提供统一的管理服务,涵盖渠道配置、日志记录等功能,支持多种通知渠道的配置,包括站内信和电子邮件等。",
|
|
9
|
-
"version": "2.1.0
|
|
9
|
+
"version": "2.1.0",
|
|
10
10
|
"homepage": "https://docs.nocobase.com/handbook/notification-manager",
|
|
11
11
|
"homepage.ru-RU": "https://docs-ru.nocobase.com/handbook/notification-manager",
|
|
12
12
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/notification-manager",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"@nocobase/actions": "2.x",
|
|
27
27
|
"@nocobase/client": "2.x",
|
|
28
|
+
"@nocobase/client-v2": "2.x",
|
|
28
29
|
"@nocobase/database": "2.x",
|
|
29
30
|
"@nocobase/plugin-workflow": ">=0.17.0-alpha.3",
|
|
30
31
|
"@nocobase/server": "2.x",
|
|
@@ -35,5 +36,5 @@
|
|
|
35
36
|
"Notification"
|
|
36
37
|
],
|
|
37
38
|
"license": "Apache-2.0",
|
|
38
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "9373212dd0f22cd985be1e23674d6b454944b9ee"
|
|
39
40
|
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is part of the NocoBase (R) project.
|
|
3
|
-
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
-
* Authors: NocoBase Team.
|
|
5
|
-
*
|
|
6
|
-
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
-
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
"use strict";(self.webpackChunk_nocobase_plugin_notification_manager=self.webpackChunk_nocobase_plugin_notification_manager||[]).push([["969"],{358:function(e,t,o){o.r(t),o.d(t,{LogManager:function(){return f}});var n,r,i=o(772),p=o(721),a=o(156),c=o.n(a),l=o(712),s=o(807),m=o(551),d=o(655),u=o(296),y={id:{"x-component":"CollectionField","x-decorator":"FormItem","x-disabled":!0,"x-read-pretty":!0},channelName:{"x-component":"CollectionField","x-decorator":"FormItem","x-read-pretty":!0},channelTitle:{"x-component":"CollectionField","x-decorator":"FormItem","x-read-pretty":!0},notificationType:{"x-component":"CollectionField","x-decorator":"FormItem","x-read-pretty":!0},triggerFrom:{"x-component":"CollectionField","x-decorator":"FormItem","x-read-pretty":!0},status:{"x-component":"CollectionField","x-decorator":"FormItem","x-read-pretty":!0},message:{"x-component":"CollectionField","x-decorator":"FormItem","x-read-pretty":!0},reason:{"x-component":"CollectionField","x-decorator":"FormItem","x-read-pretty":!0,"x-reactions":[{dependencies:["status"],fulfill:{state:{visible:'{{$deps[0] === "failure"}}'}}}]},createdAt:{"x-component":"CollectionField","x-decorator":"FormItem","x-read-pretty":!0,"x-component-props":{dateFormat:"YYYY-MM-DD",showTime:!0,timeFormat:"HH:mm:ss"}}},x={type:"void","x-uid":"t8tkmt2b9dd",name:u.O.logs,"x-decorator":"TableBlockProvider","x-decorator-props":{collection:s.Z.name,action:"list",params:{sort:["-createdAt"]},showIndex:!0,dragSort:!1},properties:{actions:{type:"void","x-component":"ActionBar","x-component-props":{style:{marginBottom:16}},properties:{refresh:{title:"{{t('Refresh')}}","x-action":"refresh","x-component":"Action","x-use-component-props":"useRefreshActionProps","x-component-props":{icon:"ReloadOutlined"}},filter:{"x-action":"filter","x-component":"Filter.Action",title:"{{t('Filter')}}","x-use-component-props":"useFilterActionProps","x-component-props":{icon:"FilterOutlined",nonfilterable:["receiver","reason"]},"x-align":"left"}}},table:{type:"array","x-component":"TableV2","x-use-component-props":"useTableBlockProps","x-component-props":{rowKey:"id"},properties:{createdAt:{type:"void","x-component":"TableV2.Column","x-component-props":{width:100},title:'{{t("Created at")}}',properties:{createdAt:{type:"string","x-component":"CollectionField","x-pattern":"readPretty","x-component-props":{dateFormat:"YYYY-MM-DD",showTime:!0,timeFormat:"HH:mm:ss"}}}},triggerFrom:{type:"void","x-component":"TableV2.Column","x-component-props":{width:100},title:'{{t("Trigger from")}}',properties:{triggerFrom:{type:"string","x-component":"CollectionField","x-read-pretty":!0,"x-component-props":{ellipsis:!0}}}},channelTitle:{type:"void","x-component":"TableV2.Column","x-component-props":{width:100},title:'{{t("Channel display name")}}',properties:{channelTitle:{type:"string","x-component":"CollectionField","x-read-pretty":!0,"x-component-props":{ellipsis:!0}}}},notificationType:{title:'{{t("Notification type")}}',type:"void","x-component":"TableV2.Column",properties:{notificationType:{type:"string","x-component":"CollectionField","x-read-pretty":!0}}},status:{type:"void","x-component":"TableV2.Column","x-component-props":{width:100},title:'{{t("Status")}}',properties:{status:{type:"string","x-component":"CollectionField","x-pattern":"readPretty"}}},reason:{type:"void","x-component":"TableV2.Column","x-component-props":{width:200},title:'{{t("Failed reason")}}',properties:{reason:{type:"string","x-component":"CollectionField","x-read-pretty":!0,"x-component-props":{ellipsis:!0}}}},actions:{type:"void",title:'{{t("Actions")}}',"x-component":"TableV2.Column",properties:{view:{type:"void",title:'{{t("View")}}',"x-component":"Action.Link","x-component-props":{openMode:"drawer"},properties:{drawer:{type:"void",title:'{{t("Log detail")}}',"x-component":"Action.Drawer",properties:{detail:{type:"void","x-component":"FormV2","x-use-component-props":"useEditFormProps","x-decorator":"BlockItemCard",properties:(n=function(e){for(var t=1;t<arguments.length;t++){var o=null!=arguments[t]?arguments[t]:{},n=Object.keys(o);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(o).filter(function(e){return Object.getOwnPropertyDescriptor(o,e).enumerable}))),n.forEach(function(t){var n;n=o[t],t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n})}return e}({},y),r=r={footer:{type:"void","x-component":"Action.Drawer.Footer"}},Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(r)):(function(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);o.push.apply(o,n)}return o})(Object(r)).forEach(function(e){Object.defineProperty(n,e,Object.getOwnPropertyDescriptor(r,e))}),n)}}}}}}}}}}},f=function(){var e=(0,m.oG)().t,t=(0,i.useSchemaComponentContext)(),o=(0,d.aT)(),n=(0,a.useMemo)(function(){var e,o;return e=function(e){for(var t=1;t<arguments.length;t++){var o=null!=arguments[t]?arguments[t]:{},n=Object.keys(o);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(o).filter(function(e){return Object.getOwnPropertyDescriptor(o,e).enumerable}))),n.forEach(function(t){var n;n=o[t],t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n})}return e}({},t),o=o={designable:!1},Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(o)):(function(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);o.push.apply(o,n)}return o})(Object(o)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(o,t))}),e},[t]);return c().createElement(i.ExtendCollectionsProvider,{collections:[s.Z,l.Z]},c().createElement(i.SchemaComponentContext.Provider,{value:n},c().createElement(p.Card,{bordered:!1},c().createElement(i.SchemaComponent,{schema:x,scope:{t:e,useEditFormProps:d.fC,notificationTypeOptions:o}}))))};f.displayName="LogManager"},712:function(e,t,o){t.Z={name:o(296).O.channels,migrationRules:["overwrite","schema-only"],filterTargetKey:"name",autoGenId:!1,createdAt:!0,createdBy:!0,updatedAt:!0,updatedBy:!0,fields:[{name:"name",type:"uid",prefix:"s_",primaryKey:!0,interface:"input",uiSchema:{type:"string",title:'{{t("Channel name")}}',"x-component":"Input",required:!0,description:"{{t('Randomly generated and can not be modified. Support letters, numbers and underscores, must start with an letter.')}}"}},{name:"title",type:"string",interface:"input",uiSchema:{type:"string","x-component":"Input",title:'{{t("Channel display name")}}',required:!0}},{name:"options",type:"json",interface:"json",uiSchema:{type:"object","x-component":"ConfigForm"}},{name:"meta",type:"json",interface:"json"},{interface:"input",type:"string",name:"notificationType",uiSchema:{type:"string",title:'{{t("Notification type")}}',"x-component":"Select",enum:"{{notificationTypeOptions}}",required:!0}},{name:"description",type:"text",interface:"textarea",uiSchema:{type:"string","x-component":"Input.TextArea",title:'{{t("Description")}}'}}]}},807:function(e,t,o){t.Z={name:o(296).O.logs,migrationRules:["schema-only"],title:"MessageLogs",fields:[{name:"id",type:"uuid",primaryKey:!0,allowNull:!1,interface:"uuid",uiSchema:{type:"string",title:'{{t("ID")}}',"x-component":"Input","x-read-pretty":!0}},{name:"channelName",type:"string",interface:"input",uiSchema:{type:"string",title:'{{t("Channel name")}}',"x-component":"Input"}},{name:"channelTitle",type:"string",interface:"input",uiSchema:{type:"string","x-component":"Input",title:'{{t("Channel display name")}}'}},{name:"triggerFrom",type:"string",interface:"input",uiSchema:{type:"string","x-component":"Input",title:'{{t("Trigger from")}}'}},{name:"notificationType",type:"string",interface:"input",uiSchema:{type:"string",title:'{{t("Notification type")}}',"x-component":"Select",enum:"{{notificationTypeOptions}}",required:!0}},{name:"status",type:"string",interface:"select",uiSchema:{type:"string","x-component":"Select",enum:[{label:'{{t("Success")}}',value:"success",color:"green"},{label:'{{t("Failure")}}',value:"failure",color:"red"}],title:'{{t("Status")}}'}},{name:"message",type:"json",interface:"json",uiSchema:{"x-component":"Input.JSON",title:'{{t("Message")}}',"x-component-props":{autoSize:{minRows:5}},autoSize:{minRows:5}}},{name:"reason",type:"text",interface:"input",uiSchema:{type:"string","x-component":"Input",title:'{{t("Failed reason")}}'}},{name:"createdAt",type:"date",interface:"createdAt",field:"createdAt",uiSchema:{type:"datetime",title:'{{t("Created at")}}',"x-component":"DatePicker","x-component-props":{},"x-read-pretty":!0}},{name:"updatedAt",type:"date",interface:"updatedAt",field:"updatedAt",uiSchema:{type:"datetime",title:'{{t("Last updated at")}}',"x-component":"DatePicker","x-component-props":{},"x-read-pretty":!0}}]}}}]);
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is part of the NocoBase (R) project.
|
|
3
|
-
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
-
* Authors: NocoBase Team.
|
|
5
|
-
*
|
|
6
|
-
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
-
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
"use strict";(self.webpackChunk_nocobase_plugin_notification_manager=self.webpackChunk_nocobase_plugin_notification_manager||[]).push([["843"],{709:function(e,t,n){n.r(t),n.d(t,{ChannelManager:function(){return S}});var o=n(482),r=n(772),i=n(721),c=n(156),a=n.n(c),p=n(712),l=n(807),s=n(551),u=n(765),m=n(655),d=n(875),y=n(296);function f(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},o=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(o=o.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),o.forEach(function(t){var o;o=n[t],t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o})}return e}function x(e,t){return t=null!=t?t:{},Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):(function(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n.push.apply(n,o)}return n})(Object(t)).forEach(function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}),e}var b={type:"object",properties:{drawer:{type:"void","x-component":"Action.Drawer","x-decorator":"FormV2","x-use-decorator-props":"useCreateFormProps",title:'{{t("Add new")}}',properties:x(f({},{name:{"x-component":"CollectionField","x-decorator":"FormItem"},title:{"x-component":"CollectionField","x-decorator":"FormItem"},description:{"x-component":"CollectionField","x-decorator":"FormItem"},options:{"x-component":"CollectionField"}}),{footer:{type:"void","x-component":"Action.Drawer.Footer",properties:{cancel:{title:'{{t("Cancel")}}',"x-component":"Action","x-use-component-props":"useCloseActionProps"},submit:{title:'{{t("Submit")}}',"x-component":"Action","x-use-component-props":"useCreateActionProps"}}}})}}},h={type:"void",name:(0,d.uid)(),"x-decorator":"TableBlockProvider","x-decorator-props":{collection:y.O.channels,action:"list",dragSort:!1,params:{sort:["createdAt"],pageSize:20}},properties:{actions:{type:"void","x-component":"ActionBar","x-component-props":{style:{marginBottom:16}},properties:{refresh:{title:"{{t('Refresh')}}","x-action":"refresh","x-component":"Action","x-use-component-props":"useRefreshActionProps","x-component-props":{icon:"ReloadOutlined"}},create:{type:"void",title:'{{t("Add new")}}',"x-component":"AddNew","x-component-props":{type:"primary"}},filter:{"x-action":"filter",type:"object","x-component":"Filter.Action",title:"{{t('Filter')}}","x-use-component-props":"useFilterActionProps","x-component-props":{icon:"FilterOutlined"},"x-align":"left"}}},table:{type:"array","x-component":"TableV2","x-use-component-props":"useTableBlockProps","x-component-props":{rowKey:"name"},properties:{title:{type:"void","x-component":"TableV2.Column",title:'{{t("Channel display name")}}',"x-component-props":{width:100},properties:{title:{type:"string","x-component":"CollectionField","x-read-pretty":!0,"x-component-props":{ellipsis:!0}}}},name:{type:"void","x-component":"TableV2.Column",title:'{{t("Channel name")}}',"x-component-props":{width:100},properties:{name:{type:"string","x-component":"CollectionField","x-read-pretty":!0,"x-component-props":{ellipsis:!0}}}},description:{type:"void","x-component":"TableV2.Column",title:'{{t("Description")}}',"x-component-props":{width:200},properties:{description:{type:"boolean","x-component":"CollectionField","x-read-pretty":!0,"x-component-props":{ellipsis:!0}}}},notificationType:{title:'{{t("Notification type")}}',type:"void","x-component":"TableV2.Column","x-component-props":{width:200},properties:{notificationType:{type:"string","x-component":"CollectionField","x-read-pretty":!0}}},actions:{type:"void",title:'{{t("Actions")}}',"x-component":"TableV2.Column",properties:{edit:{type:"void",title:'{{t("Edit")}}',"x-component":"Action.Link","x-component-props":{openMode:"drawer"},"x-use-component-props":"useRecordEditActionProps","x-decorator":"Space",properties:{drawer:{type:"void",title:'{{t("Edit")}}',"x-component":"Action.Drawer","x-decorator":"FormV2","x-use-decorator-props":"useEditFormProps",properties:x(f({},{name:{"x-component":"CollectionField","x-decorator":"FormItem","x-disabled":!0},title:{"x-component":"CollectionField","x-decorator":"FormItem"},description:{"x-component":"CollectionField","x-decorator":"FormItem"},options:{"x-component":"CollectionField"}}),{footer:{type:"void","x-component":"Action.Drawer.Footer",properties:{cancel:{title:'{{t("Cancel")}}',"x-component":"Action","x-use-component-props":"useCloseActionProps"},submit:{title:"Submit","x-component":"Action","x-use-component-props":"useEditActionProps"}}}})}}},delete:{type:"void",title:'{{t("Delete")}}',"x-decorator":"Space","x-component":"Action.Link","x-use-component-props":"useRecordDeleteActionProps","x-component-props":{confirm:{title:"{{t('Delete record')}}",content:"{{t('Are you sure you want to delete it?')}}"}}}}}}}}},g=n(505),v=(0,g.observer)(function(){var e,t,n=(0,g.useForm)(),o=(0,r.useCollectionRecord)(),i=n.values.notificationType||(null==o||null==(e=o.data)?void 0:e.notificationType),p=(0,c.useContext)(u.wi).channelTypes.find(function(e){return e.type===i});return(null==(t=p.components)?void 0:t.ChannelConfigForm)?a().createElement(p.components.ChannelConfigForm,null):null},{displayName:"ConfigForm"});function C(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=Array(t);n<t;n++)o[n]=e[n];return o}function P(e,t,n,o,r,i,c){try{var a=e[i](c),p=a.value}catch(e){n(e);return}a.done?t(p):Promise.resolve(p).then(o,r)}var w=function(){var e=(0,r.useActionContext)().setVisible;return{run:function(){var t;return(t=function(){return function(e,t){var n,o,r,i,c={label:0,sent:function(){if(1&r[0])throw r[1];return r[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){var p=[i,a];if(n)throw TypeError("Generator is already executing.");for(;c;)try{if(n=1,o&&(r=2&p[0]?o.return:p[0]?o.throw||((r=o.return)&&r.call(o),0):o.next)&&!(r=r.call(o,p[1])).done)return r;switch(o=0,r&&(p=[2&p[0],r.value]),p[0]){case 0:case 1:r=p;break;case 4:return c.label++,{value:p[1],done:!1};case 5:c.label++,o=p[1],p=[0];continue;case 7:p=c.ops.pop(),c.trys.pop();continue;default:if(!(r=(r=c.trys).length>0&&r[r.length-1])&&(6===p[0]||2===p[0])){c=0;continue}if(3===p[0]&&(!r||p[1]>r[0]&&p[1]<r[3])){c.label=p[1];break}if(6===p[0]&&c.label<r[1]){c.label=r[1],r=p;break}if(r&&c.label<r[2]){c.label=r[2],c.ops.push(p);break}r[2]&&c.ops.pop(),c.trys.pop();continue}p=t.call(e,c)}catch(e){p=[6,e],o=0}finally{n=r=0}if(5&p[0])throw p[1];return{value:p[0]?p[1]:void 0,done:!0}}}}(this,function(t){return e(!1),[2]})},function(){var e=this,n=arguments;return new Promise(function(o,r){var i=t.apply(e,n);function c(e){P(i,o,r,c,a,"next",e)}function a(e){P(i,o,r,c,a,"throw",e)}c(void 0)})})()}}},A=function(){var e,t=(0,s.oG)().t,n=(e=(0,c.useState)(!1),function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n,o,r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var i=[],c=!0,a=!1;try{for(r=r.call(e);!(c=(n=r.next()).done)&&(i.push(n.value),i.length!==t);c=!0);}catch(e){a=!0,o=e}finally{try{c||null==r.return||r.return()}finally{if(a)throw o}}return i}}(e,2)||function(e,t){if(e){if("string"==typeof e)return C(e,2);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return C(e,t)}}(e,2)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),p=n[0],l=n[1],d=(0,u.tZ)(),y=d.NotificationTypeNameProvider,f=(d.name,d.setName),x=(0,r.useAPIClient)(),h=(0,u.CZ)().filter(function(e){var t;return(null==(t=e.meta)?void 0:t.creatable)!==!1}),g=0===h.length?[{key:"__empty__",label:a().createElement(i.Empty,{image:i.Empty.PRESENTED_IMAGE_SIMPLE,description:a().createElement(a().Fragment,null,t("No channel enabled yet"),a().createElement("br",null)," ",a().createElement("a",{target:"_blank",href:"zh-CN"===x.auth.locale?"https://docs-cn.nocobase.com/handbook/notification-manager":"https://docs.nocobase.com/handbook/notification-manager",rel:"noreferrer"},t("View documentation")))})}]:h.map(function(e){return{key:e.type,label:e.title,onClick:function(){l(!0),f(e.type)}}});return a().createElement(r.ActionContextProvider,{value:{visible:p,setVisible:l}},a().createElement(y,null,a().createElement(i.Dropdown,{menu:{items:g}},a().createElement(i.Button,{icon:a().createElement(o.PlusOutlined,null),type:"primary"},t("Add new")," ",a().createElement(o.DownOutlined,null))),a().createElement(r.SchemaComponent,{scope:{useCloseAction:w,useCreateActionProps:m.cD,useEditActionProps:m.G8,useCloseActionProps:m.Uy,useEditFormProps:m.fC,useCreateFormProps:m.Uc},schema:b})))},O=function(){return(0,r.useAsyncData)().data,!1},S=function(){var e=(0,s.oG)().t,t=(0,m.aT)(),n=(0,r.useSchemaComponentContext)(),o=(0,c.useMemo)(function(){var e,t;return e=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},o=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(o=o.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),o.forEach(function(t){var o;o=n[t],t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o})}return e}({},n),t=t={designable:!1},Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):(function(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n.push.apply(n,o)}return n})(Object(t)).forEach(function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}),e},[n]);return a().createElement(r.ExtendCollectionsProvider,{collections:[p.Z,l.Z]},a().createElement(r.SchemaComponentContext.Provider,{value:o},a().createElement(u.wi.Provider,{value:{channelTypes:t}},a().createElement(i.Card,{bordered:!1},a().createElement(r.SchemaComponent,{schema:h,components:{AddNew:A,ConfigForm:v},scope:{useCanNotDelete:O,t:e,notificationTypeOptions:t,useCreateActionProps:m.cD,useEditActionProps:m.G8,useCloseActionProps:m.Uy,useEditFormProps:m.fC,useCreateFormProps:m.Uc,useRecordDeleteActionProps:m.$l,useRecordEditActionProps:m.Bj}})))))};S.displayName="ChannelManager"},712:function(e,t,n){t.Z={name:n(296).O.channels,migrationRules:["overwrite","schema-only"],filterTargetKey:"name",autoGenId:!1,createdAt:!0,createdBy:!0,updatedAt:!0,updatedBy:!0,fields:[{name:"name",type:"uid",prefix:"s_",primaryKey:!0,interface:"input",uiSchema:{type:"string",title:'{{t("Channel name")}}',"x-component":"Input",required:!0,description:"{{t('Randomly generated and can not be modified. Support letters, numbers and underscores, must start with an letter.')}}"}},{name:"title",type:"string",interface:"input",uiSchema:{type:"string","x-component":"Input",title:'{{t("Channel display name")}}',required:!0}},{name:"options",type:"json",interface:"json",uiSchema:{type:"object","x-component":"ConfigForm"}},{name:"meta",type:"json",interface:"json"},{interface:"input",type:"string",name:"notificationType",uiSchema:{type:"string",title:'{{t("Notification type")}}',"x-component":"Select",enum:"{{notificationTypeOptions}}",required:!0}},{name:"description",type:"text",interface:"textarea",uiSchema:{type:"string","x-component":"Input.TextArea",title:'{{t("Description")}}'}}]}},807:function(e,t,n){t.Z={name:n(296).O.logs,migrationRules:["schema-only"],title:"MessageLogs",fields:[{name:"id",type:"uuid",primaryKey:!0,allowNull:!1,interface:"uuid",uiSchema:{type:"string",title:'{{t("ID")}}',"x-component":"Input","x-read-pretty":!0}},{name:"channelName",type:"string",interface:"input",uiSchema:{type:"string",title:'{{t("Channel name")}}',"x-component":"Input"}},{name:"channelTitle",type:"string",interface:"input",uiSchema:{type:"string","x-component":"Input",title:'{{t("Channel display name")}}'}},{name:"triggerFrom",type:"string",interface:"input",uiSchema:{type:"string","x-component":"Input",title:'{{t("Trigger from")}}'}},{name:"notificationType",type:"string",interface:"input",uiSchema:{type:"string",title:'{{t("Notification type")}}',"x-component":"Select",enum:"{{notificationTypeOptions}}",required:!0}},{name:"status",type:"string",interface:"select",uiSchema:{type:"string","x-component":"Select",enum:[{label:'{{t("Success")}}',value:"success",color:"green"},{label:'{{t("Failure")}}',value:"failure",color:"red"}],title:'{{t("Status")}}'}},{name:"message",type:"json",interface:"json",uiSchema:{"x-component":"Input.JSON",title:'{{t("Message")}}',"x-component-props":{autoSize:{minRows:5}},autoSize:{minRows:5}}},{name:"reason",type:"text",interface:"input",uiSchema:{type:"string","x-component":"Input",title:'{{t("Failed reason")}}'}},{name:"createdAt",type:"date",interface:"createdAt",field:"createdAt",uiSchema:{type:"datetime",title:'{{t("Created at")}}',"x-component":"DatePicker","x-component-props":{},"x-read-pretty":!0}},{name:"updatedAt",type:"date",interface:"updatedAt",field:"updatedAt",uiSchema:{type:"datetime",title:'{{t("Last updated at")}}',"x-component":"DatePicker","x-component-props":{},"x-read-pretty":!0}}]}}}]);
|